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