xref: /openbsd-src/gnu/usr.bin/binutils/bfd/sparclinux.c (revision cf2f2c5620d6d9a4fd01930983c4b9a1f76d7aa3)
1fddef416Sniklas /* BFD back-end for linux flavored sparc a.out binaries.
2d2201f2fSdrahn    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003
3f7cc78ecSespie    Free Software Foundation, Inc.
4fddef416Sniklas 
5fddef416Sniklas This file is part of BFD, the Binary File Descriptor library.
6fddef416Sniklas 
7fddef416Sniklas This program is free software; you can redistribute it and/or modify
8fddef416Sniklas it under the terms of the GNU General Public License as published by
9fddef416Sniklas the Free Software Foundation; either version 2 of the License, or
10fddef416Sniklas (at your option) any later version.
11fddef416Sniklas 
12fddef416Sniklas This program is distributed in the hope that it will be useful,
13fddef416Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
14fddef416Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15fddef416Sniklas GNU General Public License for more details.
16fddef416Sniklas 
17fddef416Sniklas You should have received a copy of the GNU General Public License
18fddef416Sniklas along with this program; if not, write to the Free Software
19fddef416Sniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20fddef416Sniklas USA.  */
21fddef416Sniklas 
22fddef416Sniklas #define TARGET_PAGE_SIZE	4096
23fddef416Sniklas #define ZMAGIC_DISK_BLOCK_SIZE	1024
24fddef416Sniklas #define SEGMENT_SIZE		TARGET_PAGE_SIZE
25fddef416Sniklas #define TEXT_START_ADDR		0x0
26fddef416Sniklas #define N_SHARED_LIB(x)		0
27fddef416Sniklas 
28fddef416Sniklas #define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_UNKNOWN)
29fddef416Sniklas 
30fddef416Sniklas #include "bfd.h"
31fddef416Sniklas #include "sysdep.h"
32fddef416Sniklas #include "libbfd.h"
33fddef416Sniklas #include "aout/aout64.h"
34fddef416Sniklas #include "aout/stab_gnu.h"
35fddef416Sniklas #include "aout/ar.h"
36fddef416Sniklas #include "libaout.h"           /* BFD a.out internal data structures */
37fddef416Sniklas 
38fddef416Sniklas #define DEFAULT_ARCH bfd_arch_sparc
39d2201f2fSdrahn /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
40d2201f2fSdrahn    remove whitespace added here, and thus will fail to concatenate
41d2201f2fSdrahn    the tokens.  */
42d2201f2fSdrahn #define MY(OP) CONCAT2 (sparclinux_,OP)
43fddef416Sniklas #define TARGETNAME "a.out-sparc-linux"
44fddef416Sniklas 
45fddef416Sniklas extern const bfd_target MY(vec);
46fddef416Sniklas 
47fddef416Sniklas /* We always generate QMAGIC files in preference to ZMAGIC files.  It
48fddef416Sniklas    would be possible to make this a linker option, if that ever
49fddef416Sniklas    becomes important.  */
50fddef416Sniklas 
51fddef416Sniklas static void MY_final_link_callback
52fddef416Sniklas   PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
53fddef416Sniklas 
54d2201f2fSdrahn static bfd_boolean sparclinux_bfd_final_link
55fddef416Sniklas   PARAMS ((bfd *abfd, struct bfd_link_info *info));
56fddef416Sniklas 
57d2201f2fSdrahn static bfd_boolean
sparclinux_bfd_final_link(abfd,info)58fddef416Sniklas sparclinux_bfd_final_link (abfd, info)
59fddef416Sniklas      bfd *abfd;
60fddef416Sniklas      struct bfd_link_info *info;
61fddef416Sniklas {
62fddef416Sniklas   obj_aout_subformat (abfd) = q_magic_format;
63fddef416Sniklas   return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
64fddef416Sniklas }
65fddef416Sniklas 
66fddef416Sniklas #define MY_bfd_final_link sparclinux_bfd_final_link
67fddef416Sniklas 
68fddef416Sniklas /* Set the machine type correctly.  */
69fddef416Sniklas 
70d2201f2fSdrahn static bfd_boolean sparclinux_write_object_contents PARAMS ((bfd *abfd));
71fddef416Sniklas 
72d2201f2fSdrahn static bfd_boolean
sparclinux_write_object_contents(abfd)73fddef416Sniklas sparclinux_write_object_contents (abfd)
74fddef416Sniklas      bfd *abfd;
75fddef416Sniklas {
76fddef416Sniklas   struct external_exec exec_bytes;
77fddef416Sniklas   struct internal_exec *execp = exec_hdr (abfd);
78fddef416Sniklas 
79fddef416Sniklas   N_SET_MACHTYPE (*execp, M_SPARC);
80fddef416Sniklas 
81fddef416Sniklas   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
82fddef416Sniklas 
83fddef416Sniklas   WRITE_HEADERS(abfd, execp);
84fddef416Sniklas 
85d2201f2fSdrahn   return TRUE;
86fddef416Sniklas }
87fddef416Sniklas 
88fddef416Sniklas #define MY_write_object_contents sparclinux_write_object_contents
89fddef416Sniklas /* Code to link against Linux a.out shared libraries.  */
90fddef416Sniklas 
91fddef416Sniklas /* See if a symbol name is a reference to the global offset table.  */
92fddef416Sniklas 
93fddef416Sniklas #ifndef GOT_REF_PREFIX
94fddef416Sniklas #define GOT_REF_PREFIX  "__GOT_"
95fddef416Sniklas #endif
96fddef416Sniklas 
97fddef416Sniklas #define IS_GOT_SYM(name) \
98fddef416Sniklas   (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
99fddef416Sniklas 
100fddef416Sniklas /* See if a symbol name is a reference to the procedure linkage table.  */
101fddef416Sniklas 
102fddef416Sniklas #ifndef PLT_REF_PREFIX
103fddef416Sniklas #define PLT_REF_PREFIX  "__PLT_"
104fddef416Sniklas #endif
105fddef416Sniklas 
106fddef416Sniklas #define IS_PLT_SYM(name) \
107fddef416Sniklas   (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
108fddef416Sniklas 
109fddef416Sniklas /* This string is used to generate specialized error messages.  */
110fddef416Sniklas 
111fddef416Sniklas #ifndef NEEDS_SHRLIB
112fddef416Sniklas #define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
113fddef416Sniklas #endif
114fddef416Sniklas 
115fddef416Sniklas /* This special symbol is a set vector that contains a list of
116*cf2f2c56Smiod    pointers to fixup tables.  It will be present in any dynamically
117fddef416Sniklas    linked file.  The linker generated fixup table should also be added
118fddef416Sniklas    to the list, and it should always appear in the second slot (the
119fddef416Sniklas    first one is a dummy with a magic number that is defined in
120fddef416Sniklas    crt0.o).  */
121fddef416Sniklas 
122fddef416Sniklas #ifndef SHARABLE_CONFLICTS
123fddef416Sniklas #define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
124fddef416Sniklas #endif
125fddef416Sniklas 
126fddef416Sniklas /* We keep a list of fixups.  The terminology is a bit strange, but
127fddef416Sniklas    each fixup contains two 32 bit numbers.  A regular fixup contains
128fddef416Sniklas    an address and a pointer, and at runtime we should store the
129fddef416Sniklas    address at the location pointed to by the pointer.  A builtin fixup
130fddef416Sniklas    contains two pointers, and we should read the address using one
131fddef416Sniklas    pointer and store it at the location pointed to by the other
132fddef416Sniklas    pointer.  Builtin fixups come into play when we have duplicate
133fddef416Sniklas    __GOT__ symbols for the same variable.  The builtin fixup will copy
134fddef416Sniklas    the GOT pointer from one over into the other.  */
135fddef416Sniklas 
136fddef416Sniklas struct fixup
137fddef416Sniklas {
138fddef416Sniklas   struct fixup *next;
139fddef416Sniklas   struct linux_link_hash_entry *h;
140fddef416Sniklas   bfd_vma value;
141fddef416Sniklas 
142fddef416Sniklas   /* Nonzero if this is a jump instruction that needs to be fixed,
143fddef416Sniklas      zero if this is just a pointer */
144fddef416Sniklas   char jump;
145fddef416Sniklas 
146fddef416Sniklas   char builtin;
147fddef416Sniklas };
148fddef416Sniklas 
149fddef416Sniklas /* We don't need a special hash table entry structure, but we do need
150fddef416Sniklas    to keep some information between linker passes, so we use a special
151fddef416Sniklas    hash table.  */
152fddef416Sniklas 
153fddef416Sniklas struct linux_link_hash_entry
154fddef416Sniklas {
155fddef416Sniklas   struct aout_link_hash_entry root;
156fddef416Sniklas };
157fddef416Sniklas 
158fddef416Sniklas struct linux_link_hash_table
159fddef416Sniklas {
160fddef416Sniklas   struct aout_link_hash_table root;
161fddef416Sniklas 
162fddef416Sniklas   /* First dynamic object found in link.  */
163fddef416Sniklas   bfd *dynobj;
164fddef416Sniklas 
165fddef416Sniklas   /* Number of fixups.  */
166fddef416Sniklas   size_t fixup_count;
167fddef416Sniklas 
168fddef416Sniklas   /* Number of builtin fixups.  */
169fddef416Sniklas   size_t local_builtins;
170fddef416Sniklas 
171fddef416Sniklas   /* List of fixups.  */
172fddef416Sniklas   struct fixup *fixup_list;
173fddef416Sniklas };
174fddef416Sniklas 
175fddef416Sniklas static struct bfd_hash_entry *linux_link_hash_newfunc
176fddef416Sniklas   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
177fddef416Sniklas static struct bfd_link_hash_table *linux_link_hash_table_create
178fddef416Sniklas   PARAMS ((bfd *));
179fddef416Sniklas static struct fixup *new_fixup
180fddef416Sniklas   PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
181fddef416Sniklas 	  bfd_vma, int));
182d2201f2fSdrahn static bfd_boolean linux_link_create_dynamic_sections
183fddef416Sniklas   PARAMS ((bfd *, struct bfd_link_info *));
184d2201f2fSdrahn static bfd_boolean linux_add_one_symbol
185fddef416Sniklas   PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
186d2201f2fSdrahn 	  bfd_vma, const char *, bfd_boolean, bfd_boolean,
187fddef416Sniklas 	  struct bfd_link_hash_entry **));
188d2201f2fSdrahn static bfd_boolean linux_tally_symbols
189fddef416Sniklas   PARAMS ((struct linux_link_hash_entry *, PTR));
190d2201f2fSdrahn static bfd_boolean linux_finish_dynamic_link
191fddef416Sniklas   PARAMS ((bfd *, struct bfd_link_info *));
192fddef416Sniklas 
193fddef416Sniklas /* Routine to create an entry in an Linux link hash table.  */
194fddef416Sniklas 
195fddef416Sniklas static struct bfd_hash_entry *
linux_link_hash_newfunc(entry,table,string)196fddef416Sniklas linux_link_hash_newfunc (entry, table, string)
197fddef416Sniklas      struct bfd_hash_entry *entry;
198fddef416Sniklas      struct bfd_hash_table *table;
199fddef416Sniklas      const char *string;
200fddef416Sniklas {
201fddef416Sniklas   struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
202fddef416Sniklas 
203fddef416Sniklas   /* Allocate the structure if it has not already been allocated by a
204fddef416Sniklas      subclass.  */
205fddef416Sniklas   if (ret == (struct linux_link_hash_entry *) NULL)
206fddef416Sniklas     ret = ((struct linux_link_hash_entry *)
207fddef416Sniklas 	   bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
208fddef416Sniklas   if (ret == NULL)
209fddef416Sniklas     return (struct bfd_hash_entry *) ret;
210fddef416Sniklas 
211fddef416Sniklas   /* Call the allocation method of the superclass.  */
212fddef416Sniklas   ret = ((struct linux_link_hash_entry *)
213fddef416Sniklas 	 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
214fddef416Sniklas 				       table, string));
215fddef416Sniklas   if (ret != NULL)
216fddef416Sniklas     {
217fddef416Sniklas       /* Set local fields; there aren't any.  */
218fddef416Sniklas     }
219fddef416Sniklas 
220fddef416Sniklas   return (struct bfd_hash_entry *) ret;
221fddef416Sniklas }
222fddef416Sniklas 
223fddef416Sniklas /* Create a Linux link hash table.  */
224fddef416Sniklas 
225fddef416Sniklas static struct bfd_link_hash_table *
linux_link_hash_table_create(abfd)226fddef416Sniklas linux_link_hash_table_create (abfd)
227fddef416Sniklas      bfd *abfd;
228fddef416Sniklas {
229fddef416Sniklas   struct linux_link_hash_table *ret;
230d2201f2fSdrahn   bfd_size_type amt = sizeof (struct linux_link_hash_table);
231fddef416Sniklas 
232d2201f2fSdrahn   ret = (struct linux_link_hash_table *) bfd_malloc (amt);
233fddef416Sniklas   if (ret == (struct linux_link_hash_table *) NULL)
234fddef416Sniklas     return (struct bfd_link_hash_table *) NULL;
235fddef416Sniklas   if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
236fddef416Sniklas 					 linux_link_hash_newfunc))
237fddef416Sniklas     {
238fddef416Sniklas       free (ret);
239fddef416Sniklas       return (struct bfd_link_hash_table *) NULL;
240fddef416Sniklas     }
241fddef416Sniklas 
242fddef416Sniklas   ret->dynobj = NULL;
243fddef416Sniklas   ret->fixup_count = 0;
244fddef416Sniklas   ret->local_builtins = 0;
245fddef416Sniklas   ret->fixup_list = NULL;
246fddef416Sniklas 
247fddef416Sniklas   return &ret->root.root;
248fddef416Sniklas }
249fddef416Sniklas 
250fddef416Sniklas /* Look up an entry in a Linux link hash table.  */
251fddef416Sniklas 
252fddef416Sniklas #define linux_link_hash_lookup(table, string, create, copy, follow) \
253fddef416Sniklas   ((struct linux_link_hash_entry *) \
254fddef416Sniklas    aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
255fddef416Sniklas 			  (follow)))
256fddef416Sniklas 
257fddef416Sniklas /* Traverse a Linux link hash table.  */
258fddef416Sniklas 
259fddef416Sniklas #define linux_link_hash_traverse(table, func, info)		       \
260fddef416Sniklas   (aout_link_hash_traverse					       \
261fddef416Sniklas    (&(table)->root,						       \
262d2201f2fSdrahn     (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
263fddef416Sniklas     (info)))
264fddef416Sniklas 
265fddef416Sniklas /* Get the Linux link hash table from the info structure.  This is
266fddef416Sniklas    just a cast.  */
267fddef416Sniklas 
268fddef416Sniklas #define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
269fddef416Sniklas 
270fddef416Sniklas /* Store the information for a new fixup.  */
271fddef416Sniklas 
272fddef416Sniklas static struct fixup *
new_fixup(info,h,value,builtin)273fddef416Sniklas new_fixup (info, h, value, builtin)
274fddef416Sniklas      struct bfd_link_info *info;
275fddef416Sniklas      struct linux_link_hash_entry *h;
276fddef416Sniklas      bfd_vma value;
277fddef416Sniklas      int builtin;
278fddef416Sniklas {
279fddef416Sniklas   struct fixup *f;
280fddef416Sniklas 
281fddef416Sniklas   f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
282fddef416Sniklas 					  sizeof (struct fixup));
283fddef416Sniklas   if (f == NULL)
284fddef416Sniklas     return f;
285fddef416Sniklas   f->next = linux_hash_table (info)->fixup_list;
286fddef416Sniklas   linux_hash_table (info)->fixup_list = f;
287fddef416Sniklas   f->h = h;
288fddef416Sniklas   f->value = value;
289fddef416Sniklas   f->builtin = builtin;
290fddef416Sniklas   f->jump = 0;
291fddef416Sniklas   ++linux_hash_table (info)->fixup_count;
292fddef416Sniklas   return f;
293fddef416Sniklas }
294fddef416Sniklas 
295fddef416Sniklas /* We come here once we realize that we are going to link to a shared
296fddef416Sniklas    library.  We need to create a special section that contains the
297fddef416Sniklas    fixup table, and we ultimately need to add a pointer to this into
298fddef416Sniklas    the set vector for SHARABLE_CONFLICTS.  At this point we do not
299fddef416Sniklas    know the size of the section, but that's OK - we just need to
300fddef416Sniklas    create it for now.  */
301fddef416Sniklas 
302d2201f2fSdrahn static bfd_boolean
linux_link_create_dynamic_sections(abfd,info)303fddef416Sniklas linux_link_create_dynamic_sections (abfd, info)
304fddef416Sniklas      bfd *abfd;
305f7cc78ecSespie      struct bfd_link_info *info ATTRIBUTE_UNUSED;
306fddef416Sniklas {
307fddef416Sniklas   flagword flags;
308fddef416Sniklas   register asection *s;
309fddef416Sniklas 
310fddef416Sniklas   /* Note that we set the SEC_IN_MEMORY flag.  */
311fddef416Sniklas   flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
312fddef416Sniklas 
313fddef416Sniklas   /* We choose to use the name ".linux-dynamic" for the fixup table.
314fddef416Sniklas      Why not?  */
315fddef416Sniklas   s = bfd_make_section (abfd, ".linux-dynamic");
316fddef416Sniklas   if (s == NULL
317fddef416Sniklas       || ! bfd_set_section_flags (abfd, s, flags)
318fddef416Sniklas       || ! bfd_set_section_alignment (abfd, s, 2))
319d2201f2fSdrahn     return FALSE;
320fddef416Sniklas   s->_raw_size = 0;
321fddef416Sniklas   s->contents = 0;
322fddef416Sniklas 
323d2201f2fSdrahn   return TRUE;
324fddef416Sniklas }
325fddef416Sniklas 
326fddef416Sniklas /* Function to add a single symbol to the linker hash table.  This is
327fddef416Sniklas    a wrapper around _bfd_generic_link_add_one_symbol which handles the
328fddef416Sniklas    tweaking needed for dynamic linking support.  */
329fddef416Sniklas 
330d2201f2fSdrahn static bfd_boolean
linux_add_one_symbol(info,abfd,name,flags,section,value,string,copy,collect,hashp)331fddef416Sniklas linux_add_one_symbol (info, abfd, name, flags, section, value, string,
332fddef416Sniklas 		      copy, collect, hashp)
333fddef416Sniklas      struct bfd_link_info *info;
334fddef416Sniklas      bfd *abfd;
335fddef416Sniklas      const char *name;
336fddef416Sniklas      flagword flags;
337fddef416Sniklas      asection *section;
338fddef416Sniklas      bfd_vma value;
339fddef416Sniklas      const char *string;
340d2201f2fSdrahn      bfd_boolean copy;
341d2201f2fSdrahn      bfd_boolean collect;
342fddef416Sniklas      struct bfd_link_hash_entry **hashp;
343fddef416Sniklas {
344fddef416Sniklas   struct linux_link_hash_entry *h;
345d2201f2fSdrahn   bfd_boolean insert;
346fddef416Sniklas 
347fddef416Sniklas   /* Look up and see if we already have this symbol in the hash table.
348fddef416Sniklas      If we do, and the defining entry is from a shared library, we
349fddef416Sniklas      need to create the dynamic sections.
350fddef416Sniklas 
351fddef416Sniklas      FIXME: What if abfd->xvec != info->hash->creator?  We may want to
352fddef416Sniklas      be able to link Linux a.out and ELF objects together, but serious
353fddef416Sniklas      confusion is possible.  */
354fddef416Sniklas 
355d2201f2fSdrahn   insert = FALSE;
356fddef416Sniklas 
357*cf2f2c56Smiod   if (! info->relocatable
358fddef416Sniklas       && linux_hash_table (info)->dynobj == NULL
359fddef416Sniklas       && strcmp (name, SHARABLE_CONFLICTS) == 0
360fddef416Sniklas       && (flags & BSF_CONSTRUCTOR) != 0
361fddef416Sniklas       && abfd->xvec == info->hash->creator)
362fddef416Sniklas     {
363fddef416Sniklas       if (! linux_link_create_dynamic_sections (abfd, info))
364d2201f2fSdrahn 	return FALSE;
365fddef416Sniklas       linux_hash_table (info)->dynobj = abfd;
366d2201f2fSdrahn       insert = TRUE;
367fddef416Sniklas     }
368fddef416Sniklas 
369fddef416Sniklas   if (bfd_is_abs_section (section)
370fddef416Sniklas       && abfd->xvec == info->hash->creator)
371fddef416Sniklas     {
372d2201f2fSdrahn       h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE,
373d2201f2fSdrahn 				  FALSE, FALSE);
374fddef416Sniklas       if (h != NULL
375fddef416Sniklas 	  && (h->root.root.type == bfd_link_hash_defined
376fddef416Sniklas 	      || h->root.root.type == bfd_link_hash_defweak))
377fddef416Sniklas 	{
378fddef416Sniklas 	  struct fixup *f;
379fddef416Sniklas 
380fddef416Sniklas 	  if (hashp != NULL)
381fddef416Sniklas 	    *hashp = (struct bfd_link_hash_entry *) h;
382fddef416Sniklas 
383fddef416Sniklas 	  f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
384fddef416Sniklas 	  if (f == NULL)
385d2201f2fSdrahn 	    return FALSE;
386fddef416Sniklas 	  f->jump = IS_PLT_SYM (name);
387fddef416Sniklas 
388d2201f2fSdrahn 	  return TRUE;
389fddef416Sniklas 	}
390fddef416Sniklas     }
391fddef416Sniklas 
392fddef416Sniklas   /* Do the usual procedure for adding a symbol.  */
393fddef416Sniklas   if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
394fddef416Sniklas 					  value, string, copy, collect,
395fddef416Sniklas 					  hashp))
396d2201f2fSdrahn     return FALSE;
397fddef416Sniklas 
398fddef416Sniklas   /* Insert a pointer to our table in the set vector.  The dynamic
399d2201f2fSdrahn      linker requires this information.  */
400fddef416Sniklas   if (insert)
401fddef416Sniklas     {
402fddef416Sniklas       asection *s;
403fddef416Sniklas 
404fddef416Sniklas       /* Here we do our special thing to add the pointer to the
405fddef416Sniklas 	 dynamic section in the SHARABLE_CONFLICTS set vector.  */
406fddef416Sniklas       s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
407fddef416Sniklas 				   ".linux-dynamic");
408fddef416Sniklas       BFD_ASSERT (s != NULL);
409fddef416Sniklas 
410fddef416Sniklas       if (! (_bfd_generic_link_add_one_symbol
411fddef416Sniklas 	     (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
412d2201f2fSdrahn 	      BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,
413d2201f2fSdrahn 	      FALSE, FALSE, NULL)))
414d2201f2fSdrahn 	return FALSE;
415fddef416Sniklas     }
416fddef416Sniklas 
417d2201f2fSdrahn   return TRUE;
418fddef416Sniklas }
419fddef416Sniklas 
420fddef416Sniklas /* We will crawl the hash table and come here for every global symbol.
421fddef416Sniklas    We will examine each entry and see if there are indications that we
422fddef416Sniklas    need to add a fixup.  There are two possible cases - one is where
423fddef416Sniklas    you have duplicate definitions of PLT or GOT symbols - these will
424fddef416Sniklas    have already been caught and added as "builtin" fixups.  If we find
425fddef416Sniklas    that the corresponding non PLT/GOT symbol is also present, we
426fddef416Sniklas    convert it to a regular fixup instead.
427fddef416Sniklas 
428fddef416Sniklas    This function is called via linux_link_hash_traverse.  */
429fddef416Sniklas 
430d2201f2fSdrahn static bfd_boolean
linux_tally_symbols(h,data)431fddef416Sniklas linux_tally_symbols (h, data)
432fddef416Sniklas      struct linux_link_hash_entry *h;
433fddef416Sniklas      PTR data;
434fddef416Sniklas {
435fddef416Sniklas   struct bfd_link_info *info = (struct bfd_link_info *) data;
436fddef416Sniklas   struct fixup *f, *f1;
437fddef416Sniklas   int is_plt;
438fddef416Sniklas   struct linux_link_hash_entry *h1, *h2;
439d2201f2fSdrahn   bfd_boolean exists;
440d2201f2fSdrahn 
441d2201f2fSdrahn   if (h->root.root.type == bfd_link_hash_warning)
442d2201f2fSdrahn     h = (struct linux_link_hash_entry *) h->root.root.u.i.link;
443fddef416Sniklas 
444fddef416Sniklas   if (h->root.root.type == bfd_link_hash_undefined
445fddef416Sniklas       && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
446fddef416Sniklas 		  sizeof NEEDS_SHRLIB - 1) == 0)
447fddef416Sniklas     {
448fddef416Sniklas       const char *name;
449fddef416Sniklas       char *p;
450fddef416Sniklas       char *alloc = NULL;
451fddef416Sniklas 
452fddef416Sniklas       name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
453fddef416Sniklas       p = strrchr (name, '_');
454fddef416Sniklas       if (p != NULL)
455d2201f2fSdrahn 	alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);
456fddef416Sniklas 
457fddef416Sniklas       if (p == NULL || alloc == NULL)
458f7cc78ecSespie 	(*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
459fddef416Sniklas 			       name);
460fddef416Sniklas       else
461fddef416Sniklas 	{
462fddef416Sniklas 	  strcpy (alloc, name);
463fddef416Sniklas 	  p = strrchr (alloc, '_');
464fddef416Sniklas 	  *p++ = '\0';
465fddef416Sniklas 	  (*_bfd_error_handler)
466f7cc78ecSespie 	    (_("Output file requires shared library `%s.so.%s'\n"),
467fddef416Sniklas 	     alloc, p);
468fddef416Sniklas 	  free (alloc);
469fddef416Sniklas 	}
470fddef416Sniklas 
471fddef416Sniklas       abort ();
472fddef416Sniklas     }
473fddef416Sniklas 
474fddef416Sniklas   /* If this symbol is not a PLT/GOT, we do not even need to look at
475fddef416Sniklas      it.  */
476fddef416Sniklas   is_plt = IS_PLT_SYM (h->root.root.root.string);
477fddef416Sniklas 
478fddef416Sniklas   if (is_plt || IS_GOT_SYM (h->root.root.root.string))
479fddef416Sniklas     {
480fddef416Sniklas       /* Look up this symbol twice.  Once just as a regular lookup,
481fddef416Sniklas 	 and then again following all of the indirect links until we
482fddef416Sniklas 	 reach a real symbol.  */
483fddef416Sniklas       h1 = linux_link_hash_lookup (linux_hash_table (info),
484fddef416Sniklas 				   (h->root.root.root.string
485fddef416Sniklas 				    + sizeof PLT_REF_PREFIX - 1),
486d2201f2fSdrahn 				   FALSE, FALSE, TRUE);
487fddef416Sniklas       /* h2 does not follow indirect symbols.  */
488fddef416Sniklas       h2 = linux_link_hash_lookup (linux_hash_table (info),
489fddef416Sniklas 				   (h->root.root.root.string
490fddef416Sniklas 				    + sizeof PLT_REF_PREFIX - 1),
491d2201f2fSdrahn 				   FALSE, FALSE, FALSE);
492fddef416Sniklas 
493fddef416Sniklas       /* The real symbol must exist but if it is also an ABS symbol,
494fddef416Sniklas 	 there is no need to have a fixup.  This is because they both
495fddef416Sniklas 	 came from the same library.  If on the other hand, we had to
496fddef416Sniklas 	 use an indirect symbol to get to the real symbol, we add the
497fddef416Sniklas 	 fixup anyway, since there are cases where these symbols come
498fddef416Sniklas 	 from different shared libraries */
499fddef416Sniklas       if (h1 != NULL
500fddef416Sniklas 	  && (((h1->root.root.type == bfd_link_hash_defined
501fddef416Sniklas 		|| h1->root.root.type == bfd_link_hash_defweak)
502fddef416Sniklas 	       && ! bfd_is_abs_section (h1->root.root.u.def.section))
503fddef416Sniklas 	      || h2->root.root.type == bfd_link_hash_indirect))
504fddef416Sniklas 	{
505fddef416Sniklas 	  /* See if there is a "builtin" fixup already present
506fddef416Sniklas 	     involving this symbol.  If so, convert it to a regular
507fddef416Sniklas 	     fixup.  In the end, this relaxes some of the requirements
508fddef416Sniklas 	     about the order of performing fixups.  */
509d2201f2fSdrahn 	  exists = FALSE;
510fddef416Sniklas 	  for (f1 = linux_hash_table (info)->fixup_list;
511fddef416Sniklas 	       f1 != NULL;
512fddef416Sniklas 	       f1 = f1->next)
513fddef416Sniklas 	    {
514fddef416Sniklas 	      if ((f1->h != h && f1->h != h1)
515fddef416Sniklas 		  || (! f1->builtin && ! f1->jump))
516fddef416Sniklas 		continue;
517fddef416Sniklas 	      if (f1->h == h1)
518d2201f2fSdrahn 		exists = TRUE;
519fddef416Sniklas 	      if (! exists
520fddef416Sniklas 		  && bfd_is_abs_section (h->root.root.u.def.section))
521fddef416Sniklas 		{
522fddef416Sniklas 		  f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
523fddef416Sniklas 		  f->jump = is_plt;
524fddef416Sniklas 		}
525fddef416Sniklas 	      f1->h = h1;
526fddef416Sniklas 	      f1->jump = is_plt;
527fddef416Sniklas 	      f1->builtin = 0;
528d2201f2fSdrahn 	      exists = TRUE;
529fddef416Sniklas 	    }
530fddef416Sniklas 	  if (! exists
531fddef416Sniklas 	      && bfd_is_abs_section (h->root.root.u.def.section))
532fddef416Sniklas 	    {
533fddef416Sniklas 	      f = new_fixup (info, h1, h->root.root.u.def.value, 0);
534fddef416Sniklas 	      if (f == NULL)
535fddef416Sniklas 		{
536fddef416Sniklas 		  /* FIXME: No way to return error.  */
537fddef416Sniklas 		  abort ();
538fddef416Sniklas 		}
539fddef416Sniklas 	      f->jump = is_plt;
540fddef416Sniklas 	    }
541fddef416Sniklas 	}
542fddef416Sniklas 
543fddef416Sniklas       /* Quick and dirty way of stripping these symbols from the
544fddef416Sniklas 	 symtab.  */
545fddef416Sniklas       if (bfd_is_abs_section (h->root.root.u.def.section))
546d2201f2fSdrahn 	h->root.written = TRUE;
547fddef416Sniklas     }
548fddef416Sniklas 
549d2201f2fSdrahn   return TRUE;
550fddef416Sniklas }
551fddef416Sniklas 
552fddef416Sniklas /* This is called to set the size of the .linux-dynamic section is.
553fddef416Sniklas    It is called by the Linux linker emulation before_allocation
554fddef416Sniklas    routine.  We have finished reading all of the input files, and now
555fddef416Sniklas    we just scan the hash tables to find out how many additional fixups
556fddef416Sniklas    are required.  */
557fddef416Sniklas 
558d2201f2fSdrahn bfd_boolean
bfd_sparclinux_size_dynamic_sections(output_bfd,info)559fddef416Sniklas bfd_sparclinux_size_dynamic_sections (output_bfd, info)
560fddef416Sniklas      bfd *output_bfd;
561fddef416Sniklas      struct bfd_link_info *info;
562fddef416Sniklas {
563fddef416Sniklas   struct fixup *f;
564fddef416Sniklas   asection *s;
565fddef416Sniklas 
566fddef416Sniklas   if (output_bfd->xvec != &MY(vec))
567d2201f2fSdrahn     return TRUE;
568fddef416Sniklas 
569fddef416Sniklas   /* First find the fixups...  */
570fddef416Sniklas   linux_link_hash_traverse (linux_hash_table (info),
571fddef416Sniklas 			    linux_tally_symbols,
572fddef416Sniklas 			    (PTR) info);
573fddef416Sniklas 
574fddef416Sniklas   /* If there are builtin fixups, leave room for a marker.  This is
575fddef416Sniklas      used by the dynamic linker so that it knows that all that follow
576fddef416Sniklas      are builtin fixups instead of regular fixups.  */
577fddef416Sniklas   for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
578fddef416Sniklas     {
579fddef416Sniklas       if (f->builtin)
580fddef416Sniklas 	{
581fddef416Sniklas 	  ++linux_hash_table (info)->fixup_count;
582fddef416Sniklas 	  ++linux_hash_table (info)->local_builtins;
583fddef416Sniklas 	  break;
584fddef416Sniklas 	}
585fddef416Sniklas     }
586fddef416Sniklas 
587fddef416Sniklas   if (linux_hash_table (info)->dynobj == NULL)
588fddef416Sniklas     {
589fddef416Sniklas       if (linux_hash_table (info)->fixup_count > 0)
590fddef416Sniklas 	abort ();
591d2201f2fSdrahn       return TRUE;
592fddef416Sniklas     }
593fddef416Sniklas 
594fddef416Sniklas   /* Allocate memory for our fixup table.  We will fill it in later.  */
595fddef416Sniklas   s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
596fddef416Sniklas 			       ".linux-dynamic");
597fddef416Sniklas   if (s != NULL)
598fddef416Sniklas     {
599d2201f2fSdrahn       s->_raw_size = linux_hash_table (info)->fixup_count + 1;
600d2201f2fSdrahn       s->_raw_size *= 8;
601d2201f2fSdrahn       s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
602fddef416Sniklas       if (s->contents == NULL)
603d2201f2fSdrahn 	return FALSE;
604fddef416Sniklas     }
605fddef416Sniklas 
606d2201f2fSdrahn   return TRUE;
607fddef416Sniklas }
608fddef416Sniklas 
609fddef416Sniklas /* We come here once we are ready to actually write the fixup table to
610fddef416Sniklas    the output file.  Scan the fixup tables and so forth and generate
611fddef416Sniklas    the stuff we need.  */
612fddef416Sniklas 
613d2201f2fSdrahn static bfd_boolean
linux_finish_dynamic_link(output_bfd,info)614fddef416Sniklas linux_finish_dynamic_link (output_bfd, info)
615fddef416Sniklas      bfd *output_bfd;
616fddef416Sniklas      struct bfd_link_info *info;
617fddef416Sniklas {
618fddef416Sniklas   asection *s, *os, *is;
619fddef416Sniklas   bfd_byte *fixup_table;
620fddef416Sniklas   struct linux_link_hash_entry *h;
621fddef416Sniklas   struct fixup *f;
622fddef416Sniklas   unsigned int new_addr;
623fddef416Sniklas   int section_offset;
624fddef416Sniklas   unsigned int fixups_written;
625fddef416Sniklas 
626fddef416Sniklas   if (linux_hash_table (info)->dynobj == NULL)
627d2201f2fSdrahn     return TRUE;
628fddef416Sniklas 
629fddef416Sniklas   s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
630fddef416Sniklas 			       ".linux-dynamic");
631fddef416Sniklas   BFD_ASSERT (s != NULL);
632fddef416Sniklas   os = s->output_section;
633fddef416Sniklas   fixups_written = 0;
634fddef416Sniklas 
635fddef416Sniklas #ifdef LINUX_LINK_DEBUG
636fddef416Sniklas   printf ("Fixup table file offset: %x  VMA: %x\n",
637fddef416Sniklas 	  os->filepos + s->output_offset,
638fddef416Sniklas 	  os->vma + s->output_offset);
639fddef416Sniklas #endif
640fddef416Sniklas 
641fddef416Sniklas   fixup_table = s->contents;
642d2201f2fSdrahn   bfd_put_32 (output_bfd,
643d2201f2fSdrahn 	      (bfd_vma) linux_hash_table (info)->fixup_count, fixup_table);
644fddef416Sniklas   fixup_table += 4;
645fddef416Sniklas 
646fddef416Sniklas   /* Fill in fixup table.  */
647fddef416Sniklas   for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
648fddef416Sniklas     {
649fddef416Sniklas       if (f->builtin)
650fddef416Sniklas 	continue;
651fddef416Sniklas 
652fddef416Sniklas       if (f->h->root.root.type != bfd_link_hash_defined
653fddef416Sniklas 	  && f->h->root.root.type != bfd_link_hash_defweak)
654fddef416Sniklas 	{
655fddef416Sniklas 	  (*_bfd_error_handler)
656f7cc78ecSespie 	    (_("Symbol %s not defined for fixups\n"),
657fddef416Sniklas 	     f->h->root.root.root.string);
658fddef416Sniklas 	  continue;
659fddef416Sniklas 	}
660fddef416Sniklas 
661fddef416Sniklas       is = f->h->root.root.u.def.section;
662fddef416Sniklas       section_offset = is->output_section->vma + is->output_offset;
663fddef416Sniklas       new_addr = f->h->root.root.u.def.value + section_offset;
664fddef416Sniklas 
665fddef416Sniklas #ifdef LINUX_LINK_DEBUG
666fddef416Sniklas       printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
667fddef416Sniklas 	      new_addr, f->value);
668fddef416Sniklas #endif
669fddef416Sniklas 
670fddef416Sniklas       if (f->jump)
671fddef416Sniklas 	{
672fddef416Sniklas 	  /* Relative address */
673fddef416Sniklas 	  new_addr = new_addr - (f->value + 5);
674d2201f2fSdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
675fddef416Sniklas 	  fixup_table += 4;
676fddef416Sniklas 	  bfd_put_32 (output_bfd, f->value + 1, fixup_table);
677fddef416Sniklas 	  fixup_table += 4;
678fddef416Sniklas 	}
679fddef416Sniklas       else
680fddef416Sniklas 	{
681d2201f2fSdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
682fddef416Sniklas 	  fixup_table += 4;
683fddef416Sniklas 	  bfd_put_32 (output_bfd, f->value, fixup_table);
684fddef416Sniklas 	  fixup_table += 4;
685fddef416Sniklas 	}
686fddef416Sniklas       ++fixups_written;
687fddef416Sniklas     }
688fddef416Sniklas 
689fddef416Sniklas   if (linux_hash_table (info)->local_builtins != 0)
690fddef416Sniklas     {
691fddef416Sniklas       /* Special marker so we know to switch to the other type of fixup */
692d2201f2fSdrahn       bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
693fddef416Sniklas       fixup_table += 4;
694d2201f2fSdrahn       bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
695fddef416Sniklas       fixup_table += 4;
696fddef416Sniklas       ++fixups_written;
697fddef416Sniklas       for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
698fddef416Sniklas 	{
699fddef416Sniklas 	  if (! f->builtin)
700fddef416Sniklas 	    continue;
701fddef416Sniklas 
702fddef416Sniklas 	  if (f->h->root.root.type != bfd_link_hash_defined
703fddef416Sniklas 	      && f->h->root.root.type != bfd_link_hash_defweak)
704fddef416Sniklas 	    {
705fddef416Sniklas 	      (*_bfd_error_handler)
706f7cc78ecSespie 		(_("Symbol %s not defined for fixups\n"),
707fddef416Sniklas 		 f->h->root.root.root.string);
708fddef416Sniklas 	      continue;
709fddef416Sniklas 	    }
710fddef416Sniklas 
711fddef416Sniklas 	  is = f->h->root.root.u.def.section;
712fddef416Sniklas 	  section_offset = is->output_section->vma + is->output_offset;
713fddef416Sniklas 	  new_addr = f->h->root.root.u.def.value + section_offset;
714fddef416Sniklas 
715fddef416Sniklas #ifdef LINUX_LINK_DEBUG
716fddef416Sniklas 	  printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
717fddef416Sniklas 		  new_addr, f->value);
718fddef416Sniklas #endif
719fddef416Sniklas 
720d2201f2fSdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
721fddef416Sniklas 	  fixup_table += 4;
722fddef416Sniklas 	  bfd_put_32 (output_bfd, f->value, fixup_table);
723fddef416Sniklas 	  fixup_table += 4;
724fddef416Sniklas 	  ++fixups_written;
725fddef416Sniklas 	}
726fddef416Sniklas     }
727fddef416Sniklas 
728fddef416Sniklas   if (linux_hash_table (info)->fixup_count != fixups_written)
729fddef416Sniklas     {
730f7cc78ecSespie       (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
731fddef416Sniklas       while (linux_hash_table (info)->fixup_count > fixups_written)
732fddef416Sniklas 	{
733d2201f2fSdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
734fddef416Sniklas 	  fixup_table += 4;
735d2201f2fSdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
736fddef416Sniklas 	  fixup_table += 4;
737fddef416Sniklas 	  ++fixups_written;
738fddef416Sniklas 	}
739fddef416Sniklas     }
740fddef416Sniklas 
741fddef416Sniklas   h = linux_link_hash_lookup (linux_hash_table (info),
742fddef416Sniklas 			      "__BUILTIN_FIXUPS__",
743d2201f2fSdrahn 			      FALSE, FALSE, FALSE);
744fddef416Sniklas 
745fddef416Sniklas   if (h != NULL
746fddef416Sniklas       && (h->root.root.type == bfd_link_hash_defined
747fddef416Sniklas 	  || h->root.root.type == bfd_link_hash_defweak))
748fddef416Sniklas     {
749fddef416Sniklas       is = h->root.root.u.def.section;
750fddef416Sniklas       section_offset = is->output_section->vma + is->output_offset;
751fddef416Sniklas       new_addr = h->root.root.u.def.value + section_offset;
752fddef416Sniklas 
753fddef416Sniklas #ifdef LINUX_LINK_DEBUG
754fddef416Sniklas       printf ("Builtin fixup table at %x\n", new_addr);
755fddef416Sniklas #endif
756fddef416Sniklas 
757d2201f2fSdrahn       bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
758fddef416Sniklas     }
759fddef416Sniklas   else
760d2201f2fSdrahn     bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
761fddef416Sniklas 
762d2201f2fSdrahn   if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
763d2201f2fSdrahn 		SEEK_SET) != 0)
764d2201f2fSdrahn     return FALSE;
765fddef416Sniklas 
766d2201f2fSdrahn   if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd) != s->_raw_size)
767d2201f2fSdrahn     return FALSE;
768fddef416Sniklas 
769d2201f2fSdrahn   return TRUE;
770fddef416Sniklas }
771fddef416Sniklas 
772fddef416Sniklas #define MY_bfd_link_hash_table_create linux_link_hash_table_create
773fddef416Sniklas #define MY_add_one_symbol linux_add_one_symbol
774fddef416Sniklas #define MY_finish_dynamic_link linux_finish_dynamic_link
775fddef416Sniklas 
776fddef416Sniklas #define MY_zmagic_contiguous 1
777fddef416Sniklas 
778fddef416Sniklas #include "aout-target.h"
779