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