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