Home | History | Annotate | Download | only in bfd
      1 /* BFD back-end for linux flavored sparc 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_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
     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
     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 *
    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 *
    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 *
    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
    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
    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 (! bfd_link_relocatable (info)
    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
    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
    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
    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