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