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