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