Add output_type to bfd_link_info
[external/binutils.git] / bfd / i386linux.c
1 /* BFD back-end for linux flavored i386 a.out binaries.
2    Copyright (C) 1992-2015 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
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
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 \f
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 *
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 *
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 *
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
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
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 (! bfd_link_relocatable (info)
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
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
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
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"