xref: /openbsd/gnu/usr.bin/binutils/bfd/i386linux.c (revision 007c2a45)
12159047fSniklas /* BFD back-end for linux flavored i386 a.out binaries.
2c074d1c9Sdrahn    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 2001, 2002, 2003
3b305b0f1Sespie    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas This file is part of BFD, the Binary File Descriptor library.
62159047fSniklas 
72159047fSniklas This program is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
92159047fSniklas the Free Software Foundation; either version 2 of the License, or
102159047fSniklas (at your option) any later version.
112159047fSniklas 
122159047fSniklas This program is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas You should have received a copy of the GNU General Public License
182159047fSniklas along with this program; if not, write to the Free Software
192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
202159047fSniklas 
212159047fSniklas #define	TARGET_PAGE_SIZE	4096
222159047fSniklas #define ZMAGIC_DISK_BLOCK_SIZE 1024
23c88b1d6cSniklas #define	SEGMENT_SIZE TARGET_PAGE_SIZE
242159047fSniklas #define TEXT_START_ADDR	0x0
252159047fSniklas #define N_SHARED_LIB(x) 0
262159047fSniklas 
27b305b0f1Sespie #define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
28b305b0f1Sespie 
292159047fSniklas #include "bfd.h"
302159047fSniklas #include "sysdep.h"
312159047fSniklas #include "libbfd.h"
322159047fSniklas #include "aout/aout64.h"
332159047fSniklas #include "aout/stab_gnu.h"
342159047fSniklas #include "aout/ar.h"
352159047fSniklas #include "libaout.h"           /* BFD a.out internal data structures */
362159047fSniklas 
372159047fSniklas #define DEFAULT_ARCH bfd_arch_i386
38c074d1c9Sdrahn 
39c074d1c9Sdrahn /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
40c074d1c9Sdrahn    remove whitespace added here, and thus will fail to concatenate
41c074d1c9Sdrahn    the tokens.  */
42c074d1c9Sdrahn #define MY(OP) CONCAT2 (i386linux_,OP)
432159047fSniklas #define TARGETNAME "a.out-i386-linux"
442159047fSniklas 
452159047fSniklas extern const bfd_target MY(vec);
462159047fSniklas 
472159047fSniklas /* We always generate QMAGIC files in preference to ZMAGIC files.  It
482159047fSniklas    would be possible to make this a linker option, if that ever
492159047fSniklas    becomes important.  */
502159047fSniklas 
512159047fSniklas static void MY_final_link_callback
522159047fSniklas   PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
53c074d1c9Sdrahn static bfd_boolean i386linux_bfd_final_link
54b305b0f1Sespie   PARAMS ((bfd *, struct bfd_link_info *));
55c074d1c9Sdrahn static bfd_boolean i386linux_write_object_contents PARAMS ((bfd *));
562159047fSniklas 
57c074d1c9Sdrahn static bfd_boolean
i386linux_bfd_final_link(abfd,info)582159047fSniklas i386linux_bfd_final_link (abfd, info)
592159047fSniklas      bfd *abfd;
602159047fSniklas      struct bfd_link_info *info;
612159047fSniklas {
622159047fSniklas   obj_aout_subformat (abfd) = q_magic_format;
632159047fSniklas   return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
642159047fSniklas }
652159047fSniklas 
662159047fSniklas #define MY_bfd_final_link i386linux_bfd_final_link
672159047fSniklas 
682159047fSniklas /* Set the machine type correctly.  */
692159047fSniklas 
70c074d1c9Sdrahn static bfd_boolean
i386linux_write_object_contents(abfd)712159047fSniklas i386linux_write_object_contents (abfd)
722159047fSniklas      bfd *abfd;
732159047fSniklas {
742159047fSniklas   struct external_exec exec_bytes;
752159047fSniklas   struct internal_exec *execp = exec_hdr (abfd);
762159047fSniklas 
772159047fSniklas   N_SET_MACHTYPE (*execp, M_386);
782159047fSniklas 
792159047fSniklas   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
802159047fSniklas 
812159047fSniklas   WRITE_HEADERS(abfd, execp);
822159047fSniklas 
83c074d1c9Sdrahn   return TRUE;
842159047fSniklas }
852159047fSniklas 
862159047fSniklas #define MY_write_object_contents i386linux_write_object_contents
872159047fSniklas 
882159047fSniklas /* Code to link against Linux a.out shared libraries.  */
892159047fSniklas 
902159047fSniklas /* See if a symbol name is a reference to the global offset table.  */
912159047fSniklas 
922159047fSniklas #ifndef GOT_REF_PREFIX
932159047fSniklas #define	GOT_REF_PREFIX	"__GOT_"
942159047fSniklas #endif
952159047fSniklas 
962159047fSniklas #define IS_GOT_SYM(name) \
972159047fSniklas   (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
982159047fSniklas 
992159047fSniklas /* See if a symbol name is a reference to the procedure linkage table.  */
1002159047fSniklas 
1012159047fSniklas #ifndef PLT_REF_PREFIX
1022159047fSniklas #define	PLT_REF_PREFIX	"__PLT_"
1032159047fSniklas #endif
1042159047fSniklas 
1052159047fSniklas #define IS_PLT_SYM(name) \
1062159047fSniklas   (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
1072159047fSniklas 
1082159047fSniklas /* This string is used to generate specialized error messages.  */
1092159047fSniklas 
1102159047fSniklas #ifndef NEEDS_SHRLIB
1112159047fSniklas #define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
1122159047fSniklas #endif
1132159047fSniklas 
1142159047fSniklas /* This special symbol is a set vector that contains a list of
115*007c2a45Smiod    pointers to fixup tables.  It will be present in any dynamically
1162159047fSniklas    linked file.  The linker generated fixup table should also be added
1172159047fSniklas    to the list, and it should always appear in the second slot (the
1182159047fSniklas    first one is a dummy with a magic number that is defined in
1192159047fSniklas    crt0.o).  */
1202159047fSniklas 
1212159047fSniklas #ifndef SHARABLE_CONFLICTS
1222159047fSniklas #define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
1232159047fSniklas #endif
1242159047fSniklas 
1252159047fSniklas /* We keep a list of fixups.  The terminology is a bit strange, but
1262159047fSniklas    each fixup contains two 32 bit numbers.  A regular fixup contains
1272159047fSniklas    an address and a pointer, and at runtime we should store the
1282159047fSniklas    address at the location pointed to by the pointer.  A builtin fixup
1292159047fSniklas    contains two pointers, and we should read the address using one
1302159047fSniklas    pointer and store it at the location pointed to by the other
1312159047fSniklas    pointer.  Builtin fixups come into play when we have duplicate
1322159047fSniklas    __GOT__ symbols for the same variable.  The builtin fixup will copy
1332159047fSniklas    the GOT pointer from one over into the other.  */
1342159047fSniklas 
1352159047fSniklas struct fixup
1362159047fSniklas {
1372159047fSniklas   struct fixup *next;
1382159047fSniklas   struct linux_link_hash_entry *h;
1392159047fSniklas   bfd_vma value;
1402159047fSniklas 
1412159047fSniklas   /* Nonzero if this is a jump instruction that needs to be fixed,
1422159047fSniklas      zero if this is just a pointer */
1432159047fSniklas   char jump;
1442159047fSniklas 
1452159047fSniklas   char builtin;
1462159047fSniklas };
1472159047fSniklas 
1482159047fSniklas /* We don't need a special hash table entry structure, but we do need
1492159047fSniklas    to keep some information between linker passes, so we use a special
1502159047fSniklas    hash table.  */
1512159047fSniklas 
1522159047fSniklas struct linux_link_hash_entry
1532159047fSniklas {
1542159047fSniklas   struct aout_link_hash_entry root;
1552159047fSniklas };
1562159047fSniklas 
1572159047fSniklas struct linux_link_hash_table
1582159047fSniklas {
1592159047fSniklas   struct aout_link_hash_table root;
1602159047fSniklas 
1612159047fSniklas   /* First dynamic object found in link.  */
1622159047fSniklas   bfd *dynobj;
1632159047fSniklas 
1642159047fSniklas   /* Number of fixups.  */
1652159047fSniklas   size_t fixup_count;
1662159047fSniklas 
1672159047fSniklas   /* Number of builtin fixups.  */
1682159047fSniklas   size_t local_builtins;
1692159047fSniklas 
1702159047fSniklas   /* List of fixups.  */
1712159047fSniklas   struct fixup *fixup_list;
1722159047fSniklas };
1732159047fSniklas 
1742159047fSniklas static struct bfd_hash_entry *linux_link_hash_newfunc
1752159047fSniklas   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
1762159047fSniklas static struct bfd_link_hash_table *linux_link_hash_table_create
1772159047fSniklas   PARAMS ((bfd *));
1782159047fSniklas static struct fixup *new_fixup
1792159047fSniklas   PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
1802159047fSniklas 	   bfd_vma, int));
181c074d1c9Sdrahn static bfd_boolean linux_link_create_dynamic_sections
1822159047fSniklas   PARAMS ((bfd *, struct bfd_link_info *));
183c074d1c9Sdrahn static bfd_boolean linux_add_one_symbol
1842159047fSniklas   PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
185c074d1c9Sdrahn 	   bfd_vma, const char *, bfd_boolean, bfd_boolean,
1862159047fSniklas 	   struct bfd_link_hash_entry **));
187c074d1c9Sdrahn static bfd_boolean linux_tally_symbols
1882159047fSniklas   PARAMS ((struct linux_link_hash_entry *, PTR));
189c074d1c9Sdrahn static bfd_boolean linux_finish_dynamic_link
1902159047fSniklas   PARAMS ((bfd *, struct bfd_link_info *));
1912159047fSniklas 
1922159047fSniklas /* Routine to create an entry in an Linux link hash table.  */
1932159047fSniklas 
1942159047fSniklas static struct bfd_hash_entry *
linux_link_hash_newfunc(entry,table,string)1952159047fSniklas linux_link_hash_newfunc (entry, table, string)
1962159047fSniklas      struct bfd_hash_entry *entry;
1972159047fSniklas      struct bfd_hash_table *table;
1982159047fSniklas      const char *string;
1992159047fSniklas {
2002159047fSniklas   struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
2012159047fSniklas 
2022159047fSniklas   /* Allocate the structure if it has not already been allocated by a
2032159047fSniklas      subclass.  */
2042159047fSniklas   if (ret == (struct linux_link_hash_entry *) NULL)
2052159047fSniklas     ret = ((struct linux_link_hash_entry *)
2062159047fSniklas 	   bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
2072159047fSniklas   if (ret == NULL)
2082159047fSniklas     return (struct bfd_hash_entry *) ret;
2092159047fSniklas 
2102159047fSniklas   /* Call the allocation method of the superclass.  */
2112159047fSniklas   ret = ((struct linux_link_hash_entry *)
2122159047fSniklas 	 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
2132159047fSniklas 				       table, string));
2142159047fSniklas   if (ret != NULL)
2152159047fSniklas     {
2162159047fSniklas       /* Set local fields; there aren't any.  */
2172159047fSniklas     }
2182159047fSniklas 
2192159047fSniklas   return (struct bfd_hash_entry *) ret;
2202159047fSniklas }
2212159047fSniklas 
2222159047fSniklas /* Create a Linux link hash table.  */
2232159047fSniklas 
2242159047fSniklas static struct bfd_link_hash_table *
linux_link_hash_table_create(abfd)2252159047fSniklas linux_link_hash_table_create (abfd)
2262159047fSniklas      bfd *abfd;
2272159047fSniklas {
2282159047fSniklas   struct linux_link_hash_table *ret;
229c074d1c9Sdrahn   bfd_size_type amt = sizeof (struct linux_link_hash_table);
2302159047fSniklas 
231c074d1c9Sdrahn   ret = (struct linux_link_hash_table *) bfd_alloc (abfd, amt);
2322159047fSniklas   if (ret == (struct linux_link_hash_table *) NULL)
2332159047fSniklas     return (struct bfd_link_hash_table *) NULL;
2342159047fSniklas   if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
2352159047fSniklas 					 linux_link_hash_newfunc))
2362159047fSniklas     {
2372159047fSniklas       free (ret);
2382159047fSniklas       return (struct bfd_link_hash_table *) NULL;
2392159047fSniklas     }
2402159047fSniklas 
2412159047fSniklas   ret->dynobj = NULL;
2422159047fSniklas   ret->fixup_count = 0;
2432159047fSniklas   ret->local_builtins = 0;
2442159047fSniklas   ret->fixup_list = NULL;
2452159047fSniklas 
2462159047fSniklas   return &ret->root.root;
2472159047fSniklas }
2482159047fSniklas 
2492159047fSniklas /* Look up an entry in a Linux link hash table.  */
2502159047fSniklas 
2512159047fSniklas #define linux_link_hash_lookup(table, string, create, copy, follow) \
2522159047fSniklas   ((struct linux_link_hash_entry *) \
2532159047fSniklas    aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
2542159047fSniklas 			  (follow)))
2552159047fSniklas 
2562159047fSniklas /* Traverse a Linux link hash table.  */
2572159047fSniklas 
2582159047fSniklas #define linux_link_hash_traverse(table, func, info)			\
2592159047fSniklas   (aout_link_hash_traverse						\
2602159047fSniklas    (&(table)->root,							\
261c074d1c9Sdrahn     (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
2622159047fSniklas     (info)))
2632159047fSniklas 
2642159047fSniklas /* Get the Linux link hash table from the info structure.  This is
2652159047fSniklas    just a cast.  */
2662159047fSniklas 
2672159047fSniklas #define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
2682159047fSniklas 
2692159047fSniklas /* Store the information for a new fixup.  */
2702159047fSniklas 
2712159047fSniklas static struct fixup *
new_fixup(info,h,value,builtin)2722159047fSniklas new_fixup (info, h, value, builtin)
2732159047fSniklas      struct bfd_link_info *info;
2742159047fSniklas      struct linux_link_hash_entry *h;
2752159047fSniklas      bfd_vma value;
2762159047fSniklas      int builtin;
2772159047fSniklas {
2782159047fSniklas   struct fixup *f;
2792159047fSniklas 
2802159047fSniklas   f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
2812159047fSniklas 					  sizeof (struct fixup));
2822159047fSniklas   if (f == NULL)
2832159047fSniklas     return f;
2842159047fSniklas   f->next = linux_hash_table (info)->fixup_list;
2852159047fSniklas   linux_hash_table (info)->fixup_list = f;
2862159047fSniklas   f->h = h;
2872159047fSniklas   f->value = value;
2882159047fSniklas   f->builtin = builtin;
2892159047fSniklas   f->jump = 0;
2902159047fSniklas   ++linux_hash_table (info)->fixup_count;
2912159047fSniklas   return f;
2922159047fSniklas }
2932159047fSniklas 
2942159047fSniklas /* We come here once we realize that we are going to link to a shared
2952159047fSniklas    library.  We need to create a special section that contains the
2962159047fSniklas    fixup table, and we ultimately need to add a pointer to this into
2972159047fSniklas    the set vector for SHARABLE_CONFLICTS.  At this point we do not
2982159047fSniklas    know the size of the section, but that's OK - we just need to
2992159047fSniklas    create it for now.  */
3002159047fSniklas 
301c074d1c9Sdrahn static bfd_boolean
linux_link_create_dynamic_sections(abfd,info)3022159047fSniklas linux_link_create_dynamic_sections (abfd, info)
3032159047fSniklas      bfd *abfd;
304b305b0f1Sespie      struct bfd_link_info *info ATTRIBUTE_UNUSED;
3052159047fSniklas {
3062159047fSniklas   flagword flags;
3072159047fSniklas   register asection *s;
3082159047fSniklas 
3092159047fSniklas   /* Note that we set the SEC_IN_MEMORY flag.  */
3102159047fSniklas   flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
3112159047fSniklas 
3122159047fSniklas   /* We choose to use the name ".linux-dynamic" for the fixup table.
3132159047fSniklas      Why not? */
3142159047fSniklas   s = bfd_make_section (abfd, ".linux-dynamic");
3152159047fSniklas   if (s == NULL
3162159047fSniklas       || ! bfd_set_section_flags (abfd, s, flags)
3172159047fSniklas       || ! bfd_set_section_alignment (abfd, s, 2))
318c074d1c9Sdrahn     return FALSE;
3192159047fSniklas   s->_raw_size = 0;
3202159047fSniklas   s->contents = 0;
3212159047fSniklas 
322c074d1c9Sdrahn   return TRUE;
3232159047fSniklas }
3242159047fSniklas 
3252159047fSniklas /* Function to add a single symbol to the linker hash table.  This is
3262159047fSniklas    a wrapper around _bfd_generic_link_add_one_symbol which handles the
3272159047fSniklas    tweaking needed for dynamic linking support.  */
3282159047fSniklas 
329c074d1c9Sdrahn static bfd_boolean
linux_add_one_symbol(info,abfd,name,flags,section,value,string,copy,collect,hashp)3302159047fSniklas linux_add_one_symbol (info, abfd, name, flags, section, value, string,
3312159047fSniklas 		      copy, collect, hashp)
3322159047fSniklas      struct bfd_link_info *info;
3332159047fSniklas      bfd *abfd;
3342159047fSniklas      const char *name;
3352159047fSniklas      flagword flags;
3362159047fSniklas      asection *section;
3372159047fSniklas      bfd_vma value;
3382159047fSniklas      const char *string;
339c074d1c9Sdrahn      bfd_boolean copy;
340c074d1c9Sdrahn      bfd_boolean collect;
3412159047fSniklas      struct bfd_link_hash_entry **hashp;
3422159047fSniklas {
3432159047fSniklas   struct linux_link_hash_entry *h;
344c074d1c9Sdrahn   bfd_boolean insert;
3452159047fSniklas 
3462159047fSniklas   /* Look up and see if we already have this symbol in the hash table.
3472159047fSniklas      If we do, and the defining entry is from a shared library, we
3482159047fSniklas      need to create the dynamic sections.
3492159047fSniklas 
3502159047fSniklas      FIXME: What if abfd->xvec != info->hash->creator?  We may want to
3512159047fSniklas      be able to link Linux a.out and ELF objects together, but serious
3522159047fSniklas      confusion is possible.  */
3532159047fSniklas 
354c074d1c9Sdrahn   insert = FALSE;
3552159047fSniklas 
356*007c2a45Smiod   if (! info->relocatable
3572159047fSniklas       && linux_hash_table (info)->dynobj == NULL
3582159047fSniklas       && strcmp (name, SHARABLE_CONFLICTS) == 0
3592159047fSniklas       && (flags & BSF_CONSTRUCTOR) != 0
3602159047fSniklas       && abfd->xvec == info->hash->creator)
3612159047fSniklas     {
3622159047fSniklas       if (! linux_link_create_dynamic_sections (abfd, info))
363c074d1c9Sdrahn 	return FALSE;
3642159047fSniklas       linux_hash_table (info)->dynobj = abfd;
365c074d1c9Sdrahn       insert = TRUE;
3662159047fSniklas     }
3672159047fSniklas 
3682159047fSniklas   if (bfd_is_abs_section (section)
3692159047fSniklas       && abfd->xvec == info->hash->creator)
3702159047fSniklas     {
371c074d1c9Sdrahn       h = linux_link_hash_lookup (linux_hash_table (info), name, FALSE,
372c074d1c9Sdrahn 				  FALSE, FALSE);
3732159047fSniklas       if (h != NULL
3742159047fSniklas 	  && (h->root.root.type == bfd_link_hash_defined
3752159047fSniklas 	      || h->root.root.type == bfd_link_hash_defweak))
3762159047fSniklas 	{
3772159047fSniklas 	  struct fixup *f;
3782159047fSniklas 
3792159047fSniklas 	  if (hashp != NULL)
3802159047fSniklas 	    *hashp = (struct bfd_link_hash_entry *) h;
3812159047fSniklas 
3822159047fSniklas 	  f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
3832159047fSniklas 	  if (f == NULL)
384c074d1c9Sdrahn 	    return FALSE;
3852159047fSniklas 	  f->jump = IS_PLT_SYM (name);
3862159047fSniklas 
387c074d1c9Sdrahn 	  return TRUE;
3882159047fSniklas 	}
3892159047fSniklas     }
3902159047fSniklas 
3912159047fSniklas   /* Do the usual procedure for adding a symbol.  */
3922159047fSniklas   if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
3932159047fSniklas 					  value, string, copy, collect,
3942159047fSniklas 					  hashp))
395c074d1c9Sdrahn     return FALSE;
3962159047fSniklas 
3972159047fSniklas   /* Insert a pointer to our table in the set vector.  The dynamic
3982159047fSniklas      linker requires this information */
3992159047fSniklas   if (insert)
4002159047fSniklas     {
4012159047fSniklas       asection *s;
4022159047fSniklas 
4032159047fSniklas       /* Here we do our special thing to add the pointer to the
4042159047fSniklas 	 dynamic section in the SHARABLE_CONFLICTS set vector.  */
4052159047fSniklas       s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
4062159047fSniklas 				   ".linux-dynamic");
4072159047fSniklas       BFD_ASSERT (s != NULL);
4082159047fSniklas 
4092159047fSniklas       if (! (_bfd_generic_link_add_one_symbol
4102159047fSniklas 	     (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
411c074d1c9Sdrahn 	      BSF_GLOBAL | BSF_CONSTRUCTOR, s, (bfd_vma) 0, NULL,
412c074d1c9Sdrahn 	      FALSE, FALSE, NULL)))
413c074d1c9Sdrahn 	return FALSE;
4142159047fSniklas     }
4152159047fSniklas 
416c074d1c9Sdrahn   return TRUE;
4172159047fSniklas }
4182159047fSniklas 
4192159047fSniklas /* We will crawl the hash table and come here for every global symbol.
4202159047fSniklas    We will examine each entry and see if there are indications that we
4212159047fSniklas    need to add a fixup.  There are two possible cases - one is where
4222159047fSniklas    you have duplicate definitions of PLT or GOT symbols - these will
4232159047fSniklas    have already been caught and added as "builtin" fixups.  If we find
4242159047fSniklas    that the corresponding non PLT/GOT symbol is also present, we
4252159047fSniklas    convert it to a regular fixup instead.
4262159047fSniklas 
4272159047fSniklas    This function is called via linux_link_hash_traverse.  */
4282159047fSniklas 
429c074d1c9Sdrahn static bfd_boolean
linux_tally_symbols(h,data)4302159047fSniklas linux_tally_symbols (h, data)
4312159047fSniklas      struct linux_link_hash_entry *h;
4322159047fSniklas      PTR data;
4332159047fSniklas {
4342159047fSniklas   struct bfd_link_info *info = (struct bfd_link_info *) data;
4352159047fSniklas   struct fixup *f, *f1;
4362159047fSniklas   int is_plt;
4372159047fSniklas   struct linux_link_hash_entry *h1, *h2;
438c074d1c9Sdrahn   bfd_boolean exists;
439c074d1c9Sdrahn 
440c074d1c9Sdrahn   if (h->root.root.type == bfd_link_hash_warning)
441c074d1c9Sdrahn     h = (struct linux_link_hash_entry *) h->root.root.u.i.link;
4422159047fSniklas 
4432159047fSniklas   if (h->root.root.type == bfd_link_hash_undefined
4442159047fSniklas       && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
4452159047fSniklas 		  sizeof NEEDS_SHRLIB - 1) == 0)
4462159047fSniklas     {
4472159047fSniklas       const char *name;
4482159047fSniklas       char *p;
4492159047fSniklas       char *alloc = NULL;
4502159047fSniklas 
4512159047fSniklas       name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
4522159047fSniklas       p = strrchr (name, '_');
4532159047fSniklas       if (p != NULL)
454c074d1c9Sdrahn 	alloc = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 1);
4552159047fSniklas 
4562159047fSniklas       if (p == NULL || alloc == NULL)
457b305b0f1Sespie 	(*_bfd_error_handler) (_("Output file requires shared library `%s'\n"),
4582159047fSniklas 			       name);
4592159047fSniklas       else
4602159047fSniklas 	{
4612159047fSniklas 	  strcpy (alloc, name);
4622159047fSniklas 	  p = strrchr (alloc, '_');
4632159047fSniklas 	  *p++ = '\0';
4642159047fSniklas 	  (*_bfd_error_handler)
465b305b0f1Sespie 	    (_("Output file requires shared library `%s.so.%s'\n"),
4662159047fSniklas 	     alloc, p);
4672159047fSniklas 	  free (alloc);
4682159047fSniklas 	}
4692159047fSniklas 
4702159047fSniklas       abort ();
4712159047fSniklas     }
4722159047fSniklas 
4732159047fSniklas   /* If this symbol is not a PLT/GOT, we do not even need to look at it */
4742159047fSniklas   is_plt = IS_PLT_SYM (h->root.root.root.string);
4752159047fSniklas 
4762159047fSniklas   if (is_plt || IS_GOT_SYM (h->root.root.root.string))
4772159047fSniklas     {
4782159047fSniklas       /* Look up this symbol twice.  Once just as a regular lookup,
4792159047fSniklas 	 and then again following all of the indirect links until we
4802159047fSniklas 	 reach a real symbol.  */
4812159047fSniklas       h1 = linux_link_hash_lookup (linux_hash_table (info),
4822159047fSniklas 				   (h->root.root.root.string
4832159047fSniklas 				    + sizeof PLT_REF_PREFIX - 1),
484c074d1c9Sdrahn 				   FALSE, FALSE, TRUE);
4852159047fSniklas       /* h2 does not follow indirect symbols. */
4862159047fSniklas       h2 = linux_link_hash_lookup (linux_hash_table (info),
4872159047fSniklas 				   (h->root.root.root.string
4882159047fSniklas 				    + sizeof PLT_REF_PREFIX - 1),
489c074d1c9Sdrahn 				   FALSE, FALSE, FALSE);
4902159047fSniklas 
4912159047fSniklas       /* The real symbol must exist but if it is also an ABS symbol,
4922159047fSniklas 	 there is no need to have a fixup.  This is because they both
4932159047fSniklas 	 came from the same library.  If on the other hand, we had to
4942159047fSniklas 	 use an indirect symbol to get to the real symbol, we add the
4952159047fSniklas 	 fixup anyway, since there are cases where these symbols come
4962159047fSniklas 	 from different shared libraries */
4972159047fSniklas       if (h1 != NULL
4982159047fSniklas 	  && (((h1->root.root.type == bfd_link_hash_defined
4992159047fSniklas 		|| h1->root.root.type == bfd_link_hash_defweak)
5002159047fSniklas 	       && ! bfd_is_abs_section (h1->root.root.u.def.section))
5012159047fSniklas 	      || h2->root.root.type == bfd_link_hash_indirect))
5022159047fSniklas 	{
5032159047fSniklas 	  /* See if there is a "builtin" fixup already present
5042159047fSniklas 	     involving this symbol.  If so, convert it to a regular
5052159047fSniklas 	     fixup.  In the end, this relaxes some of the requirements
5062159047fSniklas 	     about the order of performing fixups.  */
507c074d1c9Sdrahn 	  exists = FALSE;
5082159047fSniklas 	  for (f1 = linux_hash_table (info)->fixup_list;
5092159047fSniklas 	       f1 != NULL;
5102159047fSniklas 	       f1 = f1->next)
5112159047fSniklas 	    {
5122159047fSniklas 	      if ((f1->h != h && f1->h != h1)
5132159047fSniklas 		  || (! f1->builtin && ! f1->jump))
5142159047fSniklas 		continue;
5152159047fSniklas 	      if (f1->h == h1)
516c074d1c9Sdrahn 		exists = TRUE;
5172159047fSniklas 	      if (! exists
5182159047fSniklas 		  && bfd_is_abs_section (h->root.root.u.def.section))
5192159047fSniklas 		{
5202159047fSniklas 		  f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
5212159047fSniklas 		  f->jump = is_plt;
5222159047fSniklas 		}
5232159047fSniklas 	      f1->h = h1;
5242159047fSniklas 	      f1->jump = is_plt;
5252159047fSniklas 	      f1->builtin = 0;
526c074d1c9Sdrahn 	      exists = TRUE;
5272159047fSniklas 	    }
5282159047fSniklas 	  if (! exists
5292159047fSniklas 	      && bfd_is_abs_section (h->root.root.u.def.section))
5302159047fSniklas 	    {
5312159047fSniklas 	      f = new_fixup (info, h1, h->root.root.u.def.value, 0);
5322159047fSniklas 	      if (f == NULL)
5332159047fSniklas 		{
5342159047fSniklas 		  /* FIXME: No way to return error.  */
5352159047fSniklas 		  abort ();
5362159047fSniklas 		}
5372159047fSniklas 	      f->jump = is_plt;
5382159047fSniklas 	    }
5392159047fSniklas 	}
5402159047fSniklas 
5412159047fSniklas       /* Quick and dirty way of stripping these symbols from the
5422159047fSniklas 	 symtab. */
5432159047fSniklas       if (bfd_is_abs_section (h->root.root.u.def.section))
544c074d1c9Sdrahn 	h->root.written = TRUE;
5452159047fSniklas     }
5462159047fSniklas 
547c074d1c9Sdrahn   return TRUE;
5482159047fSniklas }
5492159047fSniklas 
5502159047fSniklas /* This is called to set the size of the .linux-dynamic section is.
5512159047fSniklas    It is called by the Linux linker emulation before_allocation
5522159047fSniklas    routine.  We have finished reading all of the input files, and now
5532159047fSniklas    we just scan the hash tables to find out how many additional fixups
5542159047fSniklas    are required.  */
5552159047fSniklas 
556c074d1c9Sdrahn bfd_boolean
bfd_i386linux_size_dynamic_sections(output_bfd,info)557c88b1d6cSniklas bfd_i386linux_size_dynamic_sections (output_bfd, info)
5582159047fSniklas      bfd *output_bfd;
5592159047fSniklas      struct bfd_link_info *info;
5602159047fSniklas {
5612159047fSniklas   struct fixup *f;
5622159047fSniklas   asection *s;
5632159047fSniklas 
5642159047fSniklas   if (output_bfd->xvec != &MY(vec))
565c074d1c9Sdrahn     return TRUE;
5662159047fSniklas 
5672159047fSniklas   /* First find the fixups... */
5682159047fSniklas   linux_link_hash_traverse (linux_hash_table (info),
5692159047fSniklas 			    linux_tally_symbols,
5702159047fSniklas 			    (PTR) info);
5712159047fSniklas 
5722159047fSniklas   /* If there are builtin fixups, leave room for a marker.  This is
5732159047fSniklas      used by the dynamic linker so that it knows that all that follow
5742159047fSniklas      are builtin fixups instead of regular fixups.  */
5752159047fSniklas   for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
5762159047fSniklas     {
5772159047fSniklas       if (f->builtin)
5782159047fSniklas 	{
5792159047fSniklas 	  ++linux_hash_table (info)->fixup_count;
5802159047fSniklas 	  ++linux_hash_table (info)->local_builtins;
5812159047fSniklas 	  break;
5822159047fSniklas 	}
5832159047fSniklas     }
5842159047fSniklas 
5852159047fSniklas   if (linux_hash_table (info)->dynobj == NULL)
5862159047fSniklas     {
5872159047fSniklas       if (linux_hash_table (info)->fixup_count > 0)
5882159047fSniklas 	abort ();
589c074d1c9Sdrahn       return TRUE;
5902159047fSniklas     }
5912159047fSniklas 
5922159047fSniklas   /* Allocate memory for our fixup table.  We will fill it in later.  */
5932159047fSniklas   s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
5942159047fSniklas 			       ".linux-dynamic");
5952159047fSniklas   if (s != NULL)
5962159047fSniklas     {
597c074d1c9Sdrahn       s->_raw_size = linux_hash_table (info)->fixup_count + 1;
598c074d1c9Sdrahn       s->_raw_size *= 8;
599c074d1c9Sdrahn       s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
6002159047fSniklas       if (s->contents == NULL)
601c074d1c9Sdrahn 	return FALSE;
6022159047fSniklas     }
6032159047fSniklas 
604c074d1c9Sdrahn   return TRUE;
6052159047fSniklas }
6062159047fSniklas 
6072159047fSniklas /* We come here once we are ready to actually write the fixup table to
6082159047fSniklas    the output file.  Scan the fixup tables and so forth and generate
6092159047fSniklas    the stuff we need.  */
6102159047fSniklas 
611c074d1c9Sdrahn static bfd_boolean
linux_finish_dynamic_link(output_bfd,info)6122159047fSniklas linux_finish_dynamic_link (output_bfd, info)
6132159047fSniklas      bfd *output_bfd;
6142159047fSniklas      struct bfd_link_info *info;
6152159047fSniklas {
6162159047fSniklas   asection *s, *os, *is;
6172159047fSniklas   bfd_byte *fixup_table;
6182159047fSniklas   struct linux_link_hash_entry *h;
6192159047fSniklas   struct fixup *f;
6202159047fSniklas   unsigned int new_addr;
6212159047fSniklas   int section_offset;
6222159047fSniklas   unsigned int fixups_written;
6232159047fSniklas 
6242159047fSniklas   if (linux_hash_table (info)->dynobj == NULL)
625c074d1c9Sdrahn     return TRUE;
6262159047fSniklas 
6272159047fSniklas   s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
6282159047fSniklas 			       ".linux-dynamic");
6292159047fSniklas   BFD_ASSERT (s != NULL);
6302159047fSniklas   os = s->output_section;
6312159047fSniklas   fixups_written = 0;
6322159047fSniklas 
6332159047fSniklas #ifdef LINUX_LINK_DEBUG
6342159047fSniklas   printf ("Fixup table file offset: %x  VMA: %x\n",
6352159047fSniklas 	  os->filepos + s->output_offset,
6362159047fSniklas 	  os->vma + s->output_offset);
6372159047fSniklas #endif
6382159047fSniklas 
6392159047fSniklas   fixup_table = s->contents;
640c074d1c9Sdrahn   bfd_put_32 (output_bfd,
641c074d1c9Sdrahn 	      (bfd_vma) linux_hash_table (info)->fixup_count, fixup_table);
6422159047fSniklas   fixup_table += 4;
6432159047fSniklas 
6442159047fSniklas   /* Fill in fixup table.  */
6452159047fSniklas   for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
6462159047fSniklas     {
6472159047fSniklas       if (f->builtin)
6482159047fSniklas 	continue;
6492159047fSniklas 
6502159047fSniklas       if (f->h->root.root.type != bfd_link_hash_defined
6512159047fSniklas 	  && f->h->root.root.type != bfd_link_hash_defweak)
6522159047fSniklas 	{
6532159047fSniklas 	  (*_bfd_error_handler)
654b305b0f1Sespie 	    (_("Symbol %s not defined for fixups\n"),
6552159047fSniklas 	     f->h->root.root.root.string);
6562159047fSniklas 	  continue;
6572159047fSniklas 	}
6582159047fSniklas 
6592159047fSniklas       is = f->h->root.root.u.def.section;
6602159047fSniklas       section_offset = is->output_section->vma + is->output_offset;
6612159047fSniklas       new_addr = f->h->root.root.u.def.value + section_offset;
6622159047fSniklas 
6632159047fSniklas #ifdef LINUX_LINK_DEBUG
6642159047fSniklas       printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
6652159047fSniklas 	      new_addr, f->value);
6662159047fSniklas #endif
6672159047fSniklas 
6682159047fSniklas       if (f->jump)
6692159047fSniklas 	{
6702159047fSniklas 	  /* Relative address */
6712159047fSniklas 	  new_addr = new_addr - (f->value + 5);
672c074d1c9Sdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
6732159047fSniklas 	  fixup_table += 4;
6742159047fSniklas 	  bfd_put_32 (output_bfd, f->value + 1, fixup_table);
6752159047fSniklas 	  fixup_table += 4;
6762159047fSniklas 	}
6772159047fSniklas       else
6782159047fSniklas 	{
679c074d1c9Sdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
6802159047fSniklas 	  fixup_table += 4;
6812159047fSniklas 	  bfd_put_32 (output_bfd, f->value, fixup_table);
6822159047fSniklas 	  fixup_table += 4;
6832159047fSniklas 	}
6842159047fSniklas       ++fixups_written;
6852159047fSniklas     }
6862159047fSniklas 
6872159047fSniklas   if (linux_hash_table (info)->local_builtins != 0)
6882159047fSniklas     {
6892159047fSniklas       /* Special marker so we know to switch to the other type of fixup */
690c074d1c9Sdrahn       bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
6912159047fSniklas       fixup_table += 4;
692c074d1c9Sdrahn       bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
6932159047fSniklas       fixup_table += 4;
6942159047fSniklas       ++fixups_written;
6952159047fSniklas       for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
6962159047fSniklas 	{
6972159047fSniklas 	  if (! f->builtin)
6982159047fSniklas 	    continue;
6992159047fSniklas 
7002159047fSniklas 	  if (f->h->root.root.type != bfd_link_hash_defined
7012159047fSniklas 	      && f->h->root.root.type != bfd_link_hash_defweak)
7022159047fSniklas 	    {
7032159047fSniklas 	      (*_bfd_error_handler)
704b305b0f1Sespie 		(_("Symbol %s not defined for fixups\n"),
7052159047fSniklas 		 f->h->root.root.root.string);
7062159047fSniklas 	      continue;
7072159047fSniklas 	    }
7082159047fSniklas 
7092159047fSniklas 	  is = f->h->root.root.u.def.section;
7102159047fSniklas 	  section_offset = is->output_section->vma + is->output_offset;
7112159047fSniklas 	  new_addr = f->h->root.root.u.def.value + section_offset;
7122159047fSniklas 
7132159047fSniklas #ifdef LINUX_LINK_DEBUG
7142159047fSniklas 	  printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
7152159047fSniklas 		  new_addr, f->value);
7162159047fSniklas #endif
7172159047fSniklas 
718c074d1c9Sdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
7192159047fSniklas 	  fixup_table += 4;
7202159047fSniklas 	  bfd_put_32 (output_bfd, f->value, fixup_table);
7212159047fSniklas 	  fixup_table += 4;
7222159047fSniklas 	  ++fixups_written;
7232159047fSniklas 	}
7242159047fSniklas   }
7252159047fSniklas 
7262159047fSniklas   if (linux_hash_table (info)->fixup_count != fixups_written)
7272159047fSniklas     {
728b305b0f1Sespie       (*_bfd_error_handler) (_("Warning: fixup count mismatch\n"));
7292159047fSniklas       while (linux_hash_table (info)->fixup_count > fixups_written)
7302159047fSniklas 	{
731c074d1c9Sdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
7322159047fSniklas 	  fixup_table += 4;
733c074d1c9Sdrahn 	  bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
7342159047fSniklas 	  fixup_table += 4;
7352159047fSniklas 	  ++fixups_written;
7362159047fSniklas 	}
7372159047fSniklas     }
7382159047fSniklas 
7392159047fSniklas   h = linux_link_hash_lookup (linux_hash_table (info),
7402159047fSniklas 			      "__BUILTIN_FIXUPS__",
741c074d1c9Sdrahn 			      FALSE, FALSE, FALSE);
7422159047fSniklas 
7432159047fSniklas   if (h != NULL
7442159047fSniklas       && (h->root.root.type == bfd_link_hash_defined
7452159047fSniklas 	  || h->root.root.type == bfd_link_hash_defweak))
7462159047fSniklas     {
7472159047fSniklas       is = h->root.root.u.def.section;
7482159047fSniklas       section_offset = is->output_section->vma + is->output_offset;
7492159047fSniklas       new_addr = h->root.root.u.def.value + section_offset;
7502159047fSniklas 
7512159047fSniklas #ifdef LINUX_LINK_DEBUG
7522159047fSniklas       printf ("Builtin fixup table at %x\n", new_addr);
7532159047fSniklas #endif
7542159047fSniklas 
755c074d1c9Sdrahn       bfd_put_32 (output_bfd, (bfd_vma) new_addr, fixup_table);
7562159047fSniklas     }
7572159047fSniklas   else
758c074d1c9Sdrahn     bfd_put_32 (output_bfd, (bfd_vma) 0, fixup_table);
7592159047fSniklas 
760c074d1c9Sdrahn   if (bfd_seek (output_bfd, (file_ptr) (os->filepos + s->output_offset),
761c074d1c9Sdrahn 		SEEK_SET) != 0)
762c074d1c9Sdrahn     return FALSE;
7632159047fSniklas 
764c074d1c9Sdrahn   if (bfd_bwrite ((PTR) s->contents, s->_raw_size, output_bfd) != s->_raw_size)
765c074d1c9Sdrahn     return FALSE;
7662159047fSniklas 
767c074d1c9Sdrahn   return TRUE;
7682159047fSniklas }
7692159047fSniklas 
7702159047fSniklas #define MY_bfd_link_hash_table_create linux_link_hash_table_create
7712159047fSniklas #define MY_add_one_symbol linux_add_one_symbol
7722159047fSniklas #define MY_finish_dynamic_link linux_finish_dynamic_link
7732159047fSniklas 
7742159047fSniklas #define MY_zmagic_contiguous 1
7752159047fSniklas 
7762159047fSniklas #include "aout-target.h"
777