xref: /openbsd-src/gnu/usr.bin/binutils-2.17/bfd/sunos.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* BFD backend for SunOS binaries.
2*3d8817e4Smiod    Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3*3d8817e4Smiod    2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4*3d8817e4Smiod    Written by Cygnus Support.
5*3d8817e4Smiod 
6*3d8817e4Smiod    This file is part of BFD, the Binary File Descriptor library.
7*3d8817e4Smiod 
8*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
9*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
11*3d8817e4Smiod    (at your option) any later version.
12*3d8817e4Smiod 
13*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
14*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*3d8817e4Smiod    GNU General Public License for more details.
17*3d8817e4Smiod 
18*3d8817e4Smiod    You should have received a copy of the GNU General Public License
19*3d8817e4Smiod    along with this program; if not, write to the Free Software
20*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21*3d8817e4Smiod 
22*3d8817e4Smiod #define TARGETNAME "a.out-sunos-big"
23*3d8817e4Smiod 
24*3d8817e4Smiod /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
25*3d8817e4Smiod    remove whitespace added here, and thus will fail to concatenate
26*3d8817e4Smiod    the tokens.  */
27*3d8817e4Smiod #define MY(OP) CONCAT2 (sunos_big_,OP)
28*3d8817e4Smiod 
29*3d8817e4Smiod #include "bfd.h"
30*3d8817e4Smiod #include "bfdlink.h"
31*3d8817e4Smiod #include "libaout.h"
32*3d8817e4Smiod 
33*3d8817e4Smiod /* ??? Where should this go?  */
34*3d8817e4Smiod #define MACHTYPE_OK(mtype) \
35*3d8817e4Smiod   (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
36*3d8817e4Smiod    || ((mtype) == M_SPARCLET \
37*3d8817e4Smiod        && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
38*3d8817e4Smiod    || ((mtype) == M_SPARCLITE_LE \
39*3d8817e4Smiod        && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
40*3d8817e4Smiod    || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
41*3d8817e4Smiod        && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
42*3d8817e4Smiod 
43*3d8817e4Smiod #define MY_get_dynamic_symtab_upper_bound  sunos_get_dynamic_symtab_upper_bound
44*3d8817e4Smiod #define MY_canonicalize_dynamic_symtab     sunos_canonicalize_dynamic_symtab
45*3d8817e4Smiod #define MY_get_synthetic_symtab            _bfd_nodynamic_get_synthetic_symtab
46*3d8817e4Smiod #define MY_get_dynamic_reloc_upper_bound   sunos_get_dynamic_reloc_upper_bound
47*3d8817e4Smiod #define MY_canonicalize_dynamic_reloc      sunos_canonicalize_dynamic_reloc
48*3d8817e4Smiod #define MY_bfd_link_hash_table_create      sunos_link_hash_table_create
49*3d8817e4Smiod #define MY_add_dynamic_symbols             sunos_add_dynamic_symbols
50*3d8817e4Smiod #define MY_add_one_symbol                  sunos_add_one_symbol
51*3d8817e4Smiod #define MY_link_dynamic_object             sunos_link_dynamic_object
52*3d8817e4Smiod #define MY_write_dynamic_symbol            sunos_write_dynamic_symbol
53*3d8817e4Smiod #define MY_check_dynamic_reloc             sunos_check_dynamic_reloc
54*3d8817e4Smiod #define MY_finish_dynamic_link             sunos_finish_dynamic_link
55*3d8817e4Smiod 
56*3d8817e4Smiod static bfd_boolean sunos_add_dynamic_symbols            (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **);
57*3d8817e4Smiod 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 **);
58*3d8817e4Smiod static bfd_boolean sunos_link_dynamic_object            (struct bfd_link_info *, bfd *);
59*3d8817e4Smiod static bfd_boolean sunos_write_dynamic_symbol           (bfd *, struct bfd_link_info *, struct aout_link_hash_entry *);
60*3d8817e4Smiod 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 *);
61*3d8817e4Smiod static bfd_boolean sunos_finish_dynamic_link            (bfd *, struct bfd_link_info *);
62*3d8817e4Smiod static struct bfd_link_hash_table *sunos_link_hash_table_create  (bfd *);
63*3d8817e4Smiod static long        sunos_get_dynamic_symtab_upper_bound (bfd *);
64*3d8817e4Smiod static long        sunos_canonicalize_dynamic_symtab    (bfd *, asymbol **);
65*3d8817e4Smiod static long        sunos_get_dynamic_reloc_upper_bound  (bfd *);
66*3d8817e4Smiod static long        sunos_canonicalize_dynamic_reloc     (bfd *, arelent **, asymbol **);
67*3d8817e4Smiod 
68*3d8817e4Smiod /* Include the usual a.out support.  */
69*3d8817e4Smiod #include "aoutf1.h"
70*3d8817e4Smiod 
71*3d8817e4Smiod /* The SunOS 4.1.4 /usr/include/locale.h defines valid as a macro.  */
72*3d8817e4Smiod #undef valid
73*3d8817e4Smiod 
74*3d8817e4Smiod /* SunOS shared library support.  We store a pointer to this structure
75*3d8817e4Smiod    in obj_aout_dynamic_info (abfd).  */
76*3d8817e4Smiod 
77*3d8817e4Smiod struct sunos_dynamic_info
78*3d8817e4Smiod {
79*3d8817e4Smiod   /* Whether we found any dynamic information.  */
80*3d8817e4Smiod   bfd_boolean valid;
81*3d8817e4Smiod   /* Dynamic information.  */
82*3d8817e4Smiod   struct internal_sun4_dynamic_link dyninfo;
83*3d8817e4Smiod   /* Number of dynamic symbols.  */
84*3d8817e4Smiod   unsigned long dynsym_count;
85*3d8817e4Smiod   /* Read in nlists for dynamic symbols.  */
86*3d8817e4Smiod   struct external_nlist *dynsym;
87*3d8817e4Smiod   /* asymbol structures for dynamic symbols.  */
88*3d8817e4Smiod   aout_symbol_type *canonical_dynsym;
89*3d8817e4Smiod   /* Read in dynamic string table.  */
90*3d8817e4Smiod   char *dynstr;
91*3d8817e4Smiod   /* Number of dynamic relocs.  */
92*3d8817e4Smiod   unsigned long dynrel_count;
93*3d8817e4Smiod   /* Read in dynamic relocs.  This may be reloc_std_external or
94*3d8817e4Smiod      reloc_ext_external.  */
95*3d8817e4Smiod   void * dynrel;
96*3d8817e4Smiod   /* arelent structures for dynamic relocs.  */
97*3d8817e4Smiod   arelent *canonical_dynrel;
98*3d8817e4Smiod };
99*3d8817e4Smiod 
100*3d8817e4Smiod /* The hash table of dynamic symbols is composed of two word entries.
101*3d8817e4Smiod    See include/aout/sun4.h for details.  */
102*3d8817e4Smiod 
103*3d8817e4Smiod #define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD)
104*3d8817e4Smiod 
105*3d8817e4Smiod /* Read in the basic dynamic information.  This locates the __DYNAMIC
106*3d8817e4Smiod    structure and uses it to find the dynamic_link structure.  It
107*3d8817e4Smiod    creates and saves a sunos_dynamic_info structure.  If it can't find
108*3d8817e4Smiod    __DYNAMIC, it sets the valid field of the sunos_dynamic_info
109*3d8817e4Smiod    structure to FALSE to avoid doing this work again.  */
110*3d8817e4Smiod 
111*3d8817e4Smiod static bfd_boolean
sunos_read_dynamic_info(bfd * abfd)112*3d8817e4Smiod sunos_read_dynamic_info (bfd *abfd)
113*3d8817e4Smiod {
114*3d8817e4Smiod   struct sunos_dynamic_info *info;
115*3d8817e4Smiod   asection *dynsec;
116*3d8817e4Smiod   bfd_vma dynoff;
117*3d8817e4Smiod   struct external_sun4_dynamic dyninfo;
118*3d8817e4Smiod   unsigned long dynver;
119*3d8817e4Smiod   struct external_sun4_dynamic_link linkinfo;
120*3d8817e4Smiod   bfd_size_type amt;
121*3d8817e4Smiod 
122*3d8817e4Smiod   if (obj_aout_dynamic_info (abfd) != NULL)
123*3d8817e4Smiod     return TRUE;
124*3d8817e4Smiod 
125*3d8817e4Smiod   if ((abfd->flags & DYNAMIC) == 0)
126*3d8817e4Smiod     {
127*3d8817e4Smiod       bfd_set_error (bfd_error_invalid_operation);
128*3d8817e4Smiod       return FALSE;
129*3d8817e4Smiod     }
130*3d8817e4Smiod 
131*3d8817e4Smiod   amt = sizeof (struct sunos_dynamic_info);
132*3d8817e4Smiod   info = bfd_zalloc (abfd, amt);
133*3d8817e4Smiod   if (!info)
134*3d8817e4Smiod     return FALSE;
135*3d8817e4Smiod   info->valid = FALSE;
136*3d8817e4Smiod   info->dynsym = NULL;
137*3d8817e4Smiod   info->dynstr = NULL;
138*3d8817e4Smiod   info->canonical_dynsym = NULL;
139*3d8817e4Smiod   info->dynrel = NULL;
140*3d8817e4Smiod   info->canonical_dynrel = NULL;
141*3d8817e4Smiod   obj_aout_dynamic_info (abfd) = (void *) info;
142*3d8817e4Smiod 
143*3d8817e4Smiod   /* This code used to look for the __DYNAMIC symbol to locate the dynamic
144*3d8817e4Smiod      linking information.
145*3d8817e4Smiod      However this inhibits recovering the dynamic symbols from a
146*3d8817e4Smiod      stripped object file, so blindly assume that the dynamic linking
147*3d8817e4Smiod      information is located at the start of the data section.
148*3d8817e4Smiod      We could verify this assumption later by looking through the dynamic
149*3d8817e4Smiod      symbols for the __DYNAMIC symbol.  */
150*3d8817e4Smiod   if ((abfd->flags & DYNAMIC) == 0)
151*3d8817e4Smiod     return TRUE;
152*3d8817e4Smiod   if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (void *) &dyninfo,
153*3d8817e4Smiod 				  (file_ptr) 0,
154*3d8817e4Smiod 				  (bfd_size_type) sizeof dyninfo))
155*3d8817e4Smiod     return TRUE;
156*3d8817e4Smiod 
157*3d8817e4Smiod   dynver = GET_WORD (abfd, dyninfo.ld_version);
158*3d8817e4Smiod   if (dynver != 2 && dynver != 3)
159*3d8817e4Smiod     return TRUE;
160*3d8817e4Smiod 
161*3d8817e4Smiod   dynoff = GET_WORD (abfd, dyninfo.ld);
162*3d8817e4Smiod 
163*3d8817e4Smiod   /* dynoff is a virtual address.  It is probably always in the .data
164*3d8817e4Smiod      section, but this code should work even if it moves.  */
165*3d8817e4Smiod   if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd)))
166*3d8817e4Smiod     dynsec = obj_textsec (abfd);
167*3d8817e4Smiod   else
168*3d8817e4Smiod     dynsec = obj_datasec (abfd);
169*3d8817e4Smiod   dynoff -= bfd_get_section_vma (abfd, dynsec);
170*3d8817e4Smiod   if (dynoff > dynsec->size)
171*3d8817e4Smiod     return TRUE;
172*3d8817e4Smiod 
173*3d8817e4Smiod   /* This executable appears to be dynamically linked in a way that we
174*3d8817e4Smiod      can understand.  */
175*3d8817e4Smiod   if (! bfd_get_section_contents (abfd, dynsec, (void *) &linkinfo,
176*3d8817e4Smiod 				  (file_ptr) dynoff,
177*3d8817e4Smiod 				  (bfd_size_type) sizeof linkinfo))
178*3d8817e4Smiod     return TRUE;
179*3d8817e4Smiod 
180*3d8817e4Smiod   /* Swap in the dynamic link information.  */
181*3d8817e4Smiod   info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded);
182*3d8817e4Smiod   info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need);
183*3d8817e4Smiod   info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules);
184*3d8817e4Smiod   info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got);
185*3d8817e4Smiod   info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt);
186*3d8817e4Smiod   info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel);
187*3d8817e4Smiod   info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash);
188*3d8817e4Smiod   info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab);
189*3d8817e4Smiod   info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash);
190*3d8817e4Smiod   info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets);
191*3d8817e4Smiod   info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols);
192*3d8817e4Smiod   info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size);
193*3d8817e4Smiod   info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text);
194*3d8817e4Smiod   info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz);
195*3d8817e4Smiod 
196*3d8817e4Smiod   /* Reportedly the addresses need to be offset by the size of the
197*3d8817e4Smiod      exec header in an NMAGIC file.  */
198*3d8817e4Smiod   if (adata (abfd).magic == n_magic)
199*3d8817e4Smiod     {
200*3d8817e4Smiod       unsigned long exec_bytes_size = adata (abfd).exec_bytes_size;
201*3d8817e4Smiod 
202*3d8817e4Smiod       info->dyninfo.ld_need += exec_bytes_size;
203*3d8817e4Smiod       info->dyninfo.ld_rules += exec_bytes_size;
204*3d8817e4Smiod       info->dyninfo.ld_rel += exec_bytes_size;
205*3d8817e4Smiod       info->dyninfo.ld_hash += exec_bytes_size;
206*3d8817e4Smiod       info->dyninfo.ld_stab += exec_bytes_size;
207*3d8817e4Smiod       info->dyninfo.ld_symbols += exec_bytes_size;
208*3d8817e4Smiod     }
209*3d8817e4Smiod 
210*3d8817e4Smiod   /* The only way to get the size of the symbol information appears to
211*3d8817e4Smiod      be to determine the distance between it and the string table.  */
212*3d8817e4Smiod   info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab)
213*3d8817e4Smiod 			/ EXTERNAL_NLIST_SIZE);
214*3d8817e4Smiod   BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE
215*3d8817e4Smiod 	      == (unsigned long) (info->dyninfo.ld_symbols
216*3d8817e4Smiod 				  - info->dyninfo.ld_stab));
217*3d8817e4Smiod 
218*3d8817e4Smiod   /* Similarly, the relocs end at the hash table.  */
219*3d8817e4Smiod   info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel)
220*3d8817e4Smiod 			/ obj_reloc_entry_size (abfd));
221*3d8817e4Smiod   BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd)
222*3d8817e4Smiod 	      == (unsigned long) (info->dyninfo.ld_hash
223*3d8817e4Smiod 				  - info->dyninfo.ld_rel));
224*3d8817e4Smiod 
225*3d8817e4Smiod   info->valid = TRUE;
226*3d8817e4Smiod 
227*3d8817e4Smiod   return TRUE;
228*3d8817e4Smiod }
229*3d8817e4Smiod 
230*3d8817e4Smiod /* Return the amount of memory required for the dynamic symbols.  */
231*3d8817e4Smiod 
232*3d8817e4Smiod static long
sunos_get_dynamic_symtab_upper_bound(bfd * abfd)233*3d8817e4Smiod sunos_get_dynamic_symtab_upper_bound (bfd *abfd)
234*3d8817e4Smiod {
235*3d8817e4Smiod   struct sunos_dynamic_info *info;
236*3d8817e4Smiod 
237*3d8817e4Smiod   if (! sunos_read_dynamic_info (abfd))
238*3d8817e4Smiod     return -1;
239*3d8817e4Smiod 
240*3d8817e4Smiod   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
241*3d8817e4Smiod   if (! info->valid)
242*3d8817e4Smiod     {
243*3d8817e4Smiod       bfd_set_error (bfd_error_no_symbols);
244*3d8817e4Smiod       return -1;
245*3d8817e4Smiod     }
246*3d8817e4Smiod 
247*3d8817e4Smiod   return (info->dynsym_count + 1) * sizeof (asymbol *);
248*3d8817e4Smiod }
249*3d8817e4Smiod 
250*3d8817e4Smiod /* Read the external dynamic symbols.  */
251*3d8817e4Smiod 
252*3d8817e4Smiod static bfd_boolean
sunos_slurp_dynamic_symtab(bfd * abfd)253*3d8817e4Smiod sunos_slurp_dynamic_symtab (bfd *abfd)
254*3d8817e4Smiod {
255*3d8817e4Smiod   struct sunos_dynamic_info *info;
256*3d8817e4Smiod   bfd_size_type amt;
257*3d8817e4Smiod 
258*3d8817e4Smiod   /* Get the general dynamic information.  */
259*3d8817e4Smiod   if (obj_aout_dynamic_info (abfd) == NULL)
260*3d8817e4Smiod     {
261*3d8817e4Smiod       if (! sunos_read_dynamic_info (abfd))
262*3d8817e4Smiod 	  return FALSE;
263*3d8817e4Smiod     }
264*3d8817e4Smiod 
265*3d8817e4Smiod   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
266*3d8817e4Smiod   if (! info->valid)
267*3d8817e4Smiod     {
268*3d8817e4Smiod       bfd_set_error (bfd_error_no_symbols);
269*3d8817e4Smiod       return FALSE;
270*3d8817e4Smiod     }
271*3d8817e4Smiod 
272*3d8817e4Smiod   /* Get the dynamic nlist structures.  */
273*3d8817e4Smiod   if (info->dynsym == NULL)
274*3d8817e4Smiod     {
275*3d8817e4Smiod       amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE;
276*3d8817e4Smiod       info->dynsym = bfd_alloc (abfd, amt);
277*3d8817e4Smiod       if (info->dynsym == NULL && info->dynsym_count != 0)
278*3d8817e4Smiod 	return FALSE;
279*3d8817e4Smiod       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0
280*3d8817e4Smiod 	  || bfd_bread ((void *) info->dynsym, amt, abfd) != amt)
281*3d8817e4Smiod 	{
282*3d8817e4Smiod 	  if (info->dynsym != NULL)
283*3d8817e4Smiod 	    {
284*3d8817e4Smiod 	      bfd_release (abfd, info->dynsym);
285*3d8817e4Smiod 	      info->dynsym = NULL;
286*3d8817e4Smiod 	    }
287*3d8817e4Smiod 	  return FALSE;
288*3d8817e4Smiod 	}
289*3d8817e4Smiod     }
290*3d8817e4Smiod 
291*3d8817e4Smiod   /* Get the dynamic strings.  */
292*3d8817e4Smiod   if (info->dynstr == NULL)
293*3d8817e4Smiod     {
294*3d8817e4Smiod       amt = info->dyninfo.ld_symb_size;
295*3d8817e4Smiod       info->dynstr = bfd_alloc (abfd, amt);
296*3d8817e4Smiod       if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0)
297*3d8817e4Smiod 	return FALSE;
298*3d8817e4Smiod       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0
299*3d8817e4Smiod 	  || bfd_bread ((void *) info->dynstr, amt, abfd) != amt)
300*3d8817e4Smiod 	{
301*3d8817e4Smiod 	  if (info->dynstr != NULL)
302*3d8817e4Smiod 	    {
303*3d8817e4Smiod 	      bfd_release (abfd, info->dynstr);
304*3d8817e4Smiod 	      info->dynstr = NULL;
305*3d8817e4Smiod 	    }
306*3d8817e4Smiod 	  return FALSE;
307*3d8817e4Smiod 	}
308*3d8817e4Smiod     }
309*3d8817e4Smiod 
310*3d8817e4Smiod   return TRUE;
311*3d8817e4Smiod }
312*3d8817e4Smiod 
313*3d8817e4Smiod /* Read in the dynamic symbols.  */
314*3d8817e4Smiod 
315*3d8817e4Smiod static long
sunos_canonicalize_dynamic_symtab(bfd * abfd,asymbol ** storage)316*3d8817e4Smiod sunos_canonicalize_dynamic_symtab (bfd *abfd, asymbol **storage)
317*3d8817e4Smiod {
318*3d8817e4Smiod   struct sunos_dynamic_info *info;
319*3d8817e4Smiod   unsigned long i;
320*3d8817e4Smiod 
321*3d8817e4Smiod   if (! sunos_slurp_dynamic_symtab (abfd))
322*3d8817e4Smiod     return -1;
323*3d8817e4Smiod 
324*3d8817e4Smiod   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
325*3d8817e4Smiod 
326*3d8817e4Smiod #ifdef CHECK_DYNAMIC_HASH
327*3d8817e4Smiod   /* Check my understanding of the dynamic hash table by making sure
328*3d8817e4Smiod      that each symbol can be located in the hash table.  */
329*3d8817e4Smiod   {
330*3d8817e4Smiod     bfd_size_type table_size;
331*3d8817e4Smiod     bfd_byte *table;
332*3d8817e4Smiod     bfd_size_type i;
333*3d8817e4Smiod 
334*3d8817e4Smiod     if (info->dyninfo.ld_buckets > info->dynsym_count)
335*3d8817e4Smiod       abort ();
336*3d8817e4Smiod     table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash;
337*3d8817e4Smiod     table = bfd_malloc (table_size);
338*3d8817e4Smiod     if (table == NULL && table_size != 0)
339*3d8817e4Smiod       abort ();
340*3d8817e4Smiod     if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_hash, SEEK_SET) != 0
341*3d8817e4Smiod 	|| bfd_bread ((void *) table, table_size, abfd) != table_size)
342*3d8817e4Smiod       abort ();
343*3d8817e4Smiod     for (i = 0; i < info->dynsym_count; i++)
344*3d8817e4Smiod       {
345*3d8817e4Smiod 	unsigned char *name;
346*3d8817e4Smiod 	unsigned long hash;
347*3d8817e4Smiod 
348*3d8817e4Smiod 	name = ((unsigned char *) info->dynstr
349*3d8817e4Smiod 		+ GET_WORD (abfd, info->dynsym[i].e_strx));
350*3d8817e4Smiod 	hash = 0;
351*3d8817e4Smiod 	while (*name != '\0')
352*3d8817e4Smiod 	  hash = (hash << 1) + *name++;
353*3d8817e4Smiod 	hash &= 0x7fffffff;
354*3d8817e4Smiod 	hash %= info->dyninfo.ld_buckets;
355*3d8817e4Smiod 	while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i)
356*3d8817e4Smiod 	  {
357*3d8817e4Smiod 	    hash = GET_WORD (abfd,
358*3d8817e4Smiod 			     table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
359*3d8817e4Smiod 	    if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE)
360*3d8817e4Smiod 	      abort ();
361*3d8817e4Smiod 	  }
362*3d8817e4Smiod       }
363*3d8817e4Smiod     free (table);
364*3d8817e4Smiod   }
365*3d8817e4Smiod #endif /* CHECK_DYNAMIC_HASH */
366*3d8817e4Smiod 
367*3d8817e4Smiod   /* Get the asymbol structures corresponding to the dynamic nlist
368*3d8817e4Smiod      structures.  */
369*3d8817e4Smiod   if (info->canonical_dynsym == NULL)
370*3d8817e4Smiod     {
371*3d8817e4Smiod       bfd_size_type size;
372*3d8817e4Smiod       bfd_size_type strsize = info->dyninfo.ld_symb_size;
373*3d8817e4Smiod 
374*3d8817e4Smiod       size = (bfd_size_type) info->dynsym_count * sizeof (aout_symbol_type);
375*3d8817e4Smiod       info->canonical_dynsym = bfd_alloc (abfd, size);
376*3d8817e4Smiod       if (info->canonical_dynsym == NULL && info->dynsym_count != 0)
377*3d8817e4Smiod 	return -1;
378*3d8817e4Smiod 
379*3d8817e4Smiod       if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym,
380*3d8817e4Smiod 					    info->dynsym,
381*3d8817e4Smiod 					    (bfd_size_type) info->dynsym_count,
382*3d8817e4Smiod 					    info->dynstr, strsize, TRUE))
383*3d8817e4Smiod 	{
384*3d8817e4Smiod 	  if (info->canonical_dynsym != NULL)
385*3d8817e4Smiod 	    {
386*3d8817e4Smiod 	      bfd_release (abfd, info->canonical_dynsym);
387*3d8817e4Smiod 	      info->canonical_dynsym = NULL;
388*3d8817e4Smiod 	    }
389*3d8817e4Smiod 	  return -1;
390*3d8817e4Smiod 	}
391*3d8817e4Smiod     }
392*3d8817e4Smiod 
393*3d8817e4Smiod   /* Return pointers to the dynamic asymbol structures.  */
394*3d8817e4Smiod   for (i = 0; i < info->dynsym_count; i++)
395*3d8817e4Smiod     *storage++ = (asymbol *) (info->canonical_dynsym + i);
396*3d8817e4Smiod   *storage = NULL;
397*3d8817e4Smiod 
398*3d8817e4Smiod   return info->dynsym_count;
399*3d8817e4Smiod }
400*3d8817e4Smiod 
401*3d8817e4Smiod /* Return the amount of memory required for the dynamic relocs.  */
402*3d8817e4Smiod 
403*3d8817e4Smiod static long
sunos_get_dynamic_reloc_upper_bound(bfd * abfd)404*3d8817e4Smiod sunos_get_dynamic_reloc_upper_bound (bfd *abfd)
405*3d8817e4Smiod {
406*3d8817e4Smiod   struct sunos_dynamic_info *info;
407*3d8817e4Smiod 
408*3d8817e4Smiod   if (! sunos_read_dynamic_info (abfd))
409*3d8817e4Smiod     return -1;
410*3d8817e4Smiod 
411*3d8817e4Smiod   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
412*3d8817e4Smiod   if (! info->valid)
413*3d8817e4Smiod     {
414*3d8817e4Smiod       bfd_set_error (bfd_error_no_symbols);
415*3d8817e4Smiod       return -1;
416*3d8817e4Smiod     }
417*3d8817e4Smiod 
418*3d8817e4Smiod   return (info->dynrel_count + 1) * sizeof (arelent *);
419*3d8817e4Smiod }
420*3d8817e4Smiod 
421*3d8817e4Smiod /* Read in the dynamic relocs.  */
422*3d8817e4Smiod 
423*3d8817e4Smiod static long
sunos_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)424*3d8817e4Smiod sunos_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage, asymbol **syms)
425*3d8817e4Smiod {
426*3d8817e4Smiod   struct sunos_dynamic_info *info;
427*3d8817e4Smiod   unsigned long i;
428*3d8817e4Smiod   bfd_size_type size;
429*3d8817e4Smiod 
430*3d8817e4Smiod   /* Get the general dynamic information.  */
431*3d8817e4Smiod   if (obj_aout_dynamic_info (abfd) == NULL)
432*3d8817e4Smiod     {
433*3d8817e4Smiod       if (! sunos_read_dynamic_info (abfd))
434*3d8817e4Smiod 	return -1;
435*3d8817e4Smiod     }
436*3d8817e4Smiod 
437*3d8817e4Smiod   info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
438*3d8817e4Smiod   if (! info->valid)
439*3d8817e4Smiod     {
440*3d8817e4Smiod       bfd_set_error (bfd_error_no_symbols);
441*3d8817e4Smiod       return -1;
442*3d8817e4Smiod     }
443*3d8817e4Smiod 
444*3d8817e4Smiod   /* Get the dynamic reloc information.  */
445*3d8817e4Smiod   if (info->dynrel == NULL)
446*3d8817e4Smiod     {
447*3d8817e4Smiod       size = (bfd_size_type) info->dynrel_count * obj_reloc_entry_size (abfd);
448*3d8817e4Smiod       info->dynrel = bfd_alloc (abfd, size);
449*3d8817e4Smiod       if (info->dynrel == NULL && size != 0)
450*3d8817e4Smiod 	return -1;
451*3d8817e4Smiod       if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_rel, SEEK_SET) != 0
452*3d8817e4Smiod 	  || bfd_bread ((void *) info->dynrel, size, abfd) != size)
453*3d8817e4Smiod 	{
454*3d8817e4Smiod 	  if (info->dynrel != NULL)
455*3d8817e4Smiod 	    {
456*3d8817e4Smiod 	      bfd_release (abfd, info->dynrel);
457*3d8817e4Smiod 	      info->dynrel = NULL;
458*3d8817e4Smiod 	    }
459*3d8817e4Smiod 	  return -1;
460*3d8817e4Smiod 	}
461*3d8817e4Smiod     }
462*3d8817e4Smiod 
463*3d8817e4Smiod   /* Get the arelent structures corresponding to the dynamic reloc
464*3d8817e4Smiod      information.  */
465*3d8817e4Smiod   if (info->canonical_dynrel == NULL)
466*3d8817e4Smiod     {
467*3d8817e4Smiod       arelent *to;
468*3d8817e4Smiod 
469*3d8817e4Smiod       size = (bfd_size_type) info->dynrel_count * sizeof (arelent);
470*3d8817e4Smiod       info->canonical_dynrel = bfd_alloc (abfd, size);
471*3d8817e4Smiod       if (info->canonical_dynrel == NULL && info->dynrel_count != 0)
472*3d8817e4Smiod 	return -1;
473*3d8817e4Smiod 
474*3d8817e4Smiod       to = info->canonical_dynrel;
475*3d8817e4Smiod 
476*3d8817e4Smiod       if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
477*3d8817e4Smiod 	{
478*3d8817e4Smiod 	  struct reloc_ext_external *p;
479*3d8817e4Smiod 	  struct reloc_ext_external *pend;
480*3d8817e4Smiod 
481*3d8817e4Smiod 	  p = (struct reloc_ext_external *) info->dynrel;
482*3d8817e4Smiod 	  pend = p + info->dynrel_count;
483*3d8817e4Smiod 	  for (; p < pend; p++, to++)
484*3d8817e4Smiod 	    NAME (aout, swap_ext_reloc_in) (abfd, p, to, syms,
485*3d8817e4Smiod 					    (bfd_size_type) info->dynsym_count);
486*3d8817e4Smiod 	}
487*3d8817e4Smiod       else
488*3d8817e4Smiod 	{
489*3d8817e4Smiod 	  struct reloc_std_external *p;
490*3d8817e4Smiod 	  struct reloc_std_external *pend;
491*3d8817e4Smiod 
492*3d8817e4Smiod 	  p = (struct reloc_std_external *) info->dynrel;
493*3d8817e4Smiod 	  pend = p + info->dynrel_count;
494*3d8817e4Smiod 	  for (; p < pend; p++, to++)
495*3d8817e4Smiod 	    NAME (aout, swap_std_reloc_in) (abfd, p, to, syms,
496*3d8817e4Smiod 					    (bfd_size_type) info->dynsym_count);
497*3d8817e4Smiod 	}
498*3d8817e4Smiod     }
499*3d8817e4Smiod 
500*3d8817e4Smiod   /* Return pointers to the dynamic arelent structures.  */
501*3d8817e4Smiod   for (i = 0; i < info->dynrel_count; i++)
502*3d8817e4Smiod     *storage++ = info->canonical_dynrel + i;
503*3d8817e4Smiod   *storage = NULL;
504*3d8817e4Smiod 
505*3d8817e4Smiod   return info->dynrel_count;
506*3d8817e4Smiod }
507*3d8817e4Smiod 
508*3d8817e4Smiod /* Code to handle linking of SunOS shared libraries.  */
509*3d8817e4Smiod 
510*3d8817e4Smiod /* A SPARC procedure linkage table entry is 12 bytes.  The first entry
511*3d8817e4Smiod    in the table is a jump which is filled in by the runtime linker.
512*3d8817e4Smiod    The remaining entries are branches back to the first entry,
513*3d8817e4Smiod    followed by an index into the relocation table encoded to look like
514*3d8817e4Smiod    a sethi of %g0.  */
515*3d8817e4Smiod 
516*3d8817e4Smiod #define SPARC_PLT_ENTRY_SIZE (12)
517*3d8817e4Smiod 
518*3d8817e4Smiod static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] =
519*3d8817e4Smiod {
520*3d8817e4Smiod   /* sethi %hi(0),%g1; address filled in by runtime linker.  */
521*3d8817e4Smiod   0x3, 0, 0, 0,
522*3d8817e4Smiod   /* jmp %g1; offset filled in by runtime linker.  */
523*3d8817e4Smiod   0x81, 0xc0, 0x60, 0,
524*3d8817e4Smiod   /* nop */
525*3d8817e4Smiod   0x1, 0, 0, 0
526*3d8817e4Smiod };
527*3d8817e4Smiod 
528*3d8817e4Smiod /* save %sp, -96, %sp */
529*3d8817e4Smiod #define SPARC_PLT_ENTRY_WORD0 ((bfd_vma) 0x9de3bfa0)
530*3d8817e4Smiod /* call; address filled in later.  */
531*3d8817e4Smiod #define SPARC_PLT_ENTRY_WORD1 ((bfd_vma) 0x40000000)
532*3d8817e4Smiod /* sethi; reloc index filled in later.  */
533*3d8817e4Smiod #define SPARC_PLT_ENTRY_WORD2 ((bfd_vma) 0x01000000)
534*3d8817e4Smiod 
535*3d8817e4Smiod /* This sequence is used when for the jump table entry to a defined
536*3d8817e4Smiod    symbol in a complete executable.  It is used when linking PIC
537*3d8817e4Smiod    compiled code which is not being put into a shared library.  */
538*3d8817e4Smiod /* sethi <address to be filled in later>, %g1 */
539*3d8817e4Smiod #define SPARC_PLT_PIC_WORD0 ((bfd_vma) 0x03000000)
540*3d8817e4Smiod /* jmp %g1 + <address to be filled in later> */
541*3d8817e4Smiod #define SPARC_PLT_PIC_WORD1 ((bfd_vma) 0x81c06000)
542*3d8817e4Smiod /* nop */
543*3d8817e4Smiod #define SPARC_PLT_PIC_WORD2 ((bfd_vma) 0x01000000)
544*3d8817e4Smiod 
545*3d8817e4Smiod /* An m68k procedure linkage table entry is 8 bytes.  The first entry
546*3d8817e4Smiod    in the table is a jump which is filled in the by the runtime
547*3d8817e4Smiod    linker.  The remaining entries are branches back to the first
548*3d8817e4Smiod    entry, followed by a two byte index into the relocation table.  */
549*3d8817e4Smiod 
550*3d8817e4Smiod #define M68K_PLT_ENTRY_SIZE (8)
551*3d8817e4Smiod 
552*3d8817e4Smiod static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] =
553*3d8817e4Smiod {
554*3d8817e4Smiod   /* jmps @# */
555*3d8817e4Smiod   0x4e, 0xf9,
556*3d8817e4Smiod   /* Filled in by runtime linker with a magic address.  */
557*3d8817e4Smiod   0, 0, 0, 0,
558*3d8817e4Smiod   /* Not used?  */
559*3d8817e4Smiod   0, 0
560*3d8817e4Smiod };
561*3d8817e4Smiod 
562*3d8817e4Smiod /* bsrl */
563*3d8817e4Smiod #define M68K_PLT_ENTRY_WORD0 ((bfd_vma) 0x61ff)
564*3d8817e4Smiod /* Remaining words filled in later.  */
565*3d8817e4Smiod 
566*3d8817e4Smiod /* An entry in the SunOS linker hash table.  */
567*3d8817e4Smiod 
568*3d8817e4Smiod struct sunos_link_hash_entry
569*3d8817e4Smiod {
570*3d8817e4Smiod   struct aout_link_hash_entry root;
571*3d8817e4Smiod 
572*3d8817e4Smiod   /* If this is a dynamic symbol, this is its index into the dynamic
573*3d8817e4Smiod      symbol table.  This is initialized to -1.  As the linker looks at
574*3d8817e4Smiod      the input files, it changes this to -2 if it will be added to the
575*3d8817e4Smiod      dynamic symbol table.  After all the input files have been seen,
576*3d8817e4Smiod      the linker will know whether to build a dynamic symbol table; if
577*3d8817e4Smiod      it does build one, this becomes the index into the table.  */
578*3d8817e4Smiod   long dynindx;
579*3d8817e4Smiod 
580*3d8817e4Smiod   /* If this is a dynamic symbol, this is the index of the name in the
581*3d8817e4Smiod      dynamic symbol string table.  */
582*3d8817e4Smiod   long dynstr_index;
583*3d8817e4Smiod 
584*3d8817e4Smiod   /* The offset into the global offset table used for this symbol.  If
585*3d8817e4Smiod      the symbol does not require a GOT entry, this is 0.  */
586*3d8817e4Smiod   bfd_vma got_offset;
587*3d8817e4Smiod 
588*3d8817e4Smiod   /* The offset into the procedure linkage table used for this symbol.
589*3d8817e4Smiod      If the symbol does not require a PLT entry, this is 0.  */
590*3d8817e4Smiod   bfd_vma plt_offset;
591*3d8817e4Smiod 
592*3d8817e4Smiod   /* Some linker flags.  */
593*3d8817e4Smiod   unsigned char flags;
594*3d8817e4Smiod   /* Symbol is referenced by a regular object.  */
595*3d8817e4Smiod #define SUNOS_REF_REGULAR 01
596*3d8817e4Smiod   /* Symbol is defined by a regular object.  */
597*3d8817e4Smiod #define SUNOS_DEF_REGULAR 02
598*3d8817e4Smiod   /* Symbol is referenced by a dynamic object.  */
599*3d8817e4Smiod #define SUNOS_REF_DYNAMIC 04
600*3d8817e4Smiod   /* Symbol is defined by a dynamic object.  */
601*3d8817e4Smiod #define SUNOS_DEF_DYNAMIC 010
602*3d8817e4Smiod   /* Symbol is a constructor symbol in a regular object.  */
603*3d8817e4Smiod #define SUNOS_CONSTRUCTOR 020
604*3d8817e4Smiod };
605*3d8817e4Smiod 
606*3d8817e4Smiod /* The SunOS linker hash table.  */
607*3d8817e4Smiod 
608*3d8817e4Smiod struct sunos_link_hash_table
609*3d8817e4Smiod {
610*3d8817e4Smiod   struct aout_link_hash_table root;
611*3d8817e4Smiod 
612*3d8817e4Smiod   /* The object which holds the dynamic sections.  */
613*3d8817e4Smiod   bfd *dynobj;
614*3d8817e4Smiod 
615*3d8817e4Smiod   /* Whether we have created the dynamic sections.  */
616*3d8817e4Smiod   bfd_boolean dynamic_sections_created;
617*3d8817e4Smiod 
618*3d8817e4Smiod   /* Whether we need the dynamic sections.  */
619*3d8817e4Smiod   bfd_boolean dynamic_sections_needed;
620*3d8817e4Smiod 
621*3d8817e4Smiod   /* Whether we need the .got table.  */
622*3d8817e4Smiod   bfd_boolean got_needed;
623*3d8817e4Smiod 
624*3d8817e4Smiod   /* The number of dynamic symbols.  */
625*3d8817e4Smiod   size_t dynsymcount;
626*3d8817e4Smiod 
627*3d8817e4Smiod   /* The number of buckets in the hash table.  */
628*3d8817e4Smiod   size_t bucketcount;
629*3d8817e4Smiod 
630*3d8817e4Smiod   /* The list of dynamic objects needed by dynamic objects included in
631*3d8817e4Smiod      the link.  */
632*3d8817e4Smiod   struct bfd_link_needed_list *needed;
633*3d8817e4Smiod 
634*3d8817e4Smiod   /* The offset of __GLOBAL_OFFSET_TABLE_ into the .got section.  */
635*3d8817e4Smiod   bfd_vma got_base;
636*3d8817e4Smiod };
637*3d8817e4Smiod 
638*3d8817e4Smiod /* Routine to create an entry in an SunOS link hash table.  */
639*3d8817e4Smiod 
640*3d8817e4Smiod static struct bfd_hash_entry *
sunos_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)641*3d8817e4Smiod sunos_link_hash_newfunc (struct bfd_hash_entry *entry,
642*3d8817e4Smiod 			 struct bfd_hash_table *table,
643*3d8817e4Smiod 			 const char *string)
644*3d8817e4Smiod {
645*3d8817e4Smiod   struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry;
646*3d8817e4Smiod 
647*3d8817e4Smiod   /* Allocate the structure if it has not already been allocated by a
648*3d8817e4Smiod      subclass.  */
649*3d8817e4Smiod   if (ret ==  NULL)
650*3d8817e4Smiod     ret = bfd_hash_allocate (table, sizeof (* ret));
651*3d8817e4Smiod   if (ret == NULL)
652*3d8817e4Smiod     return NULL;
653*3d8817e4Smiod 
654*3d8817e4Smiod   /* Call the allocation method of the superclass.  */
655*3d8817e4Smiod   ret = ((struct sunos_link_hash_entry *)
656*3d8817e4Smiod 	 NAME (aout, link_hash_newfunc) ((struct bfd_hash_entry *) ret,
657*3d8817e4Smiod 					 table, string));
658*3d8817e4Smiod   if (ret != NULL)
659*3d8817e4Smiod     {
660*3d8817e4Smiod       /* Set local fields.  */
661*3d8817e4Smiod       ret->dynindx = -1;
662*3d8817e4Smiod       ret->dynstr_index = -1;
663*3d8817e4Smiod       ret->got_offset = 0;
664*3d8817e4Smiod       ret->plt_offset = 0;
665*3d8817e4Smiod       ret->flags = 0;
666*3d8817e4Smiod     }
667*3d8817e4Smiod 
668*3d8817e4Smiod   return (struct bfd_hash_entry *) ret;
669*3d8817e4Smiod }
670*3d8817e4Smiod 
671*3d8817e4Smiod /* Create a SunOS link hash table.  */
672*3d8817e4Smiod 
673*3d8817e4Smiod static struct bfd_link_hash_table *
sunos_link_hash_table_create(bfd * abfd)674*3d8817e4Smiod sunos_link_hash_table_create (bfd *abfd)
675*3d8817e4Smiod {
676*3d8817e4Smiod   struct sunos_link_hash_table *ret;
677*3d8817e4Smiod   bfd_size_type amt = sizeof (struct sunos_link_hash_table);
678*3d8817e4Smiod 
679*3d8817e4Smiod   ret = bfd_malloc (amt);
680*3d8817e4Smiod   if (ret ==  NULL)
681*3d8817e4Smiod     return NULL;
682*3d8817e4Smiod   if (!NAME (aout, link_hash_table_init) (&ret->root, abfd,
683*3d8817e4Smiod 					  sunos_link_hash_newfunc,
684*3d8817e4Smiod 					  sizeof (struct sunos_link_hash_entry)))
685*3d8817e4Smiod     {
686*3d8817e4Smiod       free (ret);
687*3d8817e4Smiod       return NULL;
688*3d8817e4Smiod     }
689*3d8817e4Smiod 
690*3d8817e4Smiod   ret->dynobj = NULL;
691*3d8817e4Smiod   ret->dynamic_sections_created = FALSE;
692*3d8817e4Smiod   ret->dynamic_sections_needed = FALSE;
693*3d8817e4Smiod   ret->got_needed = FALSE;
694*3d8817e4Smiod   ret->dynsymcount = 0;
695*3d8817e4Smiod   ret->bucketcount = 0;
696*3d8817e4Smiod   ret->needed = NULL;
697*3d8817e4Smiod   ret->got_base = 0;
698*3d8817e4Smiod 
699*3d8817e4Smiod   return &ret->root.root;
700*3d8817e4Smiod }
701*3d8817e4Smiod 
702*3d8817e4Smiod /* Look up an entry in an SunOS link hash table.  */
703*3d8817e4Smiod 
704*3d8817e4Smiod #define sunos_link_hash_lookup(table, string, create, copy, follow) \
705*3d8817e4Smiod   ((struct sunos_link_hash_entry *) \
706*3d8817e4Smiod    aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
707*3d8817e4Smiod 			  (follow)))
708*3d8817e4Smiod 
709*3d8817e4Smiod /* Traverse a SunOS link hash table.  */
710*3d8817e4Smiod 
711*3d8817e4Smiod #define sunos_link_hash_traverse(table, func, info)			\
712*3d8817e4Smiod   (aout_link_hash_traverse						\
713*3d8817e4Smiod    (&(table)->root,							\
714*3d8817e4Smiod     (bfd_boolean (*) (struct aout_link_hash_entry *, void *)) (func),	\
715*3d8817e4Smiod     (info)))
716*3d8817e4Smiod 
717*3d8817e4Smiod /* Get the SunOS link hash table from the info structure.  This is
718*3d8817e4Smiod    just a cast.  */
719*3d8817e4Smiod 
720*3d8817e4Smiod #define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash))
721*3d8817e4Smiod 
722*3d8817e4Smiod /* Create the dynamic sections needed if we are linking against a
723*3d8817e4Smiod    dynamic object, or if we are linking PIC compiled code.  ABFD is a
724*3d8817e4Smiod    bfd we can attach the dynamic sections to.  The linker script will
725*3d8817e4Smiod    look for these special sections names and put them in the right
726*3d8817e4Smiod    place in the output file.  See include/aout/sun4.h for more details
727*3d8817e4Smiod    of the dynamic linking information.  */
728*3d8817e4Smiod 
729*3d8817e4Smiod static bfd_boolean
sunos_create_dynamic_sections(bfd * abfd,struct bfd_link_info * info,bfd_boolean needed)730*3d8817e4Smiod sunos_create_dynamic_sections (bfd *abfd,
731*3d8817e4Smiod 			       struct bfd_link_info *info,
732*3d8817e4Smiod 			       bfd_boolean needed)
733*3d8817e4Smiod {
734*3d8817e4Smiod   asection *s;
735*3d8817e4Smiod 
736*3d8817e4Smiod   if (! sunos_hash_table (info)->dynamic_sections_created)
737*3d8817e4Smiod     {
738*3d8817e4Smiod       flagword flags;
739*3d8817e4Smiod 
740*3d8817e4Smiod       sunos_hash_table (info)->dynobj = abfd;
741*3d8817e4Smiod 
742*3d8817e4Smiod       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
743*3d8817e4Smiod 	       | SEC_LINKER_CREATED);
744*3d8817e4Smiod 
745*3d8817e4Smiod       /* The .dynamic section holds the basic dynamic information: the
746*3d8817e4Smiod 	 sun4_dynamic structure, the dynamic debugger information, and
747*3d8817e4Smiod 	 the sun4_dynamic_link structure.  */
748*3d8817e4Smiod       s = bfd_make_section (abfd, ".dynamic");
749*3d8817e4Smiod       if (s == NULL
750*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags)
751*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
752*3d8817e4Smiod 	return FALSE;
753*3d8817e4Smiod 
754*3d8817e4Smiod       /* The .got section holds the global offset table.  The address
755*3d8817e4Smiod 	 is put in the ld_got field.  */
756*3d8817e4Smiod       s = bfd_make_section (abfd, ".got");
757*3d8817e4Smiod       if (s == NULL
758*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags)
759*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
760*3d8817e4Smiod 	return FALSE;
761*3d8817e4Smiod 
762*3d8817e4Smiod       /* The .plt section holds the procedure linkage table.  The
763*3d8817e4Smiod 	 address is put in the ld_plt field.  */
764*3d8817e4Smiod       s = bfd_make_section (abfd, ".plt");
765*3d8817e4Smiod       if (s == NULL
766*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE)
767*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
768*3d8817e4Smiod 	return FALSE;
769*3d8817e4Smiod 
770*3d8817e4Smiod       /* The .dynrel section holds the dynamic relocs.  The address is
771*3d8817e4Smiod 	 put in the ld_rel field.  */
772*3d8817e4Smiod       s = bfd_make_section (abfd, ".dynrel");
773*3d8817e4Smiod       if (s == NULL
774*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
775*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
776*3d8817e4Smiod 	return FALSE;
777*3d8817e4Smiod 
778*3d8817e4Smiod       /* The .hash section holds the dynamic hash table.  The address
779*3d8817e4Smiod 	 is put in the ld_hash field.  */
780*3d8817e4Smiod       s = bfd_make_section (abfd, ".hash");
781*3d8817e4Smiod       if (s == NULL
782*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
783*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
784*3d8817e4Smiod 	return FALSE;
785*3d8817e4Smiod 
786*3d8817e4Smiod       /* The .dynsym section holds the dynamic symbols.  The address
787*3d8817e4Smiod 	 is put in the ld_stab field.  */
788*3d8817e4Smiod       s = bfd_make_section (abfd, ".dynsym");
789*3d8817e4Smiod       if (s == NULL
790*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
791*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
792*3d8817e4Smiod 	return FALSE;
793*3d8817e4Smiod 
794*3d8817e4Smiod       /* The .dynstr section holds the dynamic symbol string table.
795*3d8817e4Smiod 	 The address is put in the ld_symbols field.  */
796*3d8817e4Smiod       s = bfd_make_section (abfd, ".dynstr");
797*3d8817e4Smiod       if (s == NULL
798*3d8817e4Smiod 	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
799*3d8817e4Smiod 	  || ! bfd_set_section_alignment (abfd, s, 2))
800*3d8817e4Smiod 	return FALSE;
801*3d8817e4Smiod 
802*3d8817e4Smiod       sunos_hash_table (info)->dynamic_sections_created = TRUE;
803*3d8817e4Smiod     }
804*3d8817e4Smiod 
805*3d8817e4Smiod   if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed)
806*3d8817e4Smiod       || info->shared)
807*3d8817e4Smiod     {
808*3d8817e4Smiod       bfd *dynobj;
809*3d8817e4Smiod 
810*3d8817e4Smiod       dynobj = sunos_hash_table (info)->dynobj;
811*3d8817e4Smiod 
812*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".got");
813*3d8817e4Smiod       if (s->size == 0)
814*3d8817e4Smiod 	s->size = BYTES_IN_WORD;
815*3d8817e4Smiod 
816*3d8817e4Smiod       sunos_hash_table (info)->dynamic_sections_needed = TRUE;
817*3d8817e4Smiod       sunos_hash_table (info)->got_needed = TRUE;
818*3d8817e4Smiod     }
819*3d8817e4Smiod 
820*3d8817e4Smiod   return TRUE;
821*3d8817e4Smiod }
822*3d8817e4Smiod 
823*3d8817e4Smiod /* Add dynamic symbols during a link.  This is called by the a.out
824*3d8817e4Smiod    backend linker for each object it encounters.  */
825*3d8817e4Smiod 
826*3d8817e4Smiod static bfd_boolean
sunos_add_dynamic_symbols(bfd * abfd,struct bfd_link_info * info,struct external_nlist ** symsp,bfd_size_type * sym_countp,char ** stringsp)827*3d8817e4Smiod sunos_add_dynamic_symbols (bfd *abfd,
828*3d8817e4Smiod 			   struct bfd_link_info *info,
829*3d8817e4Smiod 			   struct external_nlist **symsp,
830*3d8817e4Smiod 			   bfd_size_type *sym_countp,
831*3d8817e4Smiod 			   char **stringsp)
832*3d8817e4Smiod {
833*3d8817e4Smiod   bfd *dynobj;
834*3d8817e4Smiod   struct sunos_dynamic_info *dinfo;
835*3d8817e4Smiod   unsigned long need;
836*3d8817e4Smiod 
837*3d8817e4Smiod   /* Make sure we have all the required sections.  */
838*3d8817e4Smiod   if (info->hash->creator == abfd->xvec)
839*3d8817e4Smiod     {
840*3d8817e4Smiod       if (! sunos_create_dynamic_sections (abfd, info,
841*3d8817e4Smiod 					   ((abfd->flags & DYNAMIC) != 0
842*3d8817e4Smiod 					    && !info->relocatable)))
843*3d8817e4Smiod 	return FALSE;
844*3d8817e4Smiod     }
845*3d8817e4Smiod 
846*3d8817e4Smiod   /* There is nothing else to do for a normal object.  */
847*3d8817e4Smiod   if ((abfd->flags & DYNAMIC) == 0)
848*3d8817e4Smiod     return TRUE;
849*3d8817e4Smiod 
850*3d8817e4Smiod   dynobj = sunos_hash_table (info)->dynobj;
851*3d8817e4Smiod 
852*3d8817e4Smiod   /* We do not want to include the sections in a dynamic object in the
853*3d8817e4Smiod      output file.  We hack by simply clobbering the list of sections
854*3d8817e4Smiod      in the BFD.  This could be handled more cleanly by, say, a new
855*3d8817e4Smiod      section flag; the existing SEC_NEVER_LOAD flag is not the one we
856*3d8817e4Smiod      want, because that one still implies that the section takes up
857*3d8817e4Smiod      space in the output file.  If this is the first object we have
858*3d8817e4Smiod      seen, we must preserve the dynamic sections we just created.  */
859*3d8817e4Smiod   if (abfd != dynobj)
860*3d8817e4Smiod     abfd->sections = NULL;
861*3d8817e4Smiod   else
862*3d8817e4Smiod     {
863*3d8817e4Smiod       asection *s;
864*3d8817e4Smiod 
865*3d8817e4Smiod       for (s = abfd->sections; s != NULL; s = s->next)
866*3d8817e4Smiod 	{
867*3d8817e4Smiod 	  if ((s->flags & SEC_LINKER_CREATED) == 0)
868*3d8817e4Smiod 	    bfd_section_list_remove (abfd, s);
869*3d8817e4Smiod 	}
870*3d8817e4Smiod     }
871*3d8817e4Smiod 
872*3d8817e4Smiod   /* The native linker seems to just ignore dynamic objects when -r is
873*3d8817e4Smiod      used.  */
874*3d8817e4Smiod   if (info->relocatable)
875*3d8817e4Smiod     return TRUE;
876*3d8817e4Smiod 
877*3d8817e4Smiod   /* There's no hope of using a dynamic object which does not exactly
878*3d8817e4Smiod      match the format of the output file.  */
879*3d8817e4Smiod   if (info->hash->creator != abfd->xvec)
880*3d8817e4Smiod     {
881*3d8817e4Smiod       bfd_set_error (bfd_error_invalid_operation);
882*3d8817e4Smiod       return FALSE;
883*3d8817e4Smiod     }
884*3d8817e4Smiod 
885*3d8817e4Smiod   /* Make sure we have a .need and a .rules sections.  These are only
886*3d8817e4Smiod      needed if there really is a dynamic object in the link, so they
887*3d8817e4Smiod      are not added by sunos_create_dynamic_sections.  */
888*3d8817e4Smiod   if (bfd_get_section_by_name (dynobj, ".need") == NULL)
889*3d8817e4Smiod     {
890*3d8817e4Smiod       /* The .need section holds the list of names of shared objets
891*3d8817e4Smiod 	 which must be included at runtime.  The address of this
892*3d8817e4Smiod 	 section is put in the ld_need field.  */
893*3d8817e4Smiod       asection *s = bfd_make_section (dynobj, ".need");
894*3d8817e4Smiod       if (s == NULL
895*3d8817e4Smiod 	  || ! bfd_set_section_flags (dynobj, s,
896*3d8817e4Smiod 				      (SEC_ALLOC
897*3d8817e4Smiod 				       | SEC_LOAD
898*3d8817e4Smiod 				       | SEC_HAS_CONTENTS
899*3d8817e4Smiod 				       | SEC_IN_MEMORY
900*3d8817e4Smiod 				       | SEC_READONLY))
901*3d8817e4Smiod 	  || ! bfd_set_section_alignment (dynobj, s, 2))
902*3d8817e4Smiod 	return FALSE;
903*3d8817e4Smiod     }
904*3d8817e4Smiod 
905*3d8817e4Smiod   if (bfd_get_section_by_name (dynobj, ".rules") == NULL)
906*3d8817e4Smiod     {
907*3d8817e4Smiod       /* The .rules section holds the path to search for shared
908*3d8817e4Smiod 	 objects.  The address of this section is put in the ld_rules
909*3d8817e4Smiod 	 field.  */
910*3d8817e4Smiod       asection *s = bfd_make_section (dynobj, ".rules");
911*3d8817e4Smiod       if (s == NULL
912*3d8817e4Smiod 	  || ! bfd_set_section_flags (dynobj, s,
913*3d8817e4Smiod 				      (SEC_ALLOC
914*3d8817e4Smiod 				       | SEC_LOAD
915*3d8817e4Smiod 				       | SEC_HAS_CONTENTS
916*3d8817e4Smiod 				       | SEC_IN_MEMORY
917*3d8817e4Smiod 				       | SEC_READONLY))
918*3d8817e4Smiod 	  || ! bfd_set_section_alignment (dynobj, s, 2))
919*3d8817e4Smiod 	return FALSE;
920*3d8817e4Smiod     }
921*3d8817e4Smiod 
922*3d8817e4Smiod   /* Pick up the dynamic symbols and return them to the caller.  */
923*3d8817e4Smiod   if (! sunos_slurp_dynamic_symtab (abfd))
924*3d8817e4Smiod     return FALSE;
925*3d8817e4Smiod 
926*3d8817e4Smiod   dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
927*3d8817e4Smiod   *symsp = dinfo->dynsym;
928*3d8817e4Smiod   *sym_countp = dinfo->dynsym_count;
929*3d8817e4Smiod   *stringsp = dinfo->dynstr;
930*3d8817e4Smiod 
931*3d8817e4Smiod   /* Record information about any other objects needed by this one.  */
932*3d8817e4Smiod   need = dinfo->dyninfo.ld_need;
933*3d8817e4Smiod   while (need != 0)
934*3d8817e4Smiod     {
935*3d8817e4Smiod       bfd_byte buf[16];
936*3d8817e4Smiod       unsigned long name, flags;
937*3d8817e4Smiod       unsigned short major_vno, minor_vno;
938*3d8817e4Smiod       struct bfd_link_needed_list *needed, **pp;
939*3d8817e4Smiod       char *namebuf, *p;
940*3d8817e4Smiod       bfd_size_type alc;
941*3d8817e4Smiod       bfd_byte b;
942*3d8817e4Smiod       char *namecopy;
943*3d8817e4Smiod 
944*3d8817e4Smiod       if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0
945*3d8817e4Smiod 	  || bfd_bread (buf, (bfd_size_type) 16, abfd) != 16)
946*3d8817e4Smiod 	return FALSE;
947*3d8817e4Smiod 
948*3d8817e4Smiod       /* For the format of an ld_need entry, see aout/sun4.h.  We
949*3d8817e4Smiod 	 should probably define structs for this manipulation.  */
950*3d8817e4Smiod       name = bfd_get_32 (abfd, buf);
951*3d8817e4Smiod       flags = bfd_get_32 (abfd, buf + 4);
952*3d8817e4Smiod       major_vno = (unsigned short) bfd_get_16 (abfd, buf + 8);
953*3d8817e4Smiod       minor_vno = (unsigned short) bfd_get_16 (abfd, buf + 10);
954*3d8817e4Smiod       need = bfd_get_32 (abfd, buf + 12);
955*3d8817e4Smiod 
956*3d8817e4Smiod       alc = sizeof (struct bfd_link_needed_list);
957*3d8817e4Smiod       needed = bfd_alloc (abfd, alc);
958*3d8817e4Smiod       if (needed == NULL)
959*3d8817e4Smiod 	return FALSE;
960*3d8817e4Smiod       needed->by = abfd;
961*3d8817e4Smiod 
962*3d8817e4Smiod       /* We return the name as [-l]name[.maj][.min].  */
963*3d8817e4Smiod       alc = 30;
964*3d8817e4Smiod       namebuf = bfd_malloc (alc + 1);
965*3d8817e4Smiod       if (namebuf == NULL)
966*3d8817e4Smiod 	return FALSE;
967*3d8817e4Smiod       p = namebuf;
968*3d8817e4Smiod 
969*3d8817e4Smiod       if ((flags & 0x80000000) != 0)
970*3d8817e4Smiod 	{
971*3d8817e4Smiod 	  *p++ = '-';
972*3d8817e4Smiod 	  *p++ = 'l';
973*3d8817e4Smiod 	}
974*3d8817e4Smiod       if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0)
975*3d8817e4Smiod 	{
976*3d8817e4Smiod 	  free (namebuf);
977*3d8817e4Smiod 	  return FALSE;
978*3d8817e4Smiod 	}
979*3d8817e4Smiod 
980*3d8817e4Smiod       do
981*3d8817e4Smiod 	{
982*3d8817e4Smiod 	  if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1)
983*3d8817e4Smiod 	    {
984*3d8817e4Smiod 	      free (namebuf);
985*3d8817e4Smiod 	      return FALSE;
986*3d8817e4Smiod 	    }
987*3d8817e4Smiod 
988*3d8817e4Smiod 	  if ((bfd_size_type) (p - namebuf) >= alc)
989*3d8817e4Smiod 	    {
990*3d8817e4Smiod 	      char *n;
991*3d8817e4Smiod 
992*3d8817e4Smiod 	      alc *= 2;
993*3d8817e4Smiod 	      n = bfd_realloc (namebuf, alc + 1);
994*3d8817e4Smiod 	      if (n == NULL)
995*3d8817e4Smiod 		{
996*3d8817e4Smiod 		  free (namebuf);
997*3d8817e4Smiod 		  return FALSE;
998*3d8817e4Smiod 		}
999*3d8817e4Smiod 	      p = n + (p - namebuf);
1000*3d8817e4Smiod 	      namebuf = n;
1001*3d8817e4Smiod 	    }
1002*3d8817e4Smiod 
1003*3d8817e4Smiod 	  *p++ = b;
1004*3d8817e4Smiod 	}
1005*3d8817e4Smiod       while (b != '\0');
1006*3d8817e4Smiod 
1007*3d8817e4Smiod       if (major_vno == 0)
1008*3d8817e4Smiod 	*p = '\0';
1009*3d8817e4Smiod       else
1010*3d8817e4Smiod 	{
1011*3d8817e4Smiod 	  char majbuf[30];
1012*3d8817e4Smiod 	  char minbuf[30];
1013*3d8817e4Smiod 
1014*3d8817e4Smiod 	  sprintf (majbuf, ".%d", major_vno);
1015*3d8817e4Smiod 	  if (minor_vno == 0)
1016*3d8817e4Smiod 	    minbuf[0] = '\0';
1017*3d8817e4Smiod 	  else
1018*3d8817e4Smiod 	    sprintf (minbuf, ".%d", minor_vno);
1019*3d8817e4Smiod 
1020*3d8817e4Smiod 	  if ((p - namebuf) + strlen (majbuf) + strlen (minbuf) >= alc)
1021*3d8817e4Smiod 	    {
1022*3d8817e4Smiod 	      char *n;
1023*3d8817e4Smiod 
1024*3d8817e4Smiod 	      alc = (p - namebuf) + strlen (majbuf) + strlen (minbuf);
1025*3d8817e4Smiod 	      n = bfd_realloc (namebuf, alc + 1);
1026*3d8817e4Smiod 	      if (n == NULL)
1027*3d8817e4Smiod 		{
1028*3d8817e4Smiod 		  free (namebuf);
1029*3d8817e4Smiod 		  return FALSE;
1030*3d8817e4Smiod 		}
1031*3d8817e4Smiod 	      p = n + (p - namebuf);
1032*3d8817e4Smiod 	      namebuf = n;
1033*3d8817e4Smiod 	    }
1034*3d8817e4Smiod 
1035*3d8817e4Smiod 	  strcpy (p, majbuf);
1036*3d8817e4Smiod 	  strcat (p, minbuf);
1037*3d8817e4Smiod 	}
1038*3d8817e4Smiod 
1039*3d8817e4Smiod       namecopy = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
1040*3d8817e4Smiod       if (namecopy == NULL)
1041*3d8817e4Smiod 	{
1042*3d8817e4Smiod 	  free (namebuf);
1043*3d8817e4Smiod 	  return FALSE;
1044*3d8817e4Smiod 	}
1045*3d8817e4Smiod       strcpy (namecopy, namebuf);
1046*3d8817e4Smiod       free (namebuf);
1047*3d8817e4Smiod       needed->name = namecopy;
1048*3d8817e4Smiod 
1049*3d8817e4Smiod       needed->next = NULL;
1050*3d8817e4Smiod 
1051*3d8817e4Smiod       for (pp = &sunos_hash_table (info)->needed;
1052*3d8817e4Smiod 	   *pp != NULL;
1053*3d8817e4Smiod 	   pp = &(*pp)->next)
1054*3d8817e4Smiod 	;
1055*3d8817e4Smiod       *pp = needed;
1056*3d8817e4Smiod     }
1057*3d8817e4Smiod 
1058*3d8817e4Smiod   return TRUE;
1059*3d8817e4Smiod }
1060*3d8817e4Smiod 
1061*3d8817e4Smiod /* Function to add a single symbol to the linker hash table.  This is
1062*3d8817e4Smiod    a wrapper around _bfd_generic_link_add_one_symbol which handles the
1063*3d8817e4Smiod    tweaking needed for dynamic linking support.  */
1064*3d8817e4Smiod 
1065*3d8817e4Smiod static bfd_boolean
sunos_add_one_symbol(struct bfd_link_info * info,bfd * abfd,const char * name,flagword flags,asection * section,bfd_vma value,const char * string,bfd_boolean copy,bfd_boolean collect,struct bfd_link_hash_entry ** hashp)1066*3d8817e4Smiod sunos_add_one_symbol (struct bfd_link_info *info,
1067*3d8817e4Smiod 		      bfd *abfd,
1068*3d8817e4Smiod 		      const char *name,
1069*3d8817e4Smiod 		      flagword flags,
1070*3d8817e4Smiod 		      asection *section,
1071*3d8817e4Smiod 		      bfd_vma value,
1072*3d8817e4Smiod 		      const char *string,
1073*3d8817e4Smiod 		      bfd_boolean copy,
1074*3d8817e4Smiod 		      bfd_boolean collect,
1075*3d8817e4Smiod 		      struct bfd_link_hash_entry **hashp)
1076*3d8817e4Smiod {
1077*3d8817e4Smiod   struct sunos_link_hash_entry *h;
1078*3d8817e4Smiod   int new_flag;
1079*3d8817e4Smiod 
1080*3d8817e4Smiod   if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0
1081*3d8817e4Smiod       || ! bfd_is_und_section (section))
1082*3d8817e4Smiod     h = sunos_link_hash_lookup (sunos_hash_table (info), name, TRUE, copy,
1083*3d8817e4Smiod 				FALSE);
1084*3d8817e4Smiod   else
1085*3d8817e4Smiod     h = ((struct sunos_link_hash_entry *)
1086*3d8817e4Smiod 	 bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, copy, FALSE));
1087*3d8817e4Smiod   if (h == NULL)
1088*3d8817e4Smiod     return FALSE;
1089*3d8817e4Smiod 
1090*3d8817e4Smiod   if (hashp != NULL)
1091*3d8817e4Smiod     *hashp = (struct bfd_link_hash_entry *) h;
1092*3d8817e4Smiod 
1093*3d8817e4Smiod   /* Treat a common symbol in a dynamic object as defined in the .bss
1094*3d8817e4Smiod      section of the dynamic object.  We don't want to allocate space
1095*3d8817e4Smiod      for it in our process image.  */
1096*3d8817e4Smiod   if ((abfd->flags & DYNAMIC) != 0
1097*3d8817e4Smiod       && bfd_is_com_section (section))
1098*3d8817e4Smiod     section = obj_bsssec (abfd);
1099*3d8817e4Smiod 
1100*3d8817e4Smiod   if (! bfd_is_und_section (section)
1101*3d8817e4Smiod       && h->root.root.type != bfd_link_hash_new
1102*3d8817e4Smiod       && h->root.root.type != bfd_link_hash_undefined
1103*3d8817e4Smiod       && h->root.root.type != bfd_link_hash_defweak)
1104*3d8817e4Smiod     {
1105*3d8817e4Smiod       /* We are defining the symbol, and it is already defined.  This
1106*3d8817e4Smiod 	 is a potential multiple definition error.  */
1107*3d8817e4Smiod       if ((abfd->flags & DYNAMIC) != 0)
1108*3d8817e4Smiod 	{
1109*3d8817e4Smiod 	  /* The definition we are adding is from a dynamic object.
1110*3d8817e4Smiod 	     We do not want this new definition to override the
1111*3d8817e4Smiod 	     existing definition, so we pretend it is just a
1112*3d8817e4Smiod 	     reference.  */
1113*3d8817e4Smiod 	  section = bfd_und_section_ptr;
1114*3d8817e4Smiod 	}
1115*3d8817e4Smiod       else if (h->root.root.type == bfd_link_hash_defined
1116*3d8817e4Smiod 	       && h->root.root.u.def.section->owner != NULL
1117*3d8817e4Smiod 	       && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
1118*3d8817e4Smiod 	{
1119*3d8817e4Smiod 	  /* The existing definition is from a dynamic object.  We
1120*3d8817e4Smiod 	     want to override it with the definition we just found.
1121*3d8817e4Smiod 	     Clobber the existing definition.  */
1122*3d8817e4Smiod 	  h->root.root.type = bfd_link_hash_undefined;
1123*3d8817e4Smiod 	  h->root.root.u.undef.abfd = h->root.root.u.def.section->owner;
1124*3d8817e4Smiod 	}
1125*3d8817e4Smiod       else if (h->root.root.type == bfd_link_hash_common
1126*3d8817e4Smiod 	       && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0)
1127*3d8817e4Smiod 	{
1128*3d8817e4Smiod 	  /* The existing definition is from a dynamic object.  We
1129*3d8817e4Smiod 	     want to override it with the definition we just found.
1130*3d8817e4Smiod 	     Clobber the existing definition.  We can't set it to new,
1131*3d8817e4Smiod 	     because it is on the undefined list.  */
1132*3d8817e4Smiod 	  h->root.root.type = bfd_link_hash_undefined;
1133*3d8817e4Smiod 	  h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner;
1134*3d8817e4Smiod 	}
1135*3d8817e4Smiod     }
1136*3d8817e4Smiod 
1137*3d8817e4Smiod   if ((abfd->flags & DYNAMIC) != 0
1138*3d8817e4Smiod       && abfd->xvec == info->hash->creator
1139*3d8817e4Smiod       && (h->flags & SUNOS_CONSTRUCTOR) != 0)
1140*3d8817e4Smiod     /* The existing symbol is a constructor symbol, and this symbol
1141*3d8817e4Smiod        is from a dynamic object.  A constructor symbol is actually a
1142*3d8817e4Smiod        definition, although the type will be bfd_link_hash_undefined
1143*3d8817e4Smiod        at this point.  We want to ignore the definition from the
1144*3d8817e4Smiod        dynamic object.  */
1145*3d8817e4Smiod     section = bfd_und_section_ptr;
1146*3d8817e4Smiod   else if ((flags & BSF_CONSTRUCTOR) != 0
1147*3d8817e4Smiod 	   && (abfd->flags & DYNAMIC) == 0
1148*3d8817e4Smiod 	   && h->root.root.type == bfd_link_hash_defined
1149*3d8817e4Smiod 	   && h->root.root.u.def.section->owner != NULL
1150*3d8817e4Smiod 	   && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
1151*3d8817e4Smiod     /* The existing symbol is defined by a dynamic object, and this
1152*3d8817e4Smiod        is a constructor symbol.  As above, we want to force the use
1153*3d8817e4Smiod        of the constructor symbol from the regular object.  */
1154*3d8817e4Smiod     h->root.root.type = bfd_link_hash_new;
1155*3d8817e4Smiod 
1156*3d8817e4Smiod   /* Do the usual procedure for adding a symbol.  */
1157*3d8817e4Smiod   if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
1158*3d8817e4Smiod 					  value, string, copy, collect,
1159*3d8817e4Smiod 					  hashp))
1160*3d8817e4Smiod     return FALSE;
1161*3d8817e4Smiod 
1162*3d8817e4Smiod   if (abfd->xvec == info->hash->creator)
1163*3d8817e4Smiod     {
1164*3d8817e4Smiod       /* Set a flag in the hash table entry indicating the type of
1165*3d8817e4Smiod 	 reference or definition we just found.  Keep a count of the
1166*3d8817e4Smiod 	 number of dynamic symbols we find.  A dynamic symbol is one
1167*3d8817e4Smiod 	 which is referenced or defined by both a regular object and a
1168*3d8817e4Smiod 	 shared object.  */
1169*3d8817e4Smiod       if ((abfd->flags & DYNAMIC) == 0)
1170*3d8817e4Smiod 	{
1171*3d8817e4Smiod 	  if (bfd_is_und_section (section))
1172*3d8817e4Smiod 	    new_flag = SUNOS_REF_REGULAR;
1173*3d8817e4Smiod 	  else
1174*3d8817e4Smiod 	    new_flag = SUNOS_DEF_REGULAR;
1175*3d8817e4Smiod 	}
1176*3d8817e4Smiod       else
1177*3d8817e4Smiod 	{
1178*3d8817e4Smiod 	  if (bfd_is_und_section (section))
1179*3d8817e4Smiod 	    new_flag = SUNOS_REF_DYNAMIC;
1180*3d8817e4Smiod 	  else
1181*3d8817e4Smiod 	    new_flag = SUNOS_DEF_DYNAMIC;
1182*3d8817e4Smiod 	}
1183*3d8817e4Smiod       h->flags |= new_flag;
1184*3d8817e4Smiod 
1185*3d8817e4Smiod       if (h->dynindx == -1
1186*3d8817e4Smiod 	  && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
1187*3d8817e4Smiod 	{
1188*3d8817e4Smiod 	  ++sunos_hash_table (info)->dynsymcount;
1189*3d8817e4Smiod 	  h->dynindx = -2;
1190*3d8817e4Smiod 	}
1191*3d8817e4Smiod 
1192*3d8817e4Smiod       if ((flags & BSF_CONSTRUCTOR) != 0
1193*3d8817e4Smiod 	  && (abfd->flags & DYNAMIC) == 0)
1194*3d8817e4Smiod 	h->flags |= SUNOS_CONSTRUCTOR;
1195*3d8817e4Smiod     }
1196*3d8817e4Smiod 
1197*3d8817e4Smiod   return TRUE;
1198*3d8817e4Smiod }
1199*3d8817e4Smiod 
1200*3d8817e4Smiod extern const bfd_target MY (vec);
1201*3d8817e4Smiod 
1202*3d8817e4Smiod /* Return the list of objects needed by BFD.  */
1203*3d8817e4Smiod 
1204*3d8817e4Smiod struct bfd_link_needed_list *
bfd_sunos_get_needed_list(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)1205*3d8817e4Smiod bfd_sunos_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
1206*3d8817e4Smiod 			   struct bfd_link_info *info)
1207*3d8817e4Smiod {
1208*3d8817e4Smiod   if (info->hash->creator != &MY (vec))
1209*3d8817e4Smiod     return NULL;
1210*3d8817e4Smiod   return sunos_hash_table (info)->needed;
1211*3d8817e4Smiod }
1212*3d8817e4Smiod 
1213*3d8817e4Smiod /* Record an assignment made to a symbol by a linker script.  We need
1214*3d8817e4Smiod    this in case some dynamic object refers to this symbol.  */
1215*3d8817e4Smiod 
1216*3d8817e4Smiod bfd_boolean
bfd_sunos_record_link_assignment(bfd * output_bfd,struct bfd_link_info * info,const char * name)1217*3d8817e4Smiod bfd_sunos_record_link_assignment (bfd *output_bfd,
1218*3d8817e4Smiod 				  struct bfd_link_info *info,
1219*3d8817e4Smiod 				  const char *name)
1220*3d8817e4Smiod {
1221*3d8817e4Smiod   struct sunos_link_hash_entry *h;
1222*3d8817e4Smiod 
1223*3d8817e4Smiod   if (output_bfd->xvec != &MY(vec))
1224*3d8817e4Smiod     return TRUE;
1225*3d8817e4Smiod 
1226*3d8817e4Smiod   /* This is called after we have examined all the input objects.  If
1227*3d8817e4Smiod      the symbol does not exist, it merely means that no object refers
1228*3d8817e4Smiod      to it, and we can just ignore it at this point.  */
1229*3d8817e4Smiod   h = sunos_link_hash_lookup (sunos_hash_table (info), name,
1230*3d8817e4Smiod 			      FALSE, FALSE, FALSE);
1231*3d8817e4Smiod   if (h == NULL)
1232*3d8817e4Smiod     return TRUE;
1233*3d8817e4Smiod 
1234*3d8817e4Smiod   /* In a shared library, the __DYNAMIC symbol does not appear in the
1235*3d8817e4Smiod      dynamic symbol table.  */
1236*3d8817e4Smiod   if (! info->shared || strcmp (name, "__DYNAMIC") != 0)
1237*3d8817e4Smiod     {
1238*3d8817e4Smiod       h->flags |= SUNOS_DEF_REGULAR;
1239*3d8817e4Smiod 
1240*3d8817e4Smiod       if (h->dynindx == -1)
1241*3d8817e4Smiod 	{
1242*3d8817e4Smiod 	  ++sunos_hash_table (info)->dynsymcount;
1243*3d8817e4Smiod 	  h->dynindx = -2;
1244*3d8817e4Smiod 	}
1245*3d8817e4Smiod     }
1246*3d8817e4Smiod 
1247*3d8817e4Smiod   return TRUE;
1248*3d8817e4Smiod }
1249*3d8817e4Smiod 
1250*3d8817e4Smiod /* Scan the relocs for an input section using standard relocs.  We
1251*3d8817e4Smiod    need to figure out what to do for each reloc against a dynamic
1252*3d8817e4Smiod    symbol.  If the symbol is in the .text section, an entry is made in
1253*3d8817e4Smiod    the procedure linkage table.  Note that this will do the wrong
1254*3d8817e4Smiod    thing if the symbol is actually data; I don't think the Sun 3
1255*3d8817e4Smiod    native linker handles this case correctly either.  If the symbol is
1256*3d8817e4Smiod    not in the .text section, we must preserve the reloc as a dynamic
1257*3d8817e4Smiod    reloc.  FIXME: We should also handle the PIC relocs here by
1258*3d8817e4Smiod    building global offset table entries.  */
1259*3d8817e4Smiod 
1260*3d8817e4Smiod static bfd_boolean
sunos_scan_std_relocs(struct bfd_link_info * info,bfd * abfd,asection * sec ATTRIBUTE_UNUSED,const struct reloc_std_external * relocs,bfd_size_type rel_size)1261*3d8817e4Smiod sunos_scan_std_relocs (struct bfd_link_info *info,
1262*3d8817e4Smiod 		       bfd *abfd,
1263*3d8817e4Smiod 		       asection *sec ATTRIBUTE_UNUSED,
1264*3d8817e4Smiod 		       const struct reloc_std_external *relocs,
1265*3d8817e4Smiod 		       bfd_size_type rel_size)
1266*3d8817e4Smiod {
1267*3d8817e4Smiod   bfd *dynobj;
1268*3d8817e4Smiod   asection *splt = NULL;
1269*3d8817e4Smiod   asection *srel = NULL;
1270*3d8817e4Smiod   struct sunos_link_hash_entry **sym_hashes;
1271*3d8817e4Smiod   const struct reloc_std_external *rel, *relend;
1272*3d8817e4Smiod 
1273*3d8817e4Smiod   /* We only know how to handle m68k plt entries.  */
1274*3d8817e4Smiod   if (bfd_get_arch (abfd) != bfd_arch_m68k)
1275*3d8817e4Smiod     {
1276*3d8817e4Smiod       bfd_set_error (bfd_error_invalid_target);
1277*3d8817e4Smiod       return FALSE;
1278*3d8817e4Smiod     }
1279*3d8817e4Smiod 
1280*3d8817e4Smiod   dynobj = NULL;
1281*3d8817e4Smiod 
1282*3d8817e4Smiod   sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
1283*3d8817e4Smiod 
1284*3d8817e4Smiod   relend = relocs + rel_size / RELOC_STD_SIZE;
1285*3d8817e4Smiod   for (rel = relocs; rel < relend; rel++)
1286*3d8817e4Smiod     {
1287*3d8817e4Smiod       int r_index;
1288*3d8817e4Smiod       struct sunos_link_hash_entry *h;
1289*3d8817e4Smiod 
1290*3d8817e4Smiod       /* We only want relocs against external symbols.  */
1291*3d8817e4Smiod       if (bfd_header_big_endian (abfd))
1292*3d8817e4Smiod 	{
1293*3d8817e4Smiod 	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0)
1294*3d8817e4Smiod 	    continue;
1295*3d8817e4Smiod 	}
1296*3d8817e4Smiod       else
1297*3d8817e4Smiod 	{
1298*3d8817e4Smiod 	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0)
1299*3d8817e4Smiod 	    continue;
1300*3d8817e4Smiod 	}
1301*3d8817e4Smiod 
1302*3d8817e4Smiod       /* Get the symbol index.  */
1303*3d8817e4Smiod       if (bfd_header_big_endian (abfd))
1304*3d8817e4Smiod 	r_index = ((rel->r_index[0] << 16)
1305*3d8817e4Smiod 		   | (rel->r_index[1] << 8)
1306*3d8817e4Smiod 		   | rel->r_index[2]);
1307*3d8817e4Smiod       else
1308*3d8817e4Smiod 	r_index = ((rel->r_index[2] << 16)
1309*3d8817e4Smiod 		   | (rel->r_index[1] << 8)
1310*3d8817e4Smiod 		   | rel->r_index[0]);
1311*3d8817e4Smiod 
1312*3d8817e4Smiod       /* Get the hash table entry.  */
1313*3d8817e4Smiod       h = sym_hashes[r_index];
1314*3d8817e4Smiod       if (h == NULL)
1315*3d8817e4Smiod 	/* This should not normally happen, but it will in any case
1316*3d8817e4Smiod 	   be caught in the relocation phase.  */
1317*3d8817e4Smiod 	continue;
1318*3d8817e4Smiod 
1319*3d8817e4Smiod       /* At this point common symbols have already been allocated, so
1320*3d8817e4Smiod 	 we don't have to worry about them.  We need to consider that
1321*3d8817e4Smiod 	 we may have already seen this symbol and marked it undefined;
1322*3d8817e4Smiod 	 if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
1323*3d8817e4Smiod 	 will be zero.  */
1324*3d8817e4Smiod       if (h->root.root.type != bfd_link_hash_defined
1325*3d8817e4Smiod 	  && h->root.root.type != bfd_link_hash_defweak
1326*3d8817e4Smiod 	  && h->root.root.type != bfd_link_hash_undefined)
1327*3d8817e4Smiod 	continue;
1328*3d8817e4Smiod 
1329*3d8817e4Smiod       if ((h->flags & SUNOS_DEF_DYNAMIC) == 0
1330*3d8817e4Smiod 	  || (h->flags & SUNOS_DEF_REGULAR) != 0)
1331*3d8817e4Smiod 	continue;
1332*3d8817e4Smiod 
1333*3d8817e4Smiod       if (dynobj == NULL)
1334*3d8817e4Smiod 	{
1335*3d8817e4Smiod 	  asection *sgot;
1336*3d8817e4Smiod 
1337*3d8817e4Smiod 	  if (! sunos_create_dynamic_sections (abfd, info, FALSE))
1338*3d8817e4Smiod 	    return FALSE;
1339*3d8817e4Smiod 	  dynobj = sunos_hash_table (info)->dynobj;
1340*3d8817e4Smiod 	  splt = bfd_get_section_by_name (dynobj, ".plt");
1341*3d8817e4Smiod 	  srel = bfd_get_section_by_name (dynobj, ".dynrel");
1342*3d8817e4Smiod 	  BFD_ASSERT (splt != NULL && srel != NULL);
1343*3d8817e4Smiod 
1344*3d8817e4Smiod 	  sgot = bfd_get_section_by_name (dynobj, ".got");
1345*3d8817e4Smiod 	  BFD_ASSERT (sgot != NULL);
1346*3d8817e4Smiod 	  if (sgot->size == 0)
1347*3d8817e4Smiod 	    sgot->size = BYTES_IN_WORD;
1348*3d8817e4Smiod 	  sunos_hash_table (info)->got_needed = TRUE;
1349*3d8817e4Smiod 	}
1350*3d8817e4Smiod 
1351*3d8817e4Smiod       BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
1352*3d8817e4Smiod       BFD_ASSERT (h->plt_offset != 0
1353*3d8817e4Smiod 		  || ((h->root.root.type == bfd_link_hash_defined
1354*3d8817e4Smiod 		       || h->root.root.type == bfd_link_hash_defweak)
1355*3d8817e4Smiod 		      ? (h->root.root.u.def.section->owner->flags
1356*3d8817e4Smiod 			 & DYNAMIC) != 0
1357*3d8817e4Smiod 		      : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
1358*3d8817e4Smiod 
1359*3d8817e4Smiod       /* This reloc is against a symbol defined only by a dynamic
1360*3d8817e4Smiod 	 object.  */
1361*3d8817e4Smiod       if (h->root.root.type == bfd_link_hash_undefined)
1362*3d8817e4Smiod 	/* Presumably this symbol was marked as being undefined by
1363*3d8817e4Smiod 	   an earlier reloc.  */
1364*3d8817e4Smiod 	srel->size += RELOC_STD_SIZE;
1365*3d8817e4Smiod       else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0)
1366*3d8817e4Smiod 	{
1367*3d8817e4Smiod 	  bfd *sub;
1368*3d8817e4Smiod 
1369*3d8817e4Smiod 	  /* This reloc is not in the .text section.  It must be
1370*3d8817e4Smiod 	     copied into the dynamic relocs.  We mark the symbol as
1371*3d8817e4Smiod 	     being undefined.  */
1372*3d8817e4Smiod 	  srel->size += RELOC_STD_SIZE;
1373*3d8817e4Smiod 	  sub = h->root.root.u.def.section->owner;
1374*3d8817e4Smiod 	  h->root.root.type = bfd_link_hash_undefined;
1375*3d8817e4Smiod 	  h->root.root.u.undef.abfd = sub;
1376*3d8817e4Smiod 	}
1377*3d8817e4Smiod       else
1378*3d8817e4Smiod 	{
1379*3d8817e4Smiod 	  /* This symbol is in the .text section.  We must give it an
1380*3d8817e4Smiod 	     entry in the procedure linkage table, if we have not
1381*3d8817e4Smiod 	     already done so.  We change the definition of the symbol
1382*3d8817e4Smiod 	     to the .plt section; this will cause relocs against it to
1383*3d8817e4Smiod 	     be handled correctly.  */
1384*3d8817e4Smiod 	  if (h->plt_offset == 0)
1385*3d8817e4Smiod 	    {
1386*3d8817e4Smiod 	      if (splt->size == 0)
1387*3d8817e4Smiod 		splt->size = M68K_PLT_ENTRY_SIZE;
1388*3d8817e4Smiod 	      h->plt_offset = splt->size;
1389*3d8817e4Smiod 
1390*3d8817e4Smiod 	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
1391*3d8817e4Smiod 		{
1392*3d8817e4Smiod 		  h->root.root.u.def.section = splt;
1393*3d8817e4Smiod 		  h->root.root.u.def.value = splt->size;
1394*3d8817e4Smiod 		}
1395*3d8817e4Smiod 
1396*3d8817e4Smiod 	      splt->size += M68K_PLT_ENTRY_SIZE;
1397*3d8817e4Smiod 
1398*3d8817e4Smiod 	      /* We may also need a dynamic reloc entry.  */
1399*3d8817e4Smiod 	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
1400*3d8817e4Smiod 		srel->size += RELOC_STD_SIZE;
1401*3d8817e4Smiod 	    }
1402*3d8817e4Smiod 	}
1403*3d8817e4Smiod     }
1404*3d8817e4Smiod 
1405*3d8817e4Smiod   return TRUE;
1406*3d8817e4Smiod }
1407*3d8817e4Smiod 
1408*3d8817e4Smiod /* Scan the relocs for an input section using extended relocs.  We
1409*3d8817e4Smiod    need to figure out what to do for each reloc against a dynamic
1410*3d8817e4Smiod    symbol.  If the reloc is a WDISP30, and the symbol is in the .text
1411*3d8817e4Smiod    section, an entry is made in the procedure linkage table.
1412*3d8817e4Smiod    Otherwise, we must preserve the reloc as a dynamic reloc.  */
1413*3d8817e4Smiod 
1414*3d8817e4Smiod static bfd_boolean
sunos_scan_ext_relocs(struct bfd_link_info * info,bfd * abfd,asection * sec ATTRIBUTE_UNUSED,const struct reloc_ext_external * relocs,bfd_size_type rel_size)1415*3d8817e4Smiod sunos_scan_ext_relocs (struct bfd_link_info *info,
1416*3d8817e4Smiod 		       bfd *abfd,
1417*3d8817e4Smiod 		       asection *sec ATTRIBUTE_UNUSED,
1418*3d8817e4Smiod 		       const struct reloc_ext_external *relocs,
1419*3d8817e4Smiod 		       bfd_size_type rel_size)
1420*3d8817e4Smiod {
1421*3d8817e4Smiod   bfd *dynobj;
1422*3d8817e4Smiod   struct sunos_link_hash_entry **sym_hashes;
1423*3d8817e4Smiod   const struct reloc_ext_external *rel, *relend;
1424*3d8817e4Smiod   asection *splt = NULL;
1425*3d8817e4Smiod   asection *sgot = NULL;
1426*3d8817e4Smiod   asection *srel = NULL;
1427*3d8817e4Smiod   bfd_size_type amt;
1428*3d8817e4Smiod 
1429*3d8817e4Smiod   /* We only know how to handle SPARC plt entries.  */
1430*3d8817e4Smiod   if (bfd_get_arch (abfd) != bfd_arch_sparc)
1431*3d8817e4Smiod     {
1432*3d8817e4Smiod       bfd_set_error (bfd_error_invalid_target);
1433*3d8817e4Smiod       return FALSE;
1434*3d8817e4Smiod     }
1435*3d8817e4Smiod 
1436*3d8817e4Smiod   dynobj = NULL;
1437*3d8817e4Smiod 
1438*3d8817e4Smiod   sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);
1439*3d8817e4Smiod 
1440*3d8817e4Smiod   relend = relocs + rel_size / RELOC_EXT_SIZE;
1441*3d8817e4Smiod   for (rel = relocs; rel < relend; rel++)
1442*3d8817e4Smiod     {
1443*3d8817e4Smiod       unsigned int r_index;
1444*3d8817e4Smiod       int r_extern;
1445*3d8817e4Smiod       int r_type;
1446*3d8817e4Smiod       struct sunos_link_hash_entry *h = NULL;
1447*3d8817e4Smiod 
1448*3d8817e4Smiod       /* Swap in the reloc information.  */
1449*3d8817e4Smiod       if (bfd_header_big_endian (abfd))
1450*3d8817e4Smiod 	{
1451*3d8817e4Smiod 	  r_index = ((rel->r_index[0] << 16)
1452*3d8817e4Smiod 		     | (rel->r_index[1] << 8)
1453*3d8817e4Smiod 		     | rel->r_index[2]);
1454*3d8817e4Smiod 	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1455*3d8817e4Smiod 	  r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1456*3d8817e4Smiod 		    >> RELOC_EXT_BITS_TYPE_SH_BIG);
1457*3d8817e4Smiod 	}
1458*3d8817e4Smiod       else
1459*3d8817e4Smiod 	{
1460*3d8817e4Smiod 	  r_index = ((rel->r_index[2] << 16)
1461*3d8817e4Smiod 		     | (rel->r_index[1] << 8)
1462*3d8817e4Smiod 		     | rel->r_index[0]);
1463*3d8817e4Smiod 	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1464*3d8817e4Smiod 	  r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1465*3d8817e4Smiod 		    >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
1466*3d8817e4Smiod 	}
1467*3d8817e4Smiod 
1468*3d8817e4Smiod       if (r_extern)
1469*3d8817e4Smiod 	{
1470*3d8817e4Smiod 	  h = sym_hashes[r_index];
1471*3d8817e4Smiod 	  if (h == NULL)
1472*3d8817e4Smiod 	    {
1473*3d8817e4Smiod 	      /* This should not normally happen, but it will in any
1474*3d8817e4Smiod 		 case be caught in the relocation phase.  */
1475*3d8817e4Smiod 	      continue;
1476*3d8817e4Smiod 	    }
1477*3d8817e4Smiod 	}
1478*3d8817e4Smiod 
1479*3d8817e4Smiod       /* If this is a base relative reloc, we need to make an entry in
1480*3d8817e4Smiod 	 the .got section.  */
1481*3d8817e4Smiod       if (r_type == RELOC_BASE10
1482*3d8817e4Smiod 	  || r_type == RELOC_BASE13
1483*3d8817e4Smiod 	  || r_type == RELOC_BASE22)
1484*3d8817e4Smiod 	{
1485*3d8817e4Smiod 	  if (dynobj == NULL)
1486*3d8817e4Smiod 	    {
1487*3d8817e4Smiod 	      if (! sunos_create_dynamic_sections (abfd, info, FALSE))
1488*3d8817e4Smiod 		return FALSE;
1489*3d8817e4Smiod 	      dynobj = sunos_hash_table (info)->dynobj;
1490*3d8817e4Smiod 	      splt = bfd_get_section_by_name (dynobj, ".plt");
1491*3d8817e4Smiod 	      sgot = bfd_get_section_by_name (dynobj, ".got");
1492*3d8817e4Smiod 	      srel = bfd_get_section_by_name (dynobj, ".dynrel");
1493*3d8817e4Smiod 	      BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
1494*3d8817e4Smiod 
1495*3d8817e4Smiod 	      /* Make sure we have an initial entry in the .got table.  */
1496*3d8817e4Smiod 	      if (sgot->size == 0)
1497*3d8817e4Smiod 		sgot->size = BYTES_IN_WORD;
1498*3d8817e4Smiod 	      sunos_hash_table (info)->got_needed = TRUE;
1499*3d8817e4Smiod 	    }
1500*3d8817e4Smiod 
1501*3d8817e4Smiod 	  if (r_extern)
1502*3d8817e4Smiod 	    {
1503*3d8817e4Smiod 	      if (h->got_offset != 0)
1504*3d8817e4Smiod 		continue;
1505*3d8817e4Smiod 
1506*3d8817e4Smiod 	      h->got_offset = sgot->size;
1507*3d8817e4Smiod 	    }
1508*3d8817e4Smiod 	  else
1509*3d8817e4Smiod 	    {
1510*3d8817e4Smiod 	      if (r_index >= bfd_get_symcount (abfd))
1511*3d8817e4Smiod 		/* This is abnormal, but should be caught in the
1512*3d8817e4Smiod 		   relocation phase.  */
1513*3d8817e4Smiod 		continue;
1514*3d8817e4Smiod 
1515*3d8817e4Smiod 	      if (adata (abfd).local_got_offsets == NULL)
1516*3d8817e4Smiod 		{
1517*3d8817e4Smiod 		  amt = bfd_get_symcount (abfd);
1518*3d8817e4Smiod 		  amt *= sizeof (bfd_vma);
1519*3d8817e4Smiod 		  adata (abfd).local_got_offsets = bfd_zalloc (abfd, amt);
1520*3d8817e4Smiod 		  if (adata (abfd).local_got_offsets == NULL)
1521*3d8817e4Smiod 		    return FALSE;
1522*3d8817e4Smiod 		}
1523*3d8817e4Smiod 
1524*3d8817e4Smiod 	      if (adata (abfd).local_got_offsets[r_index] != 0)
1525*3d8817e4Smiod 		continue;
1526*3d8817e4Smiod 
1527*3d8817e4Smiod 	      adata (abfd).local_got_offsets[r_index] = sgot->size;
1528*3d8817e4Smiod 	    }
1529*3d8817e4Smiod 
1530*3d8817e4Smiod 	  sgot->size += BYTES_IN_WORD;
1531*3d8817e4Smiod 
1532*3d8817e4Smiod 	  /* If we are making a shared library, or if the symbol is
1533*3d8817e4Smiod 	     defined by a dynamic object, we will need a dynamic reloc
1534*3d8817e4Smiod 	     entry.  */
1535*3d8817e4Smiod 	  if (info->shared
1536*3d8817e4Smiod 	      || (h != NULL
1537*3d8817e4Smiod 		  && (h->flags & SUNOS_DEF_DYNAMIC) != 0
1538*3d8817e4Smiod 		  && (h->flags & SUNOS_DEF_REGULAR) == 0))
1539*3d8817e4Smiod 	    srel->size += RELOC_EXT_SIZE;
1540*3d8817e4Smiod 
1541*3d8817e4Smiod 	  continue;
1542*3d8817e4Smiod 	}
1543*3d8817e4Smiod 
1544*3d8817e4Smiod       /* Otherwise, we are only interested in relocs against symbols
1545*3d8817e4Smiod 	 defined in dynamic objects but not in regular objects.  We
1546*3d8817e4Smiod 	 only need to consider relocs against external symbols.  */
1547*3d8817e4Smiod       if (! r_extern)
1548*3d8817e4Smiod 	{
1549*3d8817e4Smiod 	  /* But, if we are creating a shared library, we need to
1550*3d8817e4Smiod 	     generate an absolute reloc.  */
1551*3d8817e4Smiod 	  if (info->shared)
1552*3d8817e4Smiod 	    {
1553*3d8817e4Smiod 	      if (dynobj == NULL)
1554*3d8817e4Smiod 		{
1555*3d8817e4Smiod 		  if (! sunos_create_dynamic_sections (abfd, info, TRUE))
1556*3d8817e4Smiod 		    return FALSE;
1557*3d8817e4Smiod 		  dynobj = sunos_hash_table (info)->dynobj;
1558*3d8817e4Smiod 		  splt = bfd_get_section_by_name (dynobj, ".plt");
1559*3d8817e4Smiod 		  sgot = bfd_get_section_by_name (dynobj, ".got");
1560*3d8817e4Smiod 		  srel = bfd_get_section_by_name (dynobj, ".dynrel");
1561*3d8817e4Smiod 		  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
1562*3d8817e4Smiod 		}
1563*3d8817e4Smiod 
1564*3d8817e4Smiod 	      srel->size += RELOC_EXT_SIZE;
1565*3d8817e4Smiod 	    }
1566*3d8817e4Smiod 
1567*3d8817e4Smiod 	  continue;
1568*3d8817e4Smiod 	}
1569*3d8817e4Smiod 
1570*3d8817e4Smiod       /* At this point common symbols have already been allocated, so
1571*3d8817e4Smiod 	 we don't have to worry about them.  We need to consider that
1572*3d8817e4Smiod 	 we may have already seen this symbol and marked it undefined;
1573*3d8817e4Smiod 	 if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
1574*3d8817e4Smiod 	 will be zero.  */
1575*3d8817e4Smiod       if (h->root.root.type != bfd_link_hash_defined
1576*3d8817e4Smiod 	  && h->root.root.type != bfd_link_hash_defweak
1577*3d8817e4Smiod 	  && h->root.root.type != bfd_link_hash_undefined)
1578*3d8817e4Smiod 	continue;
1579*3d8817e4Smiod 
1580*3d8817e4Smiod       if (r_type != RELOC_JMP_TBL
1581*3d8817e4Smiod 	  && ! info->shared
1582*3d8817e4Smiod 	  && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
1583*3d8817e4Smiod 	      || (h->flags & SUNOS_DEF_REGULAR) != 0))
1584*3d8817e4Smiod 	continue;
1585*3d8817e4Smiod 
1586*3d8817e4Smiod       if (r_type == RELOC_JMP_TBL
1587*3d8817e4Smiod 	  && ! info->shared
1588*3d8817e4Smiod 	  && (h->flags & SUNOS_DEF_DYNAMIC) == 0
1589*3d8817e4Smiod 	  && (h->flags & SUNOS_DEF_REGULAR) == 0)
1590*3d8817e4Smiod 	{
1591*3d8817e4Smiod 	  /* This symbol is apparently undefined.  Don't do anything
1592*3d8817e4Smiod 	     here; just let the relocation routine report an undefined
1593*3d8817e4Smiod 	     symbol.  */
1594*3d8817e4Smiod 	  continue;
1595*3d8817e4Smiod 	}
1596*3d8817e4Smiod 
1597*3d8817e4Smiod       if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
1598*3d8817e4Smiod 	continue;
1599*3d8817e4Smiod 
1600*3d8817e4Smiod       if (dynobj == NULL)
1601*3d8817e4Smiod 	{
1602*3d8817e4Smiod 	  if (! sunos_create_dynamic_sections (abfd, info, FALSE))
1603*3d8817e4Smiod 	    return FALSE;
1604*3d8817e4Smiod 	  dynobj = sunos_hash_table (info)->dynobj;
1605*3d8817e4Smiod 	  splt = bfd_get_section_by_name (dynobj, ".plt");
1606*3d8817e4Smiod 	  sgot = bfd_get_section_by_name (dynobj, ".got");
1607*3d8817e4Smiod 	  srel = bfd_get_section_by_name (dynobj, ".dynrel");
1608*3d8817e4Smiod 	  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
1609*3d8817e4Smiod 
1610*3d8817e4Smiod 	  /* Make sure we have an initial entry in the .got table.  */
1611*3d8817e4Smiod 	  if (sgot->size == 0)
1612*3d8817e4Smiod 	    sgot->size = BYTES_IN_WORD;
1613*3d8817e4Smiod 	  sunos_hash_table (info)->got_needed = TRUE;
1614*3d8817e4Smiod 	}
1615*3d8817e4Smiod 
1616*3d8817e4Smiod       BFD_ASSERT (r_type == RELOC_JMP_TBL
1617*3d8817e4Smiod 		  || info->shared
1618*3d8817e4Smiod 		  || (h->flags & SUNOS_REF_REGULAR) != 0);
1619*3d8817e4Smiod       BFD_ASSERT (r_type == RELOC_JMP_TBL
1620*3d8817e4Smiod 		  || info->shared
1621*3d8817e4Smiod 		  || h->plt_offset != 0
1622*3d8817e4Smiod 		  || ((h->root.root.type == bfd_link_hash_defined
1623*3d8817e4Smiod 		       || h->root.root.type == bfd_link_hash_defweak)
1624*3d8817e4Smiod 		      ? (h->root.root.u.def.section->owner->flags
1625*3d8817e4Smiod 			 & DYNAMIC) != 0
1626*3d8817e4Smiod 		      : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));
1627*3d8817e4Smiod 
1628*3d8817e4Smiod       /* This reloc is against a symbol defined only by a dynamic
1629*3d8817e4Smiod 	 object, or it is a jump table reloc from PIC compiled code.  */
1630*3d8817e4Smiod 
1631*3d8817e4Smiod       if (r_type != RELOC_JMP_TBL
1632*3d8817e4Smiod 	  && h->root.root.type == bfd_link_hash_undefined)
1633*3d8817e4Smiod 	/* Presumably this symbol was marked as being undefined by
1634*3d8817e4Smiod 	   an earlier reloc.  */
1635*3d8817e4Smiod 	srel->size += RELOC_EXT_SIZE;
1636*3d8817e4Smiod 
1637*3d8817e4Smiod       else if (r_type != RELOC_JMP_TBL
1638*3d8817e4Smiod 	       && (h->root.root.u.def.section->flags & SEC_CODE) == 0)
1639*3d8817e4Smiod 	{
1640*3d8817e4Smiod 	  bfd *sub;
1641*3d8817e4Smiod 
1642*3d8817e4Smiod 	  /* This reloc is not in the .text section.  It must be
1643*3d8817e4Smiod 	     copied into the dynamic relocs.  We mark the symbol as
1644*3d8817e4Smiod 	     being undefined.  */
1645*3d8817e4Smiod 	  srel->size += RELOC_EXT_SIZE;
1646*3d8817e4Smiod 	  if ((h->flags & SUNOS_DEF_REGULAR) == 0)
1647*3d8817e4Smiod 	    {
1648*3d8817e4Smiod 	      sub = h->root.root.u.def.section->owner;
1649*3d8817e4Smiod 	      h->root.root.type = bfd_link_hash_undefined;
1650*3d8817e4Smiod 	      h->root.root.u.undef.abfd = sub;
1651*3d8817e4Smiod 	    }
1652*3d8817e4Smiod 	}
1653*3d8817e4Smiod       else
1654*3d8817e4Smiod 	{
1655*3d8817e4Smiod 	  /* This symbol is in the .text section.  We must give it an
1656*3d8817e4Smiod 	     entry in the procedure linkage table, if we have not
1657*3d8817e4Smiod 	     already done so.  We change the definition of the symbol
1658*3d8817e4Smiod 	     to the .plt section; this will cause relocs against it to
1659*3d8817e4Smiod 	     be handled correctly.  */
1660*3d8817e4Smiod 	  if (h->plt_offset == 0)
1661*3d8817e4Smiod 	    {
1662*3d8817e4Smiod 	      if (splt->size == 0)
1663*3d8817e4Smiod 		splt->size = SPARC_PLT_ENTRY_SIZE;
1664*3d8817e4Smiod 	      h->plt_offset = splt->size;
1665*3d8817e4Smiod 
1666*3d8817e4Smiod 	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
1667*3d8817e4Smiod 		{
1668*3d8817e4Smiod 		  if (h->root.root.type == bfd_link_hash_undefined)
1669*3d8817e4Smiod 		    h->root.root.type = bfd_link_hash_defined;
1670*3d8817e4Smiod 		  h->root.root.u.def.section = splt;
1671*3d8817e4Smiod 		  h->root.root.u.def.value = splt->size;
1672*3d8817e4Smiod 		}
1673*3d8817e4Smiod 
1674*3d8817e4Smiod 	      splt->size += SPARC_PLT_ENTRY_SIZE;
1675*3d8817e4Smiod 
1676*3d8817e4Smiod 	      /* We will also need a dynamic reloc entry, unless this
1677*3d8817e4Smiod 		 is a JMP_TBL reloc produced by linking PIC compiled
1678*3d8817e4Smiod 		 code, and we are not making a shared library.  */
1679*3d8817e4Smiod 	      if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
1680*3d8817e4Smiod 		srel->size += RELOC_EXT_SIZE;
1681*3d8817e4Smiod 	    }
1682*3d8817e4Smiod 
1683*3d8817e4Smiod 	  /* If we are creating a shared library, we need to copy over
1684*3d8817e4Smiod 	     any reloc other than a jump table reloc.  */
1685*3d8817e4Smiod 	  if (info->shared && r_type != RELOC_JMP_TBL)
1686*3d8817e4Smiod 	    srel->size += RELOC_EXT_SIZE;
1687*3d8817e4Smiod 	}
1688*3d8817e4Smiod     }
1689*3d8817e4Smiod 
1690*3d8817e4Smiod   return TRUE;
1691*3d8817e4Smiod }
1692*3d8817e4Smiod 
1693*3d8817e4Smiod /* Scan the relocs for an input section.  */
1694*3d8817e4Smiod 
1695*3d8817e4Smiod static bfd_boolean
sunos_scan_relocs(struct bfd_link_info * info,bfd * abfd,asection * sec,bfd_size_type rel_size)1696*3d8817e4Smiod sunos_scan_relocs (struct bfd_link_info *info,
1697*3d8817e4Smiod 		   bfd *abfd,
1698*3d8817e4Smiod 		   asection *sec,
1699*3d8817e4Smiod 		   bfd_size_type rel_size)
1700*3d8817e4Smiod {
1701*3d8817e4Smiod   void * relocs;
1702*3d8817e4Smiod   void * free_relocs = NULL;
1703*3d8817e4Smiod 
1704*3d8817e4Smiod   if (rel_size == 0)
1705*3d8817e4Smiod     return TRUE;
1706*3d8817e4Smiod 
1707*3d8817e4Smiod   if (! info->keep_memory)
1708*3d8817e4Smiod     relocs = free_relocs = bfd_malloc (rel_size);
1709*3d8817e4Smiod   else
1710*3d8817e4Smiod     {
1711*3d8817e4Smiod       struct aout_section_data_struct *n;
1712*3d8817e4Smiod       bfd_size_type amt = sizeof (struct aout_section_data_struct);
1713*3d8817e4Smiod 
1714*3d8817e4Smiod       n = bfd_alloc (abfd, amt);
1715*3d8817e4Smiod       if (n == NULL)
1716*3d8817e4Smiod 	relocs = NULL;
1717*3d8817e4Smiod       else
1718*3d8817e4Smiod 	{
1719*3d8817e4Smiod 	  set_aout_section_data (sec, n);
1720*3d8817e4Smiod 	  relocs = bfd_malloc (rel_size);
1721*3d8817e4Smiod 	  aout_section_data (sec)->relocs = relocs;
1722*3d8817e4Smiod 	}
1723*3d8817e4Smiod     }
1724*3d8817e4Smiod   if (relocs == NULL)
1725*3d8817e4Smiod     return FALSE;
1726*3d8817e4Smiod 
1727*3d8817e4Smiod   if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
1728*3d8817e4Smiod       || bfd_bread (relocs, rel_size, abfd) != rel_size)
1729*3d8817e4Smiod     goto error_return;
1730*3d8817e4Smiod 
1731*3d8817e4Smiod   if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE)
1732*3d8817e4Smiod     {
1733*3d8817e4Smiod       if (! sunos_scan_std_relocs (info, abfd, sec,
1734*3d8817e4Smiod 				   (struct reloc_std_external *) relocs,
1735*3d8817e4Smiod 				   rel_size))
1736*3d8817e4Smiod 	goto error_return;
1737*3d8817e4Smiod     }
1738*3d8817e4Smiod   else
1739*3d8817e4Smiod     {
1740*3d8817e4Smiod       if (! sunos_scan_ext_relocs (info, abfd, sec,
1741*3d8817e4Smiod 				   (struct reloc_ext_external *) relocs,
1742*3d8817e4Smiod 				   rel_size))
1743*3d8817e4Smiod 	goto error_return;
1744*3d8817e4Smiod     }
1745*3d8817e4Smiod 
1746*3d8817e4Smiod   if (free_relocs != NULL)
1747*3d8817e4Smiod     free (free_relocs);
1748*3d8817e4Smiod 
1749*3d8817e4Smiod   return TRUE;
1750*3d8817e4Smiod 
1751*3d8817e4Smiod  error_return:
1752*3d8817e4Smiod   if (free_relocs != NULL)
1753*3d8817e4Smiod     free (free_relocs);
1754*3d8817e4Smiod   return FALSE;
1755*3d8817e4Smiod }
1756*3d8817e4Smiod 
1757*3d8817e4Smiod /* Build the hash table of dynamic symbols, and to mark as written all
1758*3d8817e4Smiod    symbols from dynamic objects which we do not plan to write out.  */
1759*3d8817e4Smiod 
1760*3d8817e4Smiod static bfd_boolean
sunos_scan_dynamic_symbol(struct sunos_link_hash_entry * h,void * data)1761*3d8817e4Smiod sunos_scan_dynamic_symbol (struct sunos_link_hash_entry *h, void * data)
1762*3d8817e4Smiod {
1763*3d8817e4Smiod   struct bfd_link_info *info = (struct bfd_link_info *) data;
1764*3d8817e4Smiod 
1765*3d8817e4Smiod   if (h->root.root.type == bfd_link_hash_warning)
1766*3d8817e4Smiod     h = (struct sunos_link_hash_entry *) h->root.root.u.i.link;
1767*3d8817e4Smiod 
1768*3d8817e4Smiod   /* Set the written flag for symbols we do not want to write out as
1769*3d8817e4Smiod      part of the regular symbol table.  This is all symbols which are
1770*3d8817e4Smiod      not defined in a regular object file.  For some reason symbols
1771*3d8817e4Smiod      which are referenced by a regular object and defined by a dynamic
1772*3d8817e4Smiod      object do not seem to show up in the regular symbol table.  It is
1773*3d8817e4Smiod      possible for a symbol to have only SUNOS_REF_REGULAR set here, it
1774*3d8817e4Smiod      is an undefined symbol which was turned into a common symbol
1775*3d8817e4Smiod      because it was found in an archive object which was not included
1776*3d8817e4Smiod      in the link.  */
1777*3d8817e4Smiod   if ((h->flags & SUNOS_DEF_REGULAR) == 0
1778*3d8817e4Smiod       && (h->flags & SUNOS_DEF_DYNAMIC) != 0
1779*3d8817e4Smiod       && strcmp (h->root.root.root.string, "__DYNAMIC") != 0)
1780*3d8817e4Smiod     h->root.written = TRUE;
1781*3d8817e4Smiod 
1782*3d8817e4Smiod   /* If this symbol is defined by a dynamic object and referenced by a
1783*3d8817e4Smiod      regular object, see whether we gave it a reasonable value while
1784*3d8817e4Smiod      scanning the relocs.  */
1785*3d8817e4Smiod   if ((h->flags & SUNOS_DEF_REGULAR) == 0
1786*3d8817e4Smiod       && (h->flags & SUNOS_DEF_DYNAMIC) != 0
1787*3d8817e4Smiod       && (h->flags & SUNOS_REF_REGULAR) != 0)
1788*3d8817e4Smiod     {
1789*3d8817e4Smiod       if ((h->root.root.type == bfd_link_hash_defined
1790*3d8817e4Smiod 	   || h->root.root.type == bfd_link_hash_defweak)
1791*3d8817e4Smiod 	  && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
1792*3d8817e4Smiod 	  && h->root.root.u.def.section->output_section == NULL)
1793*3d8817e4Smiod 	{
1794*3d8817e4Smiod 	  bfd *sub;
1795*3d8817e4Smiod 
1796*3d8817e4Smiod 	  /* This symbol is currently defined in a dynamic section
1797*3d8817e4Smiod 	     which is not being put into the output file.  This
1798*3d8817e4Smiod 	     implies that there is no reloc against the symbol.  I'm
1799*3d8817e4Smiod 	     not sure why this case would ever occur.  In any case, we
1800*3d8817e4Smiod 	     change the symbol to be undefined.  */
1801*3d8817e4Smiod 	  sub = h->root.root.u.def.section->owner;
1802*3d8817e4Smiod 	  h->root.root.type = bfd_link_hash_undefined;
1803*3d8817e4Smiod 	  h->root.root.u.undef.abfd = sub;
1804*3d8817e4Smiod 	}
1805*3d8817e4Smiod     }
1806*3d8817e4Smiod 
1807*3d8817e4Smiod   /* If this symbol is defined or referenced by a regular file, add it
1808*3d8817e4Smiod      to the dynamic symbols.  */
1809*3d8817e4Smiod   if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
1810*3d8817e4Smiod     {
1811*3d8817e4Smiod       asection *s;
1812*3d8817e4Smiod       size_t len;
1813*3d8817e4Smiod       bfd_byte *contents;
1814*3d8817e4Smiod       unsigned char *name;
1815*3d8817e4Smiod       unsigned long hash;
1816*3d8817e4Smiod       bfd *dynobj;
1817*3d8817e4Smiod 
1818*3d8817e4Smiod       BFD_ASSERT (h->dynindx == -2);
1819*3d8817e4Smiod 
1820*3d8817e4Smiod       dynobj = sunos_hash_table (info)->dynobj;
1821*3d8817e4Smiod 
1822*3d8817e4Smiod       h->dynindx = sunos_hash_table (info)->dynsymcount;
1823*3d8817e4Smiod       ++sunos_hash_table (info)->dynsymcount;
1824*3d8817e4Smiod 
1825*3d8817e4Smiod       len = strlen (h->root.root.root.string);
1826*3d8817e4Smiod 
1827*3d8817e4Smiod       /* We don't bother to construct a BFD hash table for the strings
1828*3d8817e4Smiod 	 which are the names of the dynamic symbols.  Using a hash
1829*3d8817e4Smiod 	 table for the regular symbols is beneficial, because the
1830*3d8817e4Smiod 	 regular symbols includes the debugging symbols, which have
1831*3d8817e4Smiod 	 long names and are often duplicated in several object files.
1832*3d8817e4Smiod 	 There are no debugging symbols in the dynamic symbols.  */
1833*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynstr");
1834*3d8817e4Smiod       BFD_ASSERT (s != NULL);
1835*3d8817e4Smiod       contents = bfd_realloc (s->contents, s->size + len + 1);
1836*3d8817e4Smiod       if (contents == NULL)
1837*3d8817e4Smiod 	return FALSE;
1838*3d8817e4Smiod       s->contents = contents;
1839*3d8817e4Smiod 
1840*3d8817e4Smiod       h->dynstr_index = s->size;
1841*3d8817e4Smiod       strcpy ((char *) contents + s->size, h->root.root.root.string);
1842*3d8817e4Smiod       s->size += len + 1;
1843*3d8817e4Smiod 
1844*3d8817e4Smiod       /* Add it to the dynamic hash table.  */
1845*3d8817e4Smiod       name = (unsigned char *) h->root.root.root.string;
1846*3d8817e4Smiod       hash = 0;
1847*3d8817e4Smiod       while (*name != '\0')
1848*3d8817e4Smiod 	hash = (hash << 1) + *name++;
1849*3d8817e4Smiod       hash &= 0x7fffffff;
1850*3d8817e4Smiod       hash %= sunos_hash_table (info)->bucketcount;
1851*3d8817e4Smiod 
1852*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".hash");
1853*3d8817e4Smiod       BFD_ASSERT (s != NULL);
1854*3d8817e4Smiod 
1855*3d8817e4Smiod       if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1)
1856*3d8817e4Smiod 	PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE);
1857*3d8817e4Smiod       else
1858*3d8817e4Smiod 	{
1859*3d8817e4Smiod 	  bfd_vma next;
1860*3d8817e4Smiod 
1861*3d8817e4Smiod 	  next = GET_WORD (dynobj,
1862*3d8817e4Smiod 			   (s->contents
1863*3d8817e4Smiod 			    + hash * HASH_ENTRY_SIZE
1864*3d8817e4Smiod 			    + BYTES_IN_WORD));
1865*3d8817e4Smiod 	  PUT_WORD (dynobj, s->size / HASH_ENTRY_SIZE,
1866*3d8817e4Smiod 		    s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
1867*3d8817e4Smiod 	  PUT_WORD (dynobj, h->dynindx, s->contents + s->size);
1868*3d8817e4Smiod 	  PUT_WORD (dynobj, next, s->contents + s->size + BYTES_IN_WORD);
1869*3d8817e4Smiod 	  s->size += HASH_ENTRY_SIZE;
1870*3d8817e4Smiod 	}
1871*3d8817e4Smiod     }
1872*3d8817e4Smiod 
1873*3d8817e4Smiod   return TRUE;
1874*3d8817e4Smiod }
1875*3d8817e4Smiod 
1876*3d8817e4Smiod /* Set up the sizes and contents of the dynamic sections created in
1877*3d8817e4Smiod    sunos_add_dynamic_symbols.  This is called by the SunOS linker
1878*3d8817e4Smiod    emulation before_allocation routine.  We must set the sizes of the
1879*3d8817e4Smiod    sections before the linker sets the addresses of the various
1880*3d8817e4Smiod    sections.  This unfortunately requires reading all the relocs so
1881*3d8817e4Smiod    that we can work out which ones need to become dynamic relocs.  If
1882*3d8817e4Smiod    info->keep_memory is TRUE, we keep the relocs in memory; otherwise,
1883*3d8817e4Smiod    we discard them, and will read them again later.  */
1884*3d8817e4Smiod 
1885*3d8817e4Smiod bfd_boolean
bfd_sunos_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info,asection ** sdynptr,asection ** sneedptr,asection ** srulesptr)1886*3d8817e4Smiod bfd_sunos_size_dynamic_sections (bfd *output_bfd,
1887*3d8817e4Smiod 				 struct bfd_link_info *info,
1888*3d8817e4Smiod 				 asection **sdynptr,
1889*3d8817e4Smiod 				 asection **sneedptr,
1890*3d8817e4Smiod 				 asection **srulesptr)
1891*3d8817e4Smiod {
1892*3d8817e4Smiod   bfd *dynobj;
1893*3d8817e4Smiod   bfd_size_type dynsymcount;
1894*3d8817e4Smiod   struct sunos_link_hash_entry *h;
1895*3d8817e4Smiod   asection *s;
1896*3d8817e4Smiod   size_t bucketcount;
1897*3d8817e4Smiod   bfd_size_type hashalloc;
1898*3d8817e4Smiod   size_t i;
1899*3d8817e4Smiod   bfd *sub;
1900*3d8817e4Smiod 
1901*3d8817e4Smiod   *sdynptr = NULL;
1902*3d8817e4Smiod   *sneedptr = NULL;
1903*3d8817e4Smiod   *srulesptr = NULL;
1904*3d8817e4Smiod 
1905*3d8817e4Smiod   if (info->relocatable)
1906*3d8817e4Smiod     return TRUE;
1907*3d8817e4Smiod 
1908*3d8817e4Smiod   if (output_bfd->xvec != &MY(vec))
1909*3d8817e4Smiod     return TRUE;
1910*3d8817e4Smiod 
1911*3d8817e4Smiod   /* Look through all the input BFD's and read their relocs.  It would
1912*3d8817e4Smiod      be better if we didn't have to do this, but there is no other way
1913*3d8817e4Smiod      to determine the number of dynamic relocs we need, and, more
1914*3d8817e4Smiod      importantly, there is no other way to know which symbols should
1915*3d8817e4Smiod      get an entry in the procedure linkage table.  */
1916*3d8817e4Smiod   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
1917*3d8817e4Smiod     {
1918*3d8817e4Smiod       if ((sub->flags & DYNAMIC) == 0
1919*3d8817e4Smiod 	  && sub->xvec == output_bfd->xvec)
1920*3d8817e4Smiod 	{
1921*3d8817e4Smiod 	  if (! sunos_scan_relocs (info, sub, obj_textsec (sub),
1922*3d8817e4Smiod 				   exec_hdr (sub)->a_trsize)
1923*3d8817e4Smiod 	      || ! sunos_scan_relocs (info, sub, obj_datasec (sub),
1924*3d8817e4Smiod 				      exec_hdr (sub)->a_drsize))
1925*3d8817e4Smiod 	    return FALSE;
1926*3d8817e4Smiod 	}
1927*3d8817e4Smiod     }
1928*3d8817e4Smiod 
1929*3d8817e4Smiod   dynobj = sunos_hash_table (info)->dynobj;
1930*3d8817e4Smiod   dynsymcount = sunos_hash_table (info)->dynsymcount;
1931*3d8817e4Smiod 
1932*3d8817e4Smiod   /* If there were no dynamic objects in the link, and we don't need
1933*3d8817e4Smiod      to build a global offset table, there is nothing to do here.  */
1934*3d8817e4Smiod   if (! sunos_hash_table (info)->dynamic_sections_needed
1935*3d8817e4Smiod       && ! sunos_hash_table (info)->got_needed)
1936*3d8817e4Smiod     return TRUE;
1937*3d8817e4Smiod 
1938*3d8817e4Smiod   /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it.  */
1939*3d8817e4Smiod   h = sunos_link_hash_lookup (sunos_hash_table (info),
1940*3d8817e4Smiod 			      "__GLOBAL_OFFSET_TABLE_", FALSE, FALSE, FALSE);
1941*3d8817e4Smiod   if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)
1942*3d8817e4Smiod     {
1943*3d8817e4Smiod       h->flags |= SUNOS_DEF_REGULAR;
1944*3d8817e4Smiod       if (h->dynindx == -1)
1945*3d8817e4Smiod 	{
1946*3d8817e4Smiod 	  ++sunos_hash_table (info)->dynsymcount;
1947*3d8817e4Smiod 	  h->dynindx = -2;
1948*3d8817e4Smiod 	}
1949*3d8817e4Smiod       h->root.root.type = bfd_link_hash_defined;
1950*3d8817e4Smiod       h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");
1951*3d8817e4Smiod 
1952*3d8817e4Smiod       /* If the .got section is more than 0x1000 bytes, we set
1953*3d8817e4Smiod 	 __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,
1954*3d8817e4Smiod 	 so that 13 bit relocations have a greater chance of working.  */
1955*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".got");
1956*3d8817e4Smiod       BFD_ASSERT (s != NULL);
1957*3d8817e4Smiod       if (s->size >= 0x1000)
1958*3d8817e4Smiod 	h->root.root.u.def.value = 0x1000;
1959*3d8817e4Smiod       else
1960*3d8817e4Smiod 	h->root.root.u.def.value = 0;
1961*3d8817e4Smiod 
1962*3d8817e4Smiod       sunos_hash_table (info)->got_base = h->root.root.u.def.value;
1963*3d8817e4Smiod     }
1964*3d8817e4Smiod 
1965*3d8817e4Smiod   /* If there are any shared objects in the link, then we need to set
1966*3d8817e4Smiod      up the dynamic linking information.  */
1967*3d8817e4Smiod   if (sunos_hash_table (info)->dynamic_sections_needed)
1968*3d8817e4Smiod     {
1969*3d8817e4Smiod       *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");
1970*3d8817e4Smiod 
1971*3d8817e4Smiod       /* The .dynamic section is always the same size.  */
1972*3d8817e4Smiod       s = *sdynptr;
1973*3d8817e4Smiod       BFD_ASSERT (s != NULL);
1974*3d8817e4Smiod       s->size = (sizeof (struct external_sun4_dynamic)
1975*3d8817e4Smiod 		      + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE
1976*3d8817e4Smiod 		      + sizeof (struct external_sun4_dynamic_link));
1977*3d8817e4Smiod 
1978*3d8817e4Smiod       /* Set the size of the .dynsym and .hash sections.  We counted
1979*3d8817e4Smiod 	 the number of dynamic symbols as we read the input files.  We
1980*3d8817e4Smiod 	 will build the dynamic symbol table (.dynsym) and the hash
1981*3d8817e4Smiod 	 table (.hash) when we build the final symbol table, because
1982*3d8817e4Smiod 	 until then we do not know the correct value to give the
1983*3d8817e4Smiod 	 symbols.  We build the dynamic symbol string table (.dynstr)
1984*3d8817e4Smiod 	 in a traversal of the symbol table using
1985*3d8817e4Smiod 	 sunos_scan_dynamic_symbol.  */
1986*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynsym");
1987*3d8817e4Smiod       BFD_ASSERT (s != NULL);
1988*3d8817e4Smiod       s->size = dynsymcount * sizeof (struct external_nlist);
1989*3d8817e4Smiod       s->contents = bfd_alloc (output_bfd, s->size);
1990*3d8817e4Smiod       if (s->contents == NULL && s->size != 0)
1991*3d8817e4Smiod 	return FALSE;
1992*3d8817e4Smiod 
1993*3d8817e4Smiod       /* The number of buckets is just the number of symbols divided
1994*3d8817e4Smiod 	 by four.  To compute the final size of the hash table, we
1995*3d8817e4Smiod 	 must actually compute the hash table.  Normally we need
1996*3d8817e4Smiod 	 exactly as many entries in the hash table as there are
1997*3d8817e4Smiod 	 dynamic symbols, but if some of the buckets are not used we
1998*3d8817e4Smiod 	 will need additional entries.  In the worst case, every
1999*3d8817e4Smiod 	 symbol will hash to the same bucket, and we will need
2000*3d8817e4Smiod 	 BUCKETCOUNT - 1 extra entries.  */
2001*3d8817e4Smiod       if (dynsymcount >= 4)
2002*3d8817e4Smiod 	bucketcount = dynsymcount / 4;
2003*3d8817e4Smiod       else if (dynsymcount > 0)
2004*3d8817e4Smiod 	bucketcount = dynsymcount;
2005*3d8817e4Smiod       else
2006*3d8817e4Smiod 	bucketcount = 1;
2007*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".hash");
2008*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2009*3d8817e4Smiod       hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
2010*3d8817e4Smiod       s->contents = bfd_zalloc (dynobj, hashalloc);
2011*3d8817e4Smiod       if (s->contents == NULL && dynsymcount > 0)
2012*3d8817e4Smiod 	return FALSE;
2013*3d8817e4Smiod       for (i = 0; i < bucketcount; i++)
2014*3d8817e4Smiod 	PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);
2015*3d8817e4Smiod       s->size = bucketcount * HASH_ENTRY_SIZE;
2016*3d8817e4Smiod 
2017*3d8817e4Smiod       sunos_hash_table (info)->bucketcount = bucketcount;
2018*3d8817e4Smiod 
2019*3d8817e4Smiod       /* Scan all the symbols, place them in the dynamic symbol table,
2020*3d8817e4Smiod 	 and build the dynamic hash table.  We reuse dynsymcount as a
2021*3d8817e4Smiod 	 counter for the number of symbols we have added so far.  */
2022*3d8817e4Smiod       sunos_hash_table (info)->dynsymcount = 0;
2023*3d8817e4Smiod       sunos_link_hash_traverse (sunos_hash_table (info),
2024*3d8817e4Smiod 				sunos_scan_dynamic_symbol,
2025*3d8817e4Smiod 				(void *) info);
2026*3d8817e4Smiod       BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);
2027*3d8817e4Smiod 
2028*3d8817e4Smiod       /* The SunOS native linker seems to align the total size of the
2029*3d8817e4Smiod 	 symbol strings to a multiple of 8.  I don't know if this is
2030*3d8817e4Smiod 	 important, but it can't hurt much.  */
2031*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynstr");
2032*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2033*3d8817e4Smiod       if ((s->size & 7) != 0)
2034*3d8817e4Smiod 	{
2035*3d8817e4Smiod 	  bfd_size_type add;
2036*3d8817e4Smiod 	  bfd_byte *contents;
2037*3d8817e4Smiod 
2038*3d8817e4Smiod 	  add = 8 - (s->size & 7);
2039*3d8817e4Smiod 	  contents = bfd_realloc (s->contents, s->size + add);
2040*3d8817e4Smiod 	  if (contents == NULL)
2041*3d8817e4Smiod 	    return FALSE;
2042*3d8817e4Smiod 	  memset (contents + s->size, 0, (size_t) add);
2043*3d8817e4Smiod 	  s->contents = contents;
2044*3d8817e4Smiod 	  s->size += add;
2045*3d8817e4Smiod 	}
2046*3d8817e4Smiod     }
2047*3d8817e4Smiod 
2048*3d8817e4Smiod   /* Now that we have worked out the sizes of the procedure linkage
2049*3d8817e4Smiod      table and the dynamic relocs, allocate storage for them.  */
2050*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".plt");
2051*3d8817e4Smiod   BFD_ASSERT (s != NULL);
2052*3d8817e4Smiod   if (s->size != 0)
2053*3d8817e4Smiod     {
2054*3d8817e4Smiod       s->contents = bfd_alloc (dynobj, s->size);
2055*3d8817e4Smiod       if (s->contents == NULL)
2056*3d8817e4Smiod 	return FALSE;
2057*3d8817e4Smiod 
2058*3d8817e4Smiod       /* Fill in the first entry in the table.  */
2059*3d8817e4Smiod       switch (bfd_get_arch (dynobj))
2060*3d8817e4Smiod 	{
2061*3d8817e4Smiod 	case bfd_arch_sparc:
2062*3d8817e4Smiod 	  memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);
2063*3d8817e4Smiod 	  break;
2064*3d8817e4Smiod 
2065*3d8817e4Smiod 	case bfd_arch_m68k:
2066*3d8817e4Smiod 	  memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);
2067*3d8817e4Smiod 	  break;
2068*3d8817e4Smiod 
2069*3d8817e4Smiod 	default:
2070*3d8817e4Smiod 	  abort ();
2071*3d8817e4Smiod 	}
2072*3d8817e4Smiod     }
2073*3d8817e4Smiod 
2074*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".dynrel");
2075*3d8817e4Smiod   if (s->size != 0)
2076*3d8817e4Smiod     {
2077*3d8817e4Smiod       s->contents = bfd_alloc (dynobj, s->size);
2078*3d8817e4Smiod       if (s->contents == NULL)
2079*3d8817e4Smiod 	return FALSE;
2080*3d8817e4Smiod     }
2081*3d8817e4Smiod   /* We use the reloc_count field to keep track of how many of the
2082*3d8817e4Smiod      relocs we have output so far.  */
2083*3d8817e4Smiod   s->reloc_count = 0;
2084*3d8817e4Smiod 
2085*3d8817e4Smiod   /* Make space for the global offset table.  */
2086*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".got");
2087*3d8817e4Smiod   s->contents = bfd_alloc (dynobj, s->size);
2088*3d8817e4Smiod   if (s->contents == NULL)
2089*3d8817e4Smiod     return FALSE;
2090*3d8817e4Smiod 
2091*3d8817e4Smiod   *sneedptr = bfd_get_section_by_name (dynobj, ".need");
2092*3d8817e4Smiod   *srulesptr = bfd_get_section_by_name (dynobj, ".rules");
2093*3d8817e4Smiod 
2094*3d8817e4Smiod   return TRUE;
2095*3d8817e4Smiod }
2096*3d8817e4Smiod 
2097*3d8817e4Smiod /* Link a dynamic object.  We actually don't have anything to do at
2098*3d8817e4Smiod    this point.  This entry point exists to prevent the regular linker
2099*3d8817e4Smiod    code from doing anything with the object.  */
2100*3d8817e4Smiod 
2101*3d8817e4Smiod static bfd_boolean
sunos_link_dynamic_object(struct bfd_link_info * info ATTRIBUTE_UNUSED,bfd * abfd ATTRIBUTE_UNUSED)2102*3d8817e4Smiod sunos_link_dynamic_object (struct bfd_link_info *info ATTRIBUTE_UNUSED,
2103*3d8817e4Smiod 			   bfd *abfd ATTRIBUTE_UNUSED)
2104*3d8817e4Smiod {
2105*3d8817e4Smiod   return TRUE;
2106*3d8817e4Smiod }
2107*3d8817e4Smiod 
2108*3d8817e4Smiod /* Write out a dynamic symbol.  This is called by the final traversal
2109*3d8817e4Smiod    over the symbol table.  */
2110*3d8817e4Smiod 
2111*3d8817e4Smiod static bfd_boolean
sunos_write_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct aout_link_hash_entry * harg)2112*3d8817e4Smiod sunos_write_dynamic_symbol (bfd *output_bfd,
2113*3d8817e4Smiod 			    struct bfd_link_info *info,
2114*3d8817e4Smiod 			    struct aout_link_hash_entry *harg)
2115*3d8817e4Smiod {
2116*3d8817e4Smiod   struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
2117*3d8817e4Smiod   int type;
2118*3d8817e4Smiod   bfd_vma val;
2119*3d8817e4Smiod   asection *s;
2120*3d8817e4Smiod   struct external_nlist *outsym;
2121*3d8817e4Smiod 
2122*3d8817e4Smiod   /* If this symbol is in the procedure linkage table, fill in the
2123*3d8817e4Smiod      table entry.  */
2124*3d8817e4Smiod   if (h->plt_offset != 0)
2125*3d8817e4Smiod     {
2126*3d8817e4Smiod       bfd *dynobj;
2127*3d8817e4Smiod       asection *splt;
2128*3d8817e4Smiod       bfd_byte *p;
2129*3d8817e4Smiod       bfd_vma r_address;
2130*3d8817e4Smiod 
2131*3d8817e4Smiod       dynobj = sunos_hash_table (info)->dynobj;
2132*3d8817e4Smiod       splt = bfd_get_section_by_name (dynobj, ".plt");
2133*3d8817e4Smiod       p = splt->contents + h->plt_offset;
2134*3d8817e4Smiod 
2135*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynrel");
2136*3d8817e4Smiod 
2137*3d8817e4Smiod       r_address = (splt->output_section->vma
2138*3d8817e4Smiod 		   + splt->output_offset
2139*3d8817e4Smiod 		   + h->plt_offset);
2140*3d8817e4Smiod 
2141*3d8817e4Smiod       switch (bfd_get_arch (output_bfd))
2142*3d8817e4Smiod 	{
2143*3d8817e4Smiod 	case bfd_arch_sparc:
2144*3d8817e4Smiod 	  if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
2145*3d8817e4Smiod 	    {
2146*3d8817e4Smiod 	      bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p);
2147*3d8817e4Smiod 	      bfd_put_32 (output_bfd,
2148*3d8817e4Smiod 			  (SPARC_PLT_ENTRY_WORD1
2149*3d8817e4Smiod 			   + (((- (h->plt_offset + 4) >> 2)
2150*3d8817e4Smiod 			       & 0x3fffffff))),
2151*3d8817e4Smiod 			  p + 4);
2152*3d8817e4Smiod 	      bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count,
2153*3d8817e4Smiod 			  p + 8);
2154*3d8817e4Smiod 	    }
2155*3d8817e4Smiod 	  else
2156*3d8817e4Smiod 	    {
2157*3d8817e4Smiod 	      val = (h->root.root.u.def.section->output_section->vma
2158*3d8817e4Smiod 		     + h->root.root.u.def.section->output_offset
2159*3d8817e4Smiod 		     + h->root.root.u.def.value);
2160*3d8817e4Smiod 	      bfd_put_32 (output_bfd,
2161*3d8817e4Smiod 			  SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff),
2162*3d8817e4Smiod 			  p);
2163*3d8817e4Smiod 	      bfd_put_32 (output_bfd,
2164*3d8817e4Smiod 			  SPARC_PLT_PIC_WORD1 + (val & 0x3ff),
2165*3d8817e4Smiod 			  p + 4);
2166*3d8817e4Smiod 	      bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8);
2167*3d8817e4Smiod 	    }
2168*3d8817e4Smiod 	  break;
2169*3d8817e4Smiod 
2170*3d8817e4Smiod 	case bfd_arch_m68k:
2171*3d8817e4Smiod 	  if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0)
2172*3d8817e4Smiod 	    abort ();
2173*3d8817e4Smiod 	  bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p);
2174*3d8817e4Smiod 	  bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2);
2175*3d8817e4Smiod 	  bfd_put_16 (output_bfd, (bfd_vma) s->reloc_count, p + 6);
2176*3d8817e4Smiod 	  r_address += 2;
2177*3d8817e4Smiod 	  break;
2178*3d8817e4Smiod 
2179*3d8817e4Smiod 	default:
2180*3d8817e4Smiod 	  abort ();
2181*3d8817e4Smiod 	}
2182*3d8817e4Smiod 
2183*3d8817e4Smiod       /* We also need to add a jump table reloc, unless this is the
2184*3d8817e4Smiod 	 result of a JMP_TBL reloc from PIC compiled code.  */
2185*3d8817e4Smiod       if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
2186*3d8817e4Smiod 	{
2187*3d8817e4Smiod 	  BFD_ASSERT (h->dynindx >= 0);
2188*3d8817e4Smiod 	  BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
2189*3d8817e4Smiod 		      < s->size);
2190*3d8817e4Smiod 	  p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd);
2191*3d8817e4Smiod 	  if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE)
2192*3d8817e4Smiod 	    {
2193*3d8817e4Smiod 	      struct reloc_std_external *srel;
2194*3d8817e4Smiod 
2195*3d8817e4Smiod 	      srel = (struct reloc_std_external *) p;
2196*3d8817e4Smiod 	      PUT_WORD (output_bfd, r_address, srel->r_address);
2197*3d8817e4Smiod 	      if (bfd_header_big_endian (output_bfd))
2198*3d8817e4Smiod 		{
2199*3d8817e4Smiod 		  srel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
2200*3d8817e4Smiod 		  srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
2201*3d8817e4Smiod 		  srel->r_index[2] = (bfd_byte) (h->dynindx);
2202*3d8817e4Smiod 		  srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG
2203*3d8817e4Smiod 				     | RELOC_STD_BITS_JMPTABLE_BIG);
2204*3d8817e4Smiod 		}
2205*3d8817e4Smiod 	      else
2206*3d8817e4Smiod 		{
2207*3d8817e4Smiod 		  srel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
2208*3d8817e4Smiod 		  srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
2209*3d8817e4Smiod 		  srel->r_index[0] = (bfd_byte)h->dynindx;
2210*3d8817e4Smiod 		  srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE
2211*3d8817e4Smiod 				     | RELOC_STD_BITS_JMPTABLE_LITTLE);
2212*3d8817e4Smiod 		}
2213*3d8817e4Smiod 	    }
2214*3d8817e4Smiod 	  else
2215*3d8817e4Smiod 	    {
2216*3d8817e4Smiod 	      struct reloc_ext_external *erel;
2217*3d8817e4Smiod 
2218*3d8817e4Smiod 	      erel = (struct reloc_ext_external *) p;
2219*3d8817e4Smiod 	      PUT_WORD (output_bfd, r_address, erel->r_address);
2220*3d8817e4Smiod 	      if (bfd_header_big_endian (output_bfd))
2221*3d8817e4Smiod 		{
2222*3d8817e4Smiod 		  erel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
2223*3d8817e4Smiod 		  erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
2224*3d8817e4Smiod 		  erel->r_index[2] = (bfd_byte)h->dynindx;
2225*3d8817e4Smiod 		  erel->r_type[0] =
2226*3d8817e4Smiod 		    (RELOC_EXT_BITS_EXTERN_BIG
2227*3d8817e4Smiod 		     | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG));
2228*3d8817e4Smiod 		}
2229*3d8817e4Smiod 	      else
2230*3d8817e4Smiod 		{
2231*3d8817e4Smiod 		  erel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
2232*3d8817e4Smiod 		  erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
2233*3d8817e4Smiod 		  erel->r_index[0] = (bfd_byte)h->dynindx;
2234*3d8817e4Smiod 		  erel->r_type[0] =
2235*3d8817e4Smiod 		    (RELOC_EXT_BITS_EXTERN_LITTLE
2236*3d8817e4Smiod 		     | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2237*3d8817e4Smiod 		}
2238*3d8817e4Smiod 	      PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend);
2239*3d8817e4Smiod 	    }
2240*3d8817e4Smiod 
2241*3d8817e4Smiod 	  ++s->reloc_count;
2242*3d8817e4Smiod 	}
2243*3d8817e4Smiod     }
2244*3d8817e4Smiod 
2245*3d8817e4Smiod   /* If this is not a dynamic symbol, we don't have to do anything
2246*3d8817e4Smiod      else.  We only check this after handling the PLT entry, because
2247*3d8817e4Smiod      we can have a PLT entry for a nondynamic symbol when linking PIC
2248*3d8817e4Smiod      compiled code from a regular object.  */
2249*3d8817e4Smiod   if (h->dynindx < 0)
2250*3d8817e4Smiod     return TRUE;
2251*3d8817e4Smiod 
2252*3d8817e4Smiod   switch (h->root.root.type)
2253*3d8817e4Smiod     {
2254*3d8817e4Smiod     default:
2255*3d8817e4Smiod     case bfd_link_hash_new:
2256*3d8817e4Smiod       abort ();
2257*3d8817e4Smiod       /* Avoid variable not initialized warnings.  */
2258*3d8817e4Smiod       return TRUE;
2259*3d8817e4Smiod     case bfd_link_hash_undefined:
2260*3d8817e4Smiod       type = N_UNDF | N_EXT;
2261*3d8817e4Smiod       val = 0;
2262*3d8817e4Smiod       break;
2263*3d8817e4Smiod     case bfd_link_hash_defined:
2264*3d8817e4Smiod     case bfd_link_hash_defweak:
2265*3d8817e4Smiod       {
2266*3d8817e4Smiod 	asection *sec;
2267*3d8817e4Smiod 	asection *output_section;
2268*3d8817e4Smiod 
2269*3d8817e4Smiod 	sec = h->root.root.u.def.section;
2270*3d8817e4Smiod 	output_section = sec->output_section;
2271*3d8817e4Smiod 	BFD_ASSERT (bfd_is_abs_section (output_section)
2272*3d8817e4Smiod 		    || output_section->owner == output_bfd);
2273*3d8817e4Smiod 	if (h->plt_offset != 0
2274*3d8817e4Smiod 	    && (h->flags & SUNOS_DEF_REGULAR) == 0)
2275*3d8817e4Smiod 	  {
2276*3d8817e4Smiod 	    type = N_UNDF | N_EXT;
2277*3d8817e4Smiod 	    val = 0;
2278*3d8817e4Smiod 	  }
2279*3d8817e4Smiod 	else
2280*3d8817e4Smiod 	  {
2281*3d8817e4Smiod 	    if (output_section == obj_textsec (output_bfd))
2282*3d8817e4Smiod 	      type = (h->root.root.type == bfd_link_hash_defined
2283*3d8817e4Smiod 		      ? N_TEXT
2284*3d8817e4Smiod 		      : N_WEAKT);
2285*3d8817e4Smiod 	    else if (output_section == obj_datasec (output_bfd))
2286*3d8817e4Smiod 	      type = (h->root.root.type == bfd_link_hash_defined
2287*3d8817e4Smiod 		      ? N_DATA
2288*3d8817e4Smiod 		      : N_WEAKD);
2289*3d8817e4Smiod 	    else if (output_section == obj_bsssec (output_bfd))
2290*3d8817e4Smiod 	      type = (h->root.root.type == bfd_link_hash_defined
2291*3d8817e4Smiod 		      ? N_BSS
2292*3d8817e4Smiod 		      : N_WEAKB);
2293*3d8817e4Smiod 	    else
2294*3d8817e4Smiod 	      type = (h->root.root.type == bfd_link_hash_defined
2295*3d8817e4Smiod 		      ? N_ABS
2296*3d8817e4Smiod 		      : N_WEAKA);
2297*3d8817e4Smiod 	    type |= N_EXT;
2298*3d8817e4Smiod 	    val = (h->root.root.u.def.value
2299*3d8817e4Smiod 		   + output_section->vma
2300*3d8817e4Smiod 		   + sec->output_offset);
2301*3d8817e4Smiod 	  }
2302*3d8817e4Smiod       }
2303*3d8817e4Smiod       break;
2304*3d8817e4Smiod     case bfd_link_hash_common:
2305*3d8817e4Smiod       type = N_UNDF | N_EXT;
2306*3d8817e4Smiod       val = h->root.root.u.c.size;
2307*3d8817e4Smiod       break;
2308*3d8817e4Smiod     case bfd_link_hash_undefweak:
2309*3d8817e4Smiod       type = N_WEAKU;
2310*3d8817e4Smiod       val = 0;
2311*3d8817e4Smiod       break;
2312*3d8817e4Smiod     case bfd_link_hash_indirect:
2313*3d8817e4Smiod     case bfd_link_hash_warning:
2314*3d8817e4Smiod       /* FIXME: Ignore these for now.  The circumstances under which
2315*3d8817e4Smiod 	 they should be written out are not clear to me.  */
2316*3d8817e4Smiod       return TRUE;
2317*3d8817e4Smiod     }
2318*3d8817e4Smiod 
2319*3d8817e4Smiod   s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym");
2320*3d8817e4Smiod   BFD_ASSERT (s != NULL);
2321*3d8817e4Smiod   outsym = ((struct external_nlist *)
2322*3d8817e4Smiod 	    (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE));
2323*3d8817e4Smiod 
2324*3d8817e4Smiod   H_PUT_8 (output_bfd, type, outsym->e_type);
2325*3d8817e4Smiod   H_PUT_8 (output_bfd, 0, outsym->e_other);
2326*3d8817e4Smiod 
2327*3d8817e4Smiod   /* FIXME: The native linker doesn't use 0 for desc.  It seems to use
2328*3d8817e4Smiod      one less than the desc value in the shared library, although that
2329*3d8817e4Smiod      seems unlikely.  */
2330*3d8817e4Smiod   H_PUT_16 (output_bfd, 0, outsym->e_desc);
2331*3d8817e4Smiod 
2332*3d8817e4Smiod   PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx);
2333*3d8817e4Smiod   PUT_WORD (output_bfd, val, outsym->e_value);
2334*3d8817e4Smiod 
2335*3d8817e4Smiod   return TRUE;
2336*3d8817e4Smiod }
2337*3d8817e4Smiod 
2338*3d8817e4Smiod /* This is called for each reloc against an external symbol.  If this
2339*3d8817e4Smiod    is a reloc which are are going to copy as a dynamic reloc, then
2340*3d8817e4Smiod    copy it over, and tell the caller to not bother processing this
2341*3d8817e4Smiod    reloc.  */
2342*3d8817e4Smiod 
2343*3d8817e4Smiod static bfd_boolean
sunos_check_dynamic_reloc(struct bfd_link_info * info,bfd * input_bfd,asection * input_section,struct aout_link_hash_entry * harg,void * reloc,bfd_byte * contents ATTRIBUTE_UNUSED,bfd_boolean * skip,bfd_vma * relocationp)2344*3d8817e4Smiod sunos_check_dynamic_reloc (struct bfd_link_info *info,
2345*3d8817e4Smiod 			   bfd *input_bfd,
2346*3d8817e4Smiod 			   asection *input_section,
2347*3d8817e4Smiod 			   struct aout_link_hash_entry *harg,
2348*3d8817e4Smiod 			   void * reloc,
2349*3d8817e4Smiod 			   bfd_byte *contents ATTRIBUTE_UNUSED,
2350*3d8817e4Smiod 			   bfd_boolean *skip,
2351*3d8817e4Smiod 			   bfd_vma *relocationp)
2352*3d8817e4Smiod {
2353*3d8817e4Smiod   struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
2354*3d8817e4Smiod   bfd *dynobj;
2355*3d8817e4Smiod   bfd_boolean baserel;
2356*3d8817e4Smiod   bfd_boolean jmptbl;
2357*3d8817e4Smiod   bfd_boolean pcrel;
2358*3d8817e4Smiod   asection *s;
2359*3d8817e4Smiod   bfd_byte *p;
2360*3d8817e4Smiod   long indx;
2361*3d8817e4Smiod 
2362*3d8817e4Smiod   *skip = FALSE;
2363*3d8817e4Smiod 
2364*3d8817e4Smiod   dynobj = sunos_hash_table (info)->dynobj;
2365*3d8817e4Smiod 
2366*3d8817e4Smiod   if (h != NULL
2367*3d8817e4Smiod       && h->plt_offset != 0
2368*3d8817e4Smiod       && (info->shared
2369*3d8817e4Smiod 	  || (h->flags & SUNOS_DEF_REGULAR) == 0))
2370*3d8817e4Smiod     {
2371*3d8817e4Smiod       asection *splt;
2372*3d8817e4Smiod 
2373*3d8817e4Smiod       /* Redirect the relocation to the PLT entry.  */
2374*3d8817e4Smiod       splt = bfd_get_section_by_name (dynobj, ".plt");
2375*3d8817e4Smiod       *relocationp = (splt->output_section->vma
2376*3d8817e4Smiod 		      + splt->output_offset
2377*3d8817e4Smiod 		      + h->plt_offset);
2378*3d8817e4Smiod     }
2379*3d8817e4Smiod 
2380*3d8817e4Smiod   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
2381*3d8817e4Smiod     {
2382*3d8817e4Smiod       struct reloc_std_external *srel;
2383*3d8817e4Smiod 
2384*3d8817e4Smiod       srel = (struct reloc_std_external *) reloc;
2385*3d8817e4Smiod       if (bfd_header_big_endian (input_bfd))
2386*3d8817e4Smiod 	{
2387*3d8817e4Smiod 	  baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2388*3d8817e4Smiod 	  jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2389*3d8817e4Smiod 	  pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2390*3d8817e4Smiod 	}
2391*3d8817e4Smiod       else
2392*3d8817e4Smiod 	{
2393*3d8817e4Smiod 	  baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2394*3d8817e4Smiod 	  jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2395*3d8817e4Smiod 	  pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2396*3d8817e4Smiod 	}
2397*3d8817e4Smiod     }
2398*3d8817e4Smiod   else
2399*3d8817e4Smiod     {
2400*3d8817e4Smiod       struct reloc_ext_external *erel;
2401*3d8817e4Smiod       int r_type;
2402*3d8817e4Smiod 
2403*3d8817e4Smiod       erel = (struct reloc_ext_external *) reloc;
2404*3d8817e4Smiod       if (bfd_header_big_endian (input_bfd))
2405*3d8817e4Smiod 	r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2406*3d8817e4Smiod 		  >> RELOC_EXT_BITS_TYPE_SH_BIG);
2407*3d8817e4Smiod       else
2408*3d8817e4Smiod 	r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2409*3d8817e4Smiod 		  >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2410*3d8817e4Smiod       baserel = (r_type == RELOC_BASE10
2411*3d8817e4Smiod 		 || r_type == RELOC_BASE13
2412*3d8817e4Smiod 		 || r_type == RELOC_BASE22);
2413*3d8817e4Smiod       jmptbl = r_type == RELOC_JMP_TBL;
2414*3d8817e4Smiod       pcrel = (r_type == RELOC_DISP8
2415*3d8817e4Smiod 	       || r_type == RELOC_DISP16
2416*3d8817e4Smiod 	       || r_type == RELOC_DISP32
2417*3d8817e4Smiod 	       || r_type == RELOC_WDISP30
2418*3d8817e4Smiod 	       || r_type == RELOC_WDISP22);
2419*3d8817e4Smiod       /* We don't consider the PC10 and PC22 types to be PC relative,
2420*3d8817e4Smiod 	 because they are pcrel_offset.  */
2421*3d8817e4Smiod     }
2422*3d8817e4Smiod 
2423*3d8817e4Smiod   if (baserel)
2424*3d8817e4Smiod     {
2425*3d8817e4Smiod       bfd_vma *got_offsetp;
2426*3d8817e4Smiod       asection *sgot;
2427*3d8817e4Smiod 
2428*3d8817e4Smiod       if (h != NULL)
2429*3d8817e4Smiod 	got_offsetp = &h->got_offset;
2430*3d8817e4Smiod       else if (adata (input_bfd).local_got_offsets == NULL)
2431*3d8817e4Smiod 	got_offsetp = NULL;
2432*3d8817e4Smiod       else
2433*3d8817e4Smiod 	{
2434*3d8817e4Smiod 	  struct reloc_std_external *srel;
2435*3d8817e4Smiod 	  int r_index;
2436*3d8817e4Smiod 
2437*3d8817e4Smiod 	  srel = (struct reloc_std_external *) reloc;
2438*3d8817e4Smiod 	  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
2439*3d8817e4Smiod 	    {
2440*3d8817e4Smiod 	      if (bfd_header_big_endian (input_bfd))
2441*3d8817e4Smiod 		r_index = ((srel->r_index[0] << 16)
2442*3d8817e4Smiod 			   | (srel->r_index[1] << 8)
2443*3d8817e4Smiod 			   | srel->r_index[2]);
2444*3d8817e4Smiod 	      else
2445*3d8817e4Smiod 		r_index = ((srel->r_index[2] << 16)
2446*3d8817e4Smiod 			   | (srel->r_index[1] << 8)
2447*3d8817e4Smiod 			   | srel->r_index[0]);
2448*3d8817e4Smiod 	    }
2449*3d8817e4Smiod 	  else
2450*3d8817e4Smiod 	    {
2451*3d8817e4Smiod 	      struct reloc_ext_external *erel;
2452*3d8817e4Smiod 
2453*3d8817e4Smiod 	      erel = (struct reloc_ext_external *) reloc;
2454*3d8817e4Smiod 	      if (bfd_header_big_endian (input_bfd))
2455*3d8817e4Smiod 		r_index = ((erel->r_index[0] << 16)
2456*3d8817e4Smiod 			   | (erel->r_index[1] << 8)
2457*3d8817e4Smiod 			   | erel->r_index[2]);
2458*3d8817e4Smiod 	      else
2459*3d8817e4Smiod 		r_index = ((erel->r_index[2] << 16)
2460*3d8817e4Smiod 			   | (erel->r_index[1] << 8)
2461*3d8817e4Smiod 			   | erel->r_index[0]);
2462*3d8817e4Smiod 	    }
2463*3d8817e4Smiod 
2464*3d8817e4Smiod 	  got_offsetp = adata (input_bfd).local_got_offsets + r_index;
2465*3d8817e4Smiod 	}
2466*3d8817e4Smiod 
2467*3d8817e4Smiod       BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0);
2468*3d8817e4Smiod 
2469*3d8817e4Smiod       sgot = bfd_get_section_by_name (dynobj, ".got");
2470*3d8817e4Smiod 
2471*3d8817e4Smiod       /* We set the least significant bit to indicate whether we have
2472*3d8817e4Smiod 	 already initialized the GOT entry.  */
2473*3d8817e4Smiod       if ((*got_offsetp & 1) == 0)
2474*3d8817e4Smiod 	{
2475*3d8817e4Smiod 	  if (h == NULL
2476*3d8817e4Smiod 	      || (! info->shared
2477*3d8817e4Smiod 		  && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
2478*3d8817e4Smiod 		      || (h->flags & SUNOS_DEF_REGULAR) != 0)))
2479*3d8817e4Smiod 	    PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp);
2480*3d8817e4Smiod 	  else
2481*3d8817e4Smiod 	    PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp);
2482*3d8817e4Smiod 
2483*3d8817e4Smiod 	  if (info->shared
2484*3d8817e4Smiod 	      || (h != NULL
2485*3d8817e4Smiod 		  && (h->flags & SUNOS_DEF_DYNAMIC) != 0
2486*3d8817e4Smiod 		  && (h->flags & SUNOS_DEF_REGULAR) == 0))
2487*3d8817e4Smiod 	    {
2488*3d8817e4Smiod 	      /* We need to create a GLOB_DAT or 32 reloc to tell the
2489*3d8817e4Smiod 		 dynamic linker to fill in this entry in the table.  */
2490*3d8817e4Smiod 
2491*3d8817e4Smiod 	      s = bfd_get_section_by_name (dynobj, ".dynrel");
2492*3d8817e4Smiod 	      BFD_ASSERT (s != NULL);
2493*3d8817e4Smiod 	      BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
2494*3d8817e4Smiod 			  < s->size);
2495*3d8817e4Smiod 
2496*3d8817e4Smiod 	      p = (s->contents
2497*3d8817e4Smiod 		   + s->reloc_count * obj_reloc_entry_size (dynobj));
2498*3d8817e4Smiod 
2499*3d8817e4Smiod 	      if (h != NULL)
2500*3d8817e4Smiod 		indx = h->dynindx;
2501*3d8817e4Smiod 	      else
2502*3d8817e4Smiod 		indx = 0;
2503*3d8817e4Smiod 
2504*3d8817e4Smiod 	      if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
2505*3d8817e4Smiod 		{
2506*3d8817e4Smiod 		  struct reloc_std_external *srel;
2507*3d8817e4Smiod 
2508*3d8817e4Smiod 		  srel = (struct reloc_std_external *) p;
2509*3d8817e4Smiod 		  PUT_WORD (dynobj,
2510*3d8817e4Smiod 			    (*got_offsetp
2511*3d8817e4Smiod 			     + sgot->output_section->vma
2512*3d8817e4Smiod 			     + sgot->output_offset),
2513*3d8817e4Smiod 			    srel->r_address);
2514*3d8817e4Smiod 		  if (bfd_header_big_endian (dynobj))
2515*3d8817e4Smiod 		    {
2516*3d8817e4Smiod 		      srel->r_index[0] = (bfd_byte) (indx >> 16);
2517*3d8817e4Smiod 		      srel->r_index[1] = (bfd_byte) (indx >> 8);
2518*3d8817e4Smiod 		      srel->r_index[2] = (bfd_byte)indx;
2519*3d8817e4Smiod 		      if (h == NULL)
2520*3d8817e4Smiod 			srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG;
2521*3d8817e4Smiod 		      else
2522*3d8817e4Smiod 			srel->r_type[0] =
2523*3d8817e4Smiod 			  (RELOC_STD_BITS_EXTERN_BIG
2524*3d8817e4Smiod 			   | RELOC_STD_BITS_BASEREL_BIG
2525*3d8817e4Smiod 			   | RELOC_STD_BITS_RELATIVE_BIG
2526*3d8817e4Smiod 			   | (2 << RELOC_STD_BITS_LENGTH_SH_BIG));
2527*3d8817e4Smiod 		    }
2528*3d8817e4Smiod 		  else
2529*3d8817e4Smiod 		    {
2530*3d8817e4Smiod 		      srel->r_index[2] = (bfd_byte) (indx >> 16);
2531*3d8817e4Smiod 		      srel->r_index[1] = (bfd_byte) (indx >> 8);
2532*3d8817e4Smiod 		      srel->r_index[0] = (bfd_byte)indx;
2533*3d8817e4Smiod 		      if (h == NULL)
2534*3d8817e4Smiod 			srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE;
2535*3d8817e4Smiod 		      else
2536*3d8817e4Smiod 			srel->r_type[0] =
2537*3d8817e4Smiod 			  (RELOC_STD_BITS_EXTERN_LITTLE
2538*3d8817e4Smiod 			   | RELOC_STD_BITS_BASEREL_LITTLE
2539*3d8817e4Smiod 			   | RELOC_STD_BITS_RELATIVE_LITTLE
2540*3d8817e4Smiod 			   | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2541*3d8817e4Smiod 		    }
2542*3d8817e4Smiod 		}
2543*3d8817e4Smiod 	      else
2544*3d8817e4Smiod 		{
2545*3d8817e4Smiod 		  struct reloc_ext_external *erel;
2546*3d8817e4Smiod 
2547*3d8817e4Smiod 		  erel = (struct reloc_ext_external *) p;
2548*3d8817e4Smiod 		  PUT_WORD (dynobj,
2549*3d8817e4Smiod 			    (*got_offsetp
2550*3d8817e4Smiod 			     + sgot->output_section->vma
2551*3d8817e4Smiod 			     + sgot->output_offset),
2552*3d8817e4Smiod 			    erel->r_address);
2553*3d8817e4Smiod 		  if (bfd_header_big_endian (dynobj))
2554*3d8817e4Smiod 		    {
2555*3d8817e4Smiod 		      erel->r_index[0] = (bfd_byte) (indx >> 16);
2556*3d8817e4Smiod 		      erel->r_index[1] = (bfd_byte) (indx >> 8);
2557*3d8817e4Smiod 		      erel->r_index[2] = (bfd_byte)indx;
2558*3d8817e4Smiod 		      if (h == NULL)
2559*3d8817e4Smiod 			erel->r_type[0] =
2560*3d8817e4Smiod 			  RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG;
2561*3d8817e4Smiod 		      else
2562*3d8817e4Smiod 			erel->r_type[0] =
2563*3d8817e4Smiod 			  (RELOC_EXT_BITS_EXTERN_BIG
2564*3d8817e4Smiod 			   | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG));
2565*3d8817e4Smiod 		    }
2566*3d8817e4Smiod 		  else
2567*3d8817e4Smiod 		    {
2568*3d8817e4Smiod 		      erel->r_index[2] = (bfd_byte) (indx >> 16);
2569*3d8817e4Smiod 		      erel->r_index[1] = (bfd_byte) (indx >> 8);
2570*3d8817e4Smiod 		      erel->r_index[0] = (bfd_byte)indx;
2571*3d8817e4Smiod 		      if (h == NULL)
2572*3d8817e4Smiod 			erel->r_type[0] =
2573*3d8817e4Smiod 			  RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE;
2574*3d8817e4Smiod 		      else
2575*3d8817e4Smiod 			erel->r_type[0] =
2576*3d8817e4Smiod 			  (RELOC_EXT_BITS_EXTERN_LITTLE
2577*3d8817e4Smiod 			   | (RELOC_GLOB_DAT
2578*3d8817e4Smiod 			      << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2579*3d8817e4Smiod 		    }
2580*3d8817e4Smiod 		  PUT_WORD (dynobj, 0, erel->r_addend);
2581*3d8817e4Smiod 		}
2582*3d8817e4Smiod 
2583*3d8817e4Smiod 	      ++s->reloc_count;
2584*3d8817e4Smiod 	    }
2585*3d8817e4Smiod 
2586*3d8817e4Smiod 	  *got_offsetp |= 1;
2587*3d8817e4Smiod 	}
2588*3d8817e4Smiod 
2589*3d8817e4Smiod       *relocationp = (sgot->vma
2590*3d8817e4Smiod 		      + (*got_offsetp &~ (bfd_vma) 1)
2591*3d8817e4Smiod 		      - sunos_hash_table (info)->got_base);
2592*3d8817e4Smiod 
2593*3d8817e4Smiod       /* There is nothing else to do for a base relative reloc.  */
2594*3d8817e4Smiod       return TRUE;
2595*3d8817e4Smiod     }
2596*3d8817e4Smiod 
2597*3d8817e4Smiod   if (! sunos_hash_table (info)->dynamic_sections_needed)
2598*3d8817e4Smiod     return TRUE;
2599*3d8817e4Smiod   if (! info->shared)
2600*3d8817e4Smiod     {
2601*3d8817e4Smiod       if (h == NULL
2602*3d8817e4Smiod 	  || h->dynindx == -1
2603*3d8817e4Smiod 	  || h->root.root.type != bfd_link_hash_undefined
2604*3d8817e4Smiod 	  || (h->flags & SUNOS_DEF_REGULAR) != 0
2605*3d8817e4Smiod 	  || (h->flags & SUNOS_DEF_DYNAMIC) == 0
2606*3d8817e4Smiod 	  || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
2607*3d8817e4Smiod 	return TRUE;
2608*3d8817e4Smiod     }
2609*3d8817e4Smiod   else
2610*3d8817e4Smiod     {
2611*3d8817e4Smiod       if (h != NULL
2612*3d8817e4Smiod 	  && (h->dynindx == -1
2613*3d8817e4Smiod 	      || jmptbl
2614*3d8817e4Smiod 	      || strcmp (h->root.root.root.string,
2615*3d8817e4Smiod 			 "__GLOBAL_OFFSET_TABLE_") == 0))
2616*3d8817e4Smiod 	return TRUE;
2617*3d8817e4Smiod     }
2618*3d8817e4Smiod 
2619*3d8817e4Smiod   /* It looks like this is a reloc we are supposed to copy.  */
2620*3d8817e4Smiod 
2621*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".dynrel");
2622*3d8817e4Smiod   BFD_ASSERT (s != NULL);
2623*3d8817e4Smiod   BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->size);
2624*3d8817e4Smiod 
2625*3d8817e4Smiod   p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj);
2626*3d8817e4Smiod 
2627*3d8817e4Smiod   /* Copy the reloc over.  */
2628*3d8817e4Smiod   memcpy (p, reloc, obj_reloc_entry_size (dynobj));
2629*3d8817e4Smiod 
2630*3d8817e4Smiod   if (h != NULL)
2631*3d8817e4Smiod     indx = h->dynindx;
2632*3d8817e4Smiod   else
2633*3d8817e4Smiod     indx = 0;
2634*3d8817e4Smiod 
2635*3d8817e4Smiod   /* Adjust the address and symbol index.  */
2636*3d8817e4Smiod   if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
2637*3d8817e4Smiod     {
2638*3d8817e4Smiod       struct reloc_std_external *srel;
2639*3d8817e4Smiod 
2640*3d8817e4Smiod       srel = (struct reloc_std_external *) p;
2641*3d8817e4Smiod       PUT_WORD (dynobj,
2642*3d8817e4Smiod 		(GET_WORD (dynobj, srel->r_address)
2643*3d8817e4Smiod 		 + input_section->output_section->vma
2644*3d8817e4Smiod 		 + input_section->output_offset),
2645*3d8817e4Smiod 		srel->r_address);
2646*3d8817e4Smiod       if (bfd_header_big_endian (dynobj))
2647*3d8817e4Smiod 	{
2648*3d8817e4Smiod 	  srel->r_index[0] = (bfd_byte) (indx >> 16);
2649*3d8817e4Smiod 	  srel->r_index[1] = (bfd_byte) (indx >> 8);
2650*3d8817e4Smiod 	  srel->r_index[2] = (bfd_byte)indx;
2651*3d8817e4Smiod 	}
2652*3d8817e4Smiod       else
2653*3d8817e4Smiod 	{
2654*3d8817e4Smiod 	  srel->r_index[2] = (bfd_byte) (indx >> 16);
2655*3d8817e4Smiod 	  srel->r_index[1] = (bfd_byte) (indx >> 8);
2656*3d8817e4Smiod 	  srel->r_index[0] = (bfd_byte)indx;
2657*3d8817e4Smiod 	}
2658*3d8817e4Smiod       /* FIXME: We may have to change the addend for a PC relative
2659*3d8817e4Smiod 	 reloc.  */
2660*3d8817e4Smiod     }
2661*3d8817e4Smiod   else
2662*3d8817e4Smiod     {
2663*3d8817e4Smiod       struct reloc_ext_external *erel;
2664*3d8817e4Smiod 
2665*3d8817e4Smiod       erel = (struct reloc_ext_external *) p;
2666*3d8817e4Smiod       PUT_WORD (dynobj,
2667*3d8817e4Smiod 		(GET_WORD (dynobj, erel->r_address)
2668*3d8817e4Smiod 		 + input_section->output_section->vma
2669*3d8817e4Smiod 		 + input_section->output_offset),
2670*3d8817e4Smiod 		erel->r_address);
2671*3d8817e4Smiod       if (bfd_header_big_endian (dynobj))
2672*3d8817e4Smiod 	{
2673*3d8817e4Smiod 	  erel->r_index[0] = (bfd_byte) (indx >> 16);
2674*3d8817e4Smiod 	  erel->r_index[1] = (bfd_byte) (indx >> 8);
2675*3d8817e4Smiod 	  erel->r_index[2] = (bfd_byte)indx;
2676*3d8817e4Smiod 	}
2677*3d8817e4Smiod       else
2678*3d8817e4Smiod 	{
2679*3d8817e4Smiod 	  erel->r_index[2] = (bfd_byte) (indx >> 16);
2680*3d8817e4Smiod 	  erel->r_index[1] = (bfd_byte) (indx >> 8);
2681*3d8817e4Smiod 	  erel->r_index[0] = (bfd_byte)indx;
2682*3d8817e4Smiod 	}
2683*3d8817e4Smiod       if (pcrel && h != NULL)
2684*3d8817e4Smiod 	{
2685*3d8817e4Smiod 	  /* Adjust the addend for the change in address.  */
2686*3d8817e4Smiod 	  PUT_WORD (dynobj,
2687*3d8817e4Smiod 		    (GET_WORD (dynobj, erel->r_addend)
2688*3d8817e4Smiod 		     - (input_section->output_section->vma
2689*3d8817e4Smiod 			+ input_section->output_offset
2690*3d8817e4Smiod 			- input_section->vma)),
2691*3d8817e4Smiod 		    erel->r_addend);
2692*3d8817e4Smiod 	}
2693*3d8817e4Smiod     }
2694*3d8817e4Smiod 
2695*3d8817e4Smiod   ++s->reloc_count;
2696*3d8817e4Smiod 
2697*3d8817e4Smiod   if (h != NULL)
2698*3d8817e4Smiod     *skip = TRUE;
2699*3d8817e4Smiod 
2700*3d8817e4Smiod   return TRUE;
2701*3d8817e4Smiod }
2702*3d8817e4Smiod 
2703*3d8817e4Smiod /* Finish up the dynamic linking information.  */
2704*3d8817e4Smiod 
2705*3d8817e4Smiod static bfd_boolean
sunos_finish_dynamic_link(bfd * abfd,struct bfd_link_info * info)2706*3d8817e4Smiod sunos_finish_dynamic_link (bfd *abfd, struct bfd_link_info *info)
2707*3d8817e4Smiod {
2708*3d8817e4Smiod   bfd *dynobj;
2709*3d8817e4Smiod   asection *o;
2710*3d8817e4Smiod   asection *s;
2711*3d8817e4Smiod   asection *sdyn;
2712*3d8817e4Smiod 
2713*3d8817e4Smiod   if (! sunos_hash_table (info)->dynamic_sections_needed
2714*3d8817e4Smiod       && ! sunos_hash_table (info)->got_needed)
2715*3d8817e4Smiod     return TRUE;
2716*3d8817e4Smiod 
2717*3d8817e4Smiod   dynobj = sunos_hash_table (info)->dynobj;
2718*3d8817e4Smiod 
2719*3d8817e4Smiod   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2720*3d8817e4Smiod   BFD_ASSERT (sdyn != NULL);
2721*3d8817e4Smiod 
2722*3d8817e4Smiod   /* Finish up the .need section.  The linker emulation code filled it
2723*3d8817e4Smiod      in, but with offsets from the start of the section instead of
2724*3d8817e4Smiod      real addresses.  Now that we know the section location, we can
2725*3d8817e4Smiod      fill in the final values.  */
2726*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".need");
2727*3d8817e4Smiod   if (s != NULL && s->size != 0)
2728*3d8817e4Smiod     {
2729*3d8817e4Smiod       file_ptr filepos;
2730*3d8817e4Smiod       bfd_byte *p;
2731*3d8817e4Smiod 
2732*3d8817e4Smiod       filepos = s->output_section->filepos + s->output_offset;
2733*3d8817e4Smiod       p = s->contents;
2734*3d8817e4Smiod       while (1)
2735*3d8817e4Smiod 	{
2736*3d8817e4Smiod 	  bfd_vma val;
2737*3d8817e4Smiod 
2738*3d8817e4Smiod 	  PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p);
2739*3d8817e4Smiod 	  val = GET_WORD (dynobj, p + 12);
2740*3d8817e4Smiod 	  if (val == 0)
2741*3d8817e4Smiod 	    break;
2742*3d8817e4Smiod 	  PUT_WORD (dynobj, val + filepos, p + 12);
2743*3d8817e4Smiod 	  p += 16;
2744*3d8817e4Smiod 	}
2745*3d8817e4Smiod     }
2746*3d8817e4Smiod 
2747*3d8817e4Smiod   /* The first entry in the .got section is the address of the
2748*3d8817e4Smiod      dynamic information, unless this is a shared library.  */
2749*3d8817e4Smiod   s = bfd_get_section_by_name (dynobj, ".got");
2750*3d8817e4Smiod   BFD_ASSERT (s != NULL);
2751*3d8817e4Smiod   if (info->shared || sdyn->size == 0)
2752*3d8817e4Smiod     PUT_WORD (dynobj, 0, s->contents);
2753*3d8817e4Smiod   else
2754*3d8817e4Smiod     PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset,
2755*3d8817e4Smiod 	      s->contents);
2756*3d8817e4Smiod 
2757*3d8817e4Smiod   for (o = dynobj->sections; o != NULL; o = o->next)
2758*3d8817e4Smiod     {
2759*3d8817e4Smiod       if ((o->flags & SEC_HAS_CONTENTS) != 0
2760*3d8817e4Smiod 	  && o->contents != NULL)
2761*3d8817e4Smiod 	{
2762*3d8817e4Smiod 	  BFD_ASSERT (o->output_section != NULL
2763*3d8817e4Smiod 		      && o->output_section->owner == abfd);
2764*3d8817e4Smiod 	  if (! bfd_set_section_contents (abfd, o->output_section,
2765*3d8817e4Smiod 					  o->contents,
2766*3d8817e4Smiod 					  (file_ptr) o->output_offset,
2767*3d8817e4Smiod 					  o->size))
2768*3d8817e4Smiod 	    return FALSE;
2769*3d8817e4Smiod 	}
2770*3d8817e4Smiod     }
2771*3d8817e4Smiod 
2772*3d8817e4Smiod   if (sdyn->size > 0)
2773*3d8817e4Smiod     {
2774*3d8817e4Smiod       struct external_sun4_dynamic esd;
2775*3d8817e4Smiod       struct external_sun4_dynamic_link esdl;
2776*3d8817e4Smiod       file_ptr pos;
2777*3d8817e4Smiod 
2778*3d8817e4Smiod       /* Finish up the dynamic link information.  */
2779*3d8817e4Smiod       PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version);
2780*3d8817e4Smiod       PUT_WORD (dynobj,
2781*3d8817e4Smiod 		sdyn->output_section->vma + sdyn->output_offset + sizeof esd,
2782*3d8817e4Smiod 		esd.ldd);
2783*3d8817e4Smiod       PUT_WORD (dynobj,
2784*3d8817e4Smiod 		(sdyn->output_section->vma
2785*3d8817e4Smiod 		 + sdyn->output_offset
2786*3d8817e4Smiod 		 + sizeof esd
2787*3d8817e4Smiod 		 + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE),
2788*3d8817e4Smiod 		esd.ld);
2789*3d8817e4Smiod 
2790*3d8817e4Smiod       if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd,
2791*3d8817e4Smiod 				      (file_ptr) sdyn->output_offset,
2792*3d8817e4Smiod 				      (bfd_size_type) sizeof esd))
2793*3d8817e4Smiod 	return FALSE;
2794*3d8817e4Smiod 
2795*3d8817e4Smiod       PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded);
2796*3d8817e4Smiod 
2797*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".need");
2798*3d8817e4Smiod       if (s == NULL || s->size == 0)
2799*3d8817e4Smiod 	PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need);
2800*3d8817e4Smiod       else
2801*3d8817e4Smiod 	PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2802*3d8817e4Smiod 		  esdl.ld_need);
2803*3d8817e4Smiod 
2804*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".rules");
2805*3d8817e4Smiod       if (s == NULL || s->size == 0)
2806*3d8817e4Smiod 	PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules);
2807*3d8817e4Smiod       else
2808*3d8817e4Smiod 	PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2809*3d8817e4Smiod 		  esdl.ld_rules);
2810*3d8817e4Smiod 
2811*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".got");
2812*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2813*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
2814*3d8817e4Smiod 		esdl.ld_got);
2815*3d8817e4Smiod 
2816*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".plt");
2817*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2818*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
2819*3d8817e4Smiod 		esdl.ld_plt);
2820*3d8817e4Smiod       PUT_WORD (dynobj, s->size, esdl.ld_plt_sz);
2821*3d8817e4Smiod 
2822*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynrel");
2823*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2824*3d8817e4Smiod       BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
2825*3d8817e4Smiod 		  == s->size);
2826*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2827*3d8817e4Smiod 		esdl.ld_rel);
2828*3d8817e4Smiod 
2829*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".hash");
2830*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2831*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2832*3d8817e4Smiod 		esdl.ld_hash);
2833*3d8817e4Smiod 
2834*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynsym");
2835*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2836*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2837*3d8817e4Smiod 		esdl.ld_stab);
2838*3d8817e4Smiod 
2839*3d8817e4Smiod       PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash);
2840*3d8817e4Smiod 
2841*3d8817e4Smiod       PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount,
2842*3d8817e4Smiod 		esdl.ld_buckets);
2843*3d8817e4Smiod 
2844*3d8817e4Smiod       s = bfd_get_section_by_name (dynobj, ".dynstr");
2845*3d8817e4Smiod       BFD_ASSERT (s != NULL);
2846*3d8817e4Smiod       PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
2847*3d8817e4Smiod 		esdl.ld_symbols);
2848*3d8817e4Smiod       PUT_WORD (dynobj, s->size, esdl.ld_symb_size);
2849*3d8817e4Smiod 
2850*3d8817e4Smiod       /* The size of the text area is the size of the .text section
2851*3d8817e4Smiod 	 rounded up to a page boundary.  FIXME: Should the page size be
2852*3d8817e4Smiod 	 conditional on something?  */
2853*3d8817e4Smiod       PUT_WORD (dynobj,
2854*3d8817e4Smiod 		BFD_ALIGN (obj_textsec (abfd)->size, 0x2000),
2855*3d8817e4Smiod 		esdl.ld_text);
2856*3d8817e4Smiod 
2857*3d8817e4Smiod       pos = sdyn->output_offset;
2858*3d8817e4Smiod       pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE;
2859*3d8817e4Smiod       if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl,
2860*3d8817e4Smiod 				      pos, (bfd_size_type) sizeof esdl))
2861*3d8817e4Smiod 	return FALSE;
2862*3d8817e4Smiod 
2863*3d8817e4Smiod       abfd->flags |= DYNAMIC;
2864*3d8817e4Smiod     }
2865*3d8817e4Smiod 
2866*3d8817e4Smiod   return TRUE;
2867*3d8817e4Smiod }
2868