i386linux.c revision 33965
133965Sjdp/* BFD back-end for linux flavored i386 a.out binaries.
233965Sjdp   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
333965Sjdp
433965SjdpThis file is part of BFD, the Binary File Descriptor library.
533965Sjdp
633965SjdpThis program is free software; you can redistribute it and/or modify
733965Sjdpit under the terms of the GNU General Public License as published by
833965Sjdpthe Free Software Foundation; either version 2 of the License, or
933965Sjdp(at your option) any later version.
1033965Sjdp
1133965SjdpThis program is distributed in the hope that it will be useful,
1233965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1333965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1433965SjdpGNU General Public License for more details.
1533965Sjdp
1633965SjdpYou should have received a copy of the GNU General Public License
1733965Sjdpalong with this program; if not, write to the Free Software
1833965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1933965Sjdp
2033965Sjdp#define	TARGET_PAGE_SIZE	4096
2133965Sjdp#define ZMAGIC_DISK_BLOCK_SIZE 1024
2233965Sjdp#define	SEGMENT_SIZE TARGET_PAGE_SIZE
2333965Sjdp#define TEXT_START_ADDR	0x0
2433965Sjdp#define N_SHARED_LIB(x) 0
2533965Sjdp#define BYTES_IN_WORD 4
2633965Sjdp
2733965Sjdp#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN)
2833965Sjdp
2933965Sjdp#include "bfd.h"
3033965Sjdp#include "sysdep.h"
3133965Sjdp#include "libbfd.h"
3233965Sjdp#include "aout/aout64.h"
3333965Sjdp#include "aout/stab_gnu.h"
3433965Sjdp#include "aout/ar.h"
3533965Sjdp#include "libaout.h"           /* BFD a.out internal data structures */
3633965Sjdp
3733965Sjdp#define DEFAULT_ARCH bfd_arch_i386
3833965Sjdp#define MY(OP) CAT(i386linux_,OP)
3933965Sjdp#define TARGETNAME "a.out-i386-linux"
4033965Sjdp
4133965Sjdpextern const bfd_target MY(vec);
4233965Sjdp
4333965Sjdp/* We always generate QMAGIC files in preference to ZMAGIC files.  It
4433965Sjdp   would be possible to make this a linker option, if that ever
4533965Sjdp   becomes important.  */
4633965Sjdp
4733965Sjdpstatic void MY_final_link_callback
4833965Sjdp  PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
4933965Sjdpstatic boolean i386linux_bfd_final_link
5033965Sjdp  PARAMS ((bfd *, struct bfd_link_info *));
5133965Sjdpstatic boolean i386linux_write_object_contents PARAMS ((bfd *));
5233965Sjdp
5333965Sjdpstatic boolean
5433965Sjdpi386linux_bfd_final_link (abfd, info)
5533965Sjdp     bfd *abfd;
5633965Sjdp     struct bfd_link_info *info;
5733965Sjdp{
5833965Sjdp  obj_aout_subformat (abfd) = q_magic_format;
5933965Sjdp  return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
6033965Sjdp}
6133965Sjdp
6233965Sjdp#define MY_bfd_final_link i386linux_bfd_final_link
6333965Sjdp
6433965Sjdp/* Set the machine type correctly.  */
6533965Sjdp
6633965Sjdpstatic boolean
6733965Sjdpi386linux_write_object_contents (abfd)
6833965Sjdp     bfd *abfd;
6933965Sjdp{
7033965Sjdp  struct external_exec exec_bytes;
7133965Sjdp  struct internal_exec *execp = exec_hdr (abfd);
7233965Sjdp
7333965Sjdp  N_SET_MACHTYPE (*execp, M_386);
7433965Sjdp
7533965Sjdp  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
7633965Sjdp
7733965Sjdp  WRITE_HEADERS(abfd, execp);
7833965Sjdp
7933965Sjdp  return true;
8033965Sjdp}
8133965Sjdp
8233965Sjdp#define MY_write_object_contents i386linux_write_object_contents
8333965Sjdp
8433965Sjdp/* Code to link against Linux a.out shared libraries.  */
8533965Sjdp
8633965Sjdp/* See if a symbol name is a reference to the global offset table.  */
8733965Sjdp
8833965Sjdp#ifndef GOT_REF_PREFIX
8933965Sjdp#define	GOT_REF_PREFIX	"__GOT_"
9033965Sjdp#endif
9133965Sjdp
9233965Sjdp#define IS_GOT_SYM(name) \
9333965Sjdp  (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0)
9433965Sjdp
9533965Sjdp/* See if a symbol name is a reference to the procedure linkage table.  */
9633965Sjdp
9733965Sjdp#ifndef PLT_REF_PREFIX
9833965Sjdp#define	PLT_REF_PREFIX	"__PLT_"
9933965Sjdp#endif
10033965Sjdp
10133965Sjdp#define IS_PLT_SYM(name) \
10233965Sjdp  (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0)
10333965Sjdp
10433965Sjdp/* This string is used to generate specialized error messages.  */
10533965Sjdp
10633965Sjdp#ifndef NEEDS_SHRLIB
10733965Sjdp#define NEEDS_SHRLIB "__NEEDS_SHRLIB_"
10833965Sjdp#endif
10933965Sjdp
11033965Sjdp/* This special symbol is a set vector that contains a list of
11133965Sjdp   pointers to fixup tables.  It will be present in any dynamicly
11233965Sjdp   linked file.  The linker generated fixup table should also be added
11333965Sjdp   to the list, and it should always appear in the second slot (the
11433965Sjdp   first one is a dummy with a magic number that is defined in
11533965Sjdp   crt0.o).  */
11633965Sjdp
11733965Sjdp#ifndef SHARABLE_CONFLICTS
11833965Sjdp#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__"
11933965Sjdp#endif
12033965Sjdp
12133965Sjdp/* We keep a list of fixups.  The terminology is a bit strange, but
12233965Sjdp   each fixup contains two 32 bit numbers.  A regular fixup contains
12333965Sjdp   an address and a pointer, and at runtime we should store the
12433965Sjdp   address at the location pointed to by the pointer.  A builtin fixup
12533965Sjdp   contains two pointers, and we should read the address using one
12633965Sjdp   pointer and store it at the location pointed to by the other
12733965Sjdp   pointer.  Builtin fixups come into play when we have duplicate
12833965Sjdp   __GOT__ symbols for the same variable.  The builtin fixup will copy
12933965Sjdp   the GOT pointer from one over into the other.  */
13033965Sjdp
13133965Sjdpstruct fixup
13233965Sjdp{
13333965Sjdp  struct fixup *next;
13433965Sjdp  struct linux_link_hash_entry *h;
13533965Sjdp  bfd_vma value;
13633965Sjdp
13733965Sjdp  /* Nonzero if this is a jump instruction that needs to be fixed,
13833965Sjdp     zero if this is just a pointer */
13933965Sjdp  char jump;
14033965Sjdp
14133965Sjdp  char builtin;
14233965Sjdp};
14333965Sjdp
14433965Sjdp/* We don't need a special hash table entry structure, but we do need
14533965Sjdp   to keep some information between linker passes, so we use a special
14633965Sjdp   hash table.  */
14733965Sjdp
14833965Sjdpstruct linux_link_hash_entry
14933965Sjdp{
15033965Sjdp  struct aout_link_hash_entry root;
15133965Sjdp};
15233965Sjdp
15333965Sjdpstruct linux_link_hash_table
15433965Sjdp{
15533965Sjdp  struct aout_link_hash_table root;
15633965Sjdp
15733965Sjdp  /* First dynamic object found in link.  */
15833965Sjdp  bfd *dynobj;
15933965Sjdp
16033965Sjdp  /* Number of fixups.  */
16133965Sjdp  size_t fixup_count;
16233965Sjdp
16333965Sjdp  /* Number of builtin fixups.  */
16433965Sjdp  size_t local_builtins;
16533965Sjdp
16633965Sjdp  /* List of fixups.  */
16733965Sjdp  struct fixup *fixup_list;
16833965Sjdp};
16933965Sjdp
17033965Sjdpstatic struct bfd_hash_entry *linux_link_hash_newfunc
17133965Sjdp  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
17233965Sjdpstatic struct bfd_link_hash_table *linux_link_hash_table_create
17333965Sjdp  PARAMS ((bfd *));
17433965Sjdpstatic struct fixup *new_fixup
17533965Sjdp  PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *,
17633965Sjdp	   bfd_vma, int));
17733965Sjdpstatic boolean linux_link_create_dynamic_sections
17833965Sjdp  PARAMS ((bfd *, struct bfd_link_info *));
17933965Sjdpstatic boolean linux_add_one_symbol
18033965Sjdp  PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
18133965Sjdp	   bfd_vma, const char *, boolean, boolean,
18233965Sjdp	   struct bfd_link_hash_entry **));
18333965Sjdpstatic boolean linux_tally_symbols
18433965Sjdp  PARAMS ((struct linux_link_hash_entry *, PTR));
18533965Sjdpstatic boolean linux_finish_dynamic_link
18633965Sjdp  PARAMS ((bfd *, struct bfd_link_info *));
18733965Sjdp
18833965Sjdp/* Routine to create an entry in an Linux link hash table.  */
18933965Sjdp
19033965Sjdpstatic struct bfd_hash_entry *
19133965Sjdplinux_link_hash_newfunc (entry, table, string)
19233965Sjdp     struct bfd_hash_entry *entry;
19333965Sjdp     struct bfd_hash_table *table;
19433965Sjdp     const char *string;
19533965Sjdp{
19633965Sjdp  struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry;
19733965Sjdp
19833965Sjdp  /* Allocate the structure if it has not already been allocated by a
19933965Sjdp     subclass.  */
20033965Sjdp  if (ret == (struct linux_link_hash_entry *) NULL)
20133965Sjdp    ret = ((struct linux_link_hash_entry *)
20233965Sjdp	   bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry)));
20333965Sjdp  if (ret == NULL)
20433965Sjdp    return (struct bfd_hash_entry *) ret;
20533965Sjdp
20633965Sjdp  /* Call the allocation method of the superclass.  */
20733965Sjdp  ret = ((struct linux_link_hash_entry *)
20833965Sjdp	 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
20933965Sjdp				       table, string));
21033965Sjdp  if (ret != NULL)
21133965Sjdp    {
21233965Sjdp      /* Set local fields; there aren't any.  */
21333965Sjdp    }
21433965Sjdp
21533965Sjdp  return (struct bfd_hash_entry *) ret;
21633965Sjdp}
21733965Sjdp
21833965Sjdp/* Create a Linux link hash table.  */
21933965Sjdp
22033965Sjdpstatic struct bfd_link_hash_table *
22133965Sjdplinux_link_hash_table_create (abfd)
22233965Sjdp     bfd *abfd;
22333965Sjdp{
22433965Sjdp  struct linux_link_hash_table *ret;
22533965Sjdp
22633965Sjdp  ret = ((struct linux_link_hash_table *)
22733965Sjdp	 bfd_alloc (abfd, sizeof (struct linux_link_hash_table)));
22833965Sjdp  if (ret == (struct linux_link_hash_table *) NULL)
22933965Sjdp    return (struct bfd_link_hash_table *) NULL;
23033965Sjdp  if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
23133965Sjdp					 linux_link_hash_newfunc))
23233965Sjdp    {
23333965Sjdp      free (ret);
23433965Sjdp      return (struct bfd_link_hash_table *) NULL;
23533965Sjdp    }
23633965Sjdp
23733965Sjdp  ret->dynobj = NULL;
23833965Sjdp  ret->fixup_count = 0;
23933965Sjdp  ret->local_builtins = 0;
24033965Sjdp  ret->fixup_list = NULL;
24133965Sjdp
24233965Sjdp  return &ret->root.root;
24333965Sjdp}
24433965Sjdp
24533965Sjdp/* Look up an entry in a Linux link hash table.  */
24633965Sjdp
24733965Sjdp#define linux_link_hash_lookup(table, string, create, copy, follow) \
24833965Sjdp  ((struct linux_link_hash_entry *) \
24933965Sjdp   aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
25033965Sjdp			  (follow)))
25133965Sjdp
25233965Sjdp/* Traverse a Linux link hash table.  */
25333965Sjdp
25433965Sjdp#define linux_link_hash_traverse(table, func, info)			\
25533965Sjdp  (aout_link_hash_traverse						\
25633965Sjdp   (&(table)->root,							\
25733965Sjdp    (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func),	\
25833965Sjdp    (info)))
25933965Sjdp
26033965Sjdp/* Get the Linux link hash table from the info structure.  This is
26133965Sjdp   just a cast.  */
26233965Sjdp
26333965Sjdp#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash))
26433965Sjdp
26533965Sjdp/* Store the information for a new fixup.  */
26633965Sjdp
26733965Sjdpstatic struct fixup *
26833965Sjdpnew_fixup (info, h, value, builtin)
26933965Sjdp     struct bfd_link_info *info;
27033965Sjdp     struct linux_link_hash_entry *h;
27133965Sjdp     bfd_vma value;
27233965Sjdp     int builtin;
27333965Sjdp{
27433965Sjdp  struct fixup *f;
27533965Sjdp
27633965Sjdp  f = (struct fixup *) bfd_hash_allocate (&info->hash->table,
27733965Sjdp					  sizeof (struct fixup));
27833965Sjdp  if (f == NULL)
27933965Sjdp    return f;
28033965Sjdp  f->next = linux_hash_table (info)->fixup_list;
28133965Sjdp  linux_hash_table (info)->fixup_list = f;
28233965Sjdp  f->h = h;
28333965Sjdp  f->value = value;
28433965Sjdp  f->builtin = builtin;
28533965Sjdp  f->jump = 0;
28633965Sjdp  ++linux_hash_table (info)->fixup_count;
28733965Sjdp  return f;
28833965Sjdp}
28933965Sjdp
29033965Sjdp/* We come here once we realize that we are going to link to a shared
29133965Sjdp   library.  We need to create a special section that contains the
29233965Sjdp   fixup table, and we ultimately need to add a pointer to this into
29333965Sjdp   the set vector for SHARABLE_CONFLICTS.  At this point we do not
29433965Sjdp   know the size of the section, but that's OK - we just need to
29533965Sjdp   create it for now.  */
29633965Sjdp
29733965Sjdpstatic boolean
29833965Sjdplinux_link_create_dynamic_sections (abfd, info)
29933965Sjdp     bfd *abfd;
30033965Sjdp     struct bfd_link_info *info;
30133965Sjdp{
30233965Sjdp  flagword flags;
30333965Sjdp  register asection *s;
30433965Sjdp
30533965Sjdp  /* Note that we set the SEC_IN_MEMORY flag.  */
30633965Sjdp  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
30733965Sjdp
30833965Sjdp  /* We choose to use the name ".linux-dynamic" for the fixup table.
30933965Sjdp     Why not? */
31033965Sjdp  s = bfd_make_section (abfd, ".linux-dynamic");
31133965Sjdp  if (s == NULL
31233965Sjdp      || ! bfd_set_section_flags (abfd, s, flags)
31333965Sjdp      || ! bfd_set_section_alignment (abfd, s, 2))
31433965Sjdp    return false;
31533965Sjdp  s->_raw_size = 0;
31633965Sjdp  s->contents = 0;
31733965Sjdp
31833965Sjdp  return true;
31933965Sjdp}
32033965Sjdp
32133965Sjdp/* Function to add a single symbol to the linker hash table.  This is
32233965Sjdp   a wrapper around _bfd_generic_link_add_one_symbol which handles the
32333965Sjdp   tweaking needed for dynamic linking support.  */
32433965Sjdp
32533965Sjdpstatic boolean
32633965Sjdplinux_add_one_symbol (info, abfd, name, flags, section, value, string,
32733965Sjdp		      copy, collect, hashp)
32833965Sjdp     struct bfd_link_info *info;
32933965Sjdp     bfd *abfd;
33033965Sjdp     const char *name;
33133965Sjdp     flagword flags;
33233965Sjdp     asection *section;
33333965Sjdp     bfd_vma value;
33433965Sjdp     const char *string;
33533965Sjdp     boolean copy;
33633965Sjdp     boolean collect;
33733965Sjdp     struct bfd_link_hash_entry **hashp;
33833965Sjdp{
33933965Sjdp  struct linux_link_hash_entry *h;
34033965Sjdp  boolean insert;
34133965Sjdp
34233965Sjdp  /* Look up and see if we already have this symbol in the hash table.
34333965Sjdp     If we do, and the defining entry is from a shared library, we
34433965Sjdp     need to create the dynamic sections.
34533965Sjdp
34633965Sjdp     FIXME: What if abfd->xvec != info->hash->creator?  We may want to
34733965Sjdp     be able to link Linux a.out and ELF objects together, but serious
34833965Sjdp     confusion is possible.  */
34933965Sjdp
35033965Sjdp  insert = false;
35133965Sjdp
35233965Sjdp  if (! info->relocateable
35333965Sjdp      && linux_hash_table (info)->dynobj == NULL
35433965Sjdp      && strcmp (name, SHARABLE_CONFLICTS) == 0
35533965Sjdp      && (flags & BSF_CONSTRUCTOR) != 0
35633965Sjdp      && abfd->xvec == info->hash->creator)
35733965Sjdp    {
35833965Sjdp      if (! linux_link_create_dynamic_sections (abfd, info))
35933965Sjdp	return false;
36033965Sjdp      linux_hash_table (info)->dynobj = abfd;
36133965Sjdp      insert = true;
36233965Sjdp    }
36333965Sjdp
36433965Sjdp  if (bfd_is_abs_section (section)
36533965Sjdp      && abfd->xvec == info->hash->creator)
36633965Sjdp    {
36733965Sjdp      h = linux_link_hash_lookup (linux_hash_table (info), name, false,
36833965Sjdp				  false, false);
36933965Sjdp      if (h != NULL
37033965Sjdp	  && (h->root.root.type == bfd_link_hash_defined
37133965Sjdp	      || h->root.root.type == bfd_link_hash_defweak))
37233965Sjdp	{
37333965Sjdp	  struct fixup *f;
37433965Sjdp
37533965Sjdp	  if (hashp != NULL)
37633965Sjdp	    *hashp = (struct bfd_link_hash_entry *) h;
37733965Sjdp
37833965Sjdp	  f = new_fixup (info, h, value, ! IS_PLT_SYM (name));
37933965Sjdp	  if (f == NULL)
38033965Sjdp	    return false;
38133965Sjdp	  f->jump = IS_PLT_SYM (name);
38233965Sjdp
38333965Sjdp	  return true;
38433965Sjdp	}
38533965Sjdp    }
38633965Sjdp
38733965Sjdp  /* Do the usual procedure for adding a symbol.  */
38833965Sjdp  if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
38933965Sjdp					  value, string, copy, collect,
39033965Sjdp					  hashp))
39133965Sjdp    return false;
39233965Sjdp
39333965Sjdp  /* Insert a pointer to our table in the set vector.  The dynamic
39433965Sjdp     linker requires this information */
39533965Sjdp  if (insert)
39633965Sjdp    {
39733965Sjdp      asection *s;
39833965Sjdp
39933965Sjdp      /* Here we do our special thing to add the pointer to the
40033965Sjdp	 dynamic section in the SHARABLE_CONFLICTS set vector.  */
40133965Sjdp      s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
40233965Sjdp				   ".linux-dynamic");
40333965Sjdp      BFD_ASSERT (s != NULL);
40433965Sjdp
40533965Sjdp      if (! (_bfd_generic_link_add_one_symbol
40633965Sjdp	     (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS,
40733965Sjdp	      BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL)))
40833965Sjdp	return false;
40933965Sjdp    }
41033965Sjdp
41133965Sjdp  return true;
41233965Sjdp}
41333965Sjdp
41433965Sjdp/* We will crawl the hash table and come here for every global symbol.
41533965Sjdp   We will examine each entry and see if there are indications that we
41633965Sjdp   need to add a fixup.  There are two possible cases - one is where
41733965Sjdp   you have duplicate definitions of PLT or GOT symbols - these will
41833965Sjdp   have already been caught and added as "builtin" fixups.  If we find
41933965Sjdp   that the corresponding non PLT/GOT symbol is also present, we
42033965Sjdp   convert it to a regular fixup instead.
42133965Sjdp
42233965Sjdp   This function is called via linux_link_hash_traverse.  */
42333965Sjdp
42433965Sjdpstatic boolean
42533965Sjdplinux_tally_symbols (h, data)
42633965Sjdp     struct linux_link_hash_entry *h;
42733965Sjdp     PTR data;
42833965Sjdp{
42933965Sjdp  struct bfd_link_info *info = (struct bfd_link_info *) data;
43033965Sjdp  struct fixup *f, *f1;
43133965Sjdp  int is_plt;
43233965Sjdp  struct linux_link_hash_entry *h1, *h2;
43333965Sjdp  boolean exists;
43433965Sjdp
43533965Sjdp  if (h->root.root.type == bfd_link_hash_undefined
43633965Sjdp      && strncmp (h->root.root.root.string, NEEDS_SHRLIB,
43733965Sjdp		  sizeof NEEDS_SHRLIB - 1) == 0)
43833965Sjdp    {
43933965Sjdp      const char *name;
44033965Sjdp      char *p;
44133965Sjdp      char *alloc = NULL;
44233965Sjdp
44333965Sjdp      name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1;
44433965Sjdp      p = strrchr (name, '_');
44533965Sjdp      if (p != NULL)
44633965Sjdp	alloc = (char *) bfd_malloc (strlen (name) + 1);
44733965Sjdp
44833965Sjdp      if (p == NULL || alloc == NULL)
44933965Sjdp	(*_bfd_error_handler) ("Output file requires shared library `%s'\n",
45033965Sjdp			       name);
45133965Sjdp      else
45233965Sjdp	{
45333965Sjdp	  strcpy (alloc, name);
45433965Sjdp	  p = strrchr (alloc, '_');
45533965Sjdp	  *p++ = '\0';
45633965Sjdp	  (*_bfd_error_handler)
45733965Sjdp	    ("Output file requires shared library `%s.so.%s'\n",
45833965Sjdp	     alloc, p);
45933965Sjdp	  free (alloc);
46033965Sjdp	}
46133965Sjdp
46233965Sjdp      abort ();
46333965Sjdp    }
46433965Sjdp
46533965Sjdp  /* If this symbol is not a PLT/GOT, we do not even need to look at it */
46633965Sjdp  is_plt = IS_PLT_SYM (h->root.root.root.string);
46733965Sjdp
46833965Sjdp  if (is_plt || IS_GOT_SYM (h->root.root.root.string))
46933965Sjdp    {
47033965Sjdp      /* Look up this symbol twice.  Once just as a regular lookup,
47133965Sjdp	 and then again following all of the indirect links until we
47233965Sjdp	 reach a real symbol.  */
47333965Sjdp      h1 = linux_link_hash_lookup (linux_hash_table (info),
47433965Sjdp				   (h->root.root.root.string
47533965Sjdp				    + sizeof PLT_REF_PREFIX - 1),
47633965Sjdp				   false, false, true);
47733965Sjdp      /* h2 does not follow indirect symbols. */
47833965Sjdp      h2 = linux_link_hash_lookup (linux_hash_table (info),
47933965Sjdp				   (h->root.root.root.string
48033965Sjdp				    + sizeof PLT_REF_PREFIX - 1),
48133965Sjdp				   false, false, false);
48233965Sjdp
48333965Sjdp      /* The real symbol must exist but if it is also an ABS symbol,
48433965Sjdp	 there is no need to have a fixup.  This is because they both
48533965Sjdp	 came from the same library.  If on the other hand, we had to
48633965Sjdp	 use an indirect symbol to get to the real symbol, we add the
48733965Sjdp	 fixup anyway, since there are cases where these symbols come
48833965Sjdp	 from different shared libraries */
48933965Sjdp      if (h1 != NULL
49033965Sjdp	  && (((h1->root.root.type == bfd_link_hash_defined
49133965Sjdp		|| h1->root.root.type == bfd_link_hash_defweak)
49233965Sjdp	       && ! bfd_is_abs_section (h1->root.root.u.def.section))
49333965Sjdp	      || h2->root.root.type == bfd_link_hash_indirect))
49433965Sjdp	{
49533965Sjdp	  /* See if there is a "builtin" fixup already present
49633965Sjdp	     involving this symbol.  If so, convert it to a regular
49733965Sjdp	     fixup.  In the end, this relaxes some of the requirements
49833965Sjdp	     about the order of performing fixups.  */
49933965Sjdp	  exists = false;
50033965Sjdp	  for (f1 = linux_hash_table (info)->fixup_list;
50133965Sjdp	       f1 != NULL;
50233965Sjdp	       f1 = f1->next)
50333965Sjdp	    {
50433965Sjdp	      if ((f1->h != h && f1->h != h1)
50533965Sjdp		  || (! f1->builtin && ! f1->jump))
50633965Sjdp		continue;
50733965Sjdp	      if (f1->h == h1)
50833965Sjdp		exists = true;
50933965Sjdp	      if (! exists
51033965Sjdp		  && bfd_is_abs_section (h->root.root.u.def.section))
51133965Sjdp		{
51233965Sjdp		  f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0);
51333965Sjdp		  f->jump = is_plt;
51433965Sjdp		}
51533965Sjdp	      f1->h = h1;
51633965Sjdp	      f1->jump = is_plt;
51733965Sjdp	      f1->builtin = 0;
51833965Sjdp	      exists = true;
51933965Sjdp	    }
52033965Sjdp	  if (! exists
52133965Sjdp	      && bfd_is_abs_section (h->root.root.u.def.section))
52233965Sjdp	    {
52333965Sjdp	      f = new_fixup (info, h1, h->root.root.u.def.value, 0);
52433965Sjdp	      if (f == NULL)
52533965Sjdp		{
52633965Sjdp		  /* FIXME: No way to return error.  */
52733965Sjdp		  abort ();
52833965Sjdp		}
52933965Sjdp	      f->jump = is_plt;
53033965Sjdp	    }
53133965Sjdp	}
53233965Sjdp
53333965Sjdp      /* Quick and dirty way of stripping these symbols from the
53433965Sjdp	 symtab. */
53533965Sjdp      if (bfd_is_abs_section (h->root.root.u.def.section))
53633965Sjdp	h->root.written = true;
53733965Sjdp    }
53833965Sjdp
53933965Sjdp  return true;
54033965Sjdp}
54133965Sjdp
54233965Sjdp/* This is called to set the size of the .linux-dynamic section is.
54333965Sjdp   It is called by the Linux linker emulation before_allocation
54433965Sjdp   routine.  We have finished reading all of the input files, and now
54533965Sjdp   we just scan the hash tables to find out how many additional fixups
54633965Sjdp   are required.  */
54733965Sjdp
54833965Sjdpboolean
54933965Sjdpbfd_i386linux_size_dynamic_sections (output_bfd, info)
55033965Sjdp     bfd *output_bfd;
55133965Sjdp     struct bfd_link_info *info;
55233965Sjdp{
55333965Sjdp  struct fixup *f;
55433965Sjdp  asection *s;
55533965Sjdp
55633965Sjdp  if (output_bfd->xvec != &MY(vec))
55733965Sjdp    return true;
55833965Sjdp
55933965Sjdp  /* First find the fixups... */
56033965Sjdp  linux_link_hash_traverse (linux_hash_table (info),
56133965Sjdp			    linux_tally_symbols,
56233965Sjdp			    (PTR) info);
56333965Sjdp
56433965Sjdp  /* If there are builtin fixups, leave room for a marker.  This is
56533965Sjdp     used by the dynamic linker so that it knows that all that follow
56633965Sjdp     are builtin fixups instead of regular fixups.  */
56733965Sjdp  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
56833965Sjdp    {
56933965Sjdp      if (f->builtin)
57033965Sjdp	{
57133965Sjdp	  ++linux_hash_table (info)->fixup_count;
57233965Sjdp	  ++linux_hash_table (info)->local_builtins;
57333965Sjdp	  break;
57433965Sjdp	}
57533965Sjdp    }
57633965Sjdp
57733965Sjdp  if (linux_hash_table (info)->dynobj == NULL)
57833965Sjdp    {
57933965Sjdp      if (linux_hash_table (info)->fixup_count > 0)
58033965Sjdp	abort ();
58133965Sjdp      return true;
58233965Sjdp    }
58333965Sjdp
58433965Sjdp  /* Allocate memory for our fixup table.  We will fill it in later.  */
58533965Sjdp  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
58633965Sjdp			       ".linux-dynamic");
58733965Sjdp  if (s != NULL)
58833965Sjdp    {
58933965Sjdp      s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8;
59033965Sjdp      s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
59133965Sjdp      if (s->contents == NULL)
59233965Sjdp	return false;
59333965Sjdp      memset (s->contents, 0, (size_t) s->_raw_size);
59433965Sjdp    }
59533965Sjdp
59633965Sjdp  return true;
59733965Sjdp}
59833965Sjdp
59933965Sjdp/* We come here once we are ready to actually write the fixup table to
60033965Sjdp   the output file.  Scan the fixup tables and so forth and generate
60133965Sjdp   the stuff we need.  */
60233965Sjdp
60333965Sjdpstatic boolean
60433965Sjdplinux_finish_dynamic_link (output_bfd, info)
60533965Sjdp     bfd *output_bfd;
60633965Sjdp     struct bfd_link_info *info;
60733965Sjdp{
60833965Sjdp  asection *s, *os, *is;
60933965Sjdp  bfd_byte *fixup_table;
61033965Sjdp  struct linux_link_hash_entry *h;
61133965Sjdp  struct fixup *f;
61233965Sjdp  unsigned int new_addr;
61333965Sjdp  int section_offset;
61433965Sjdp  unsigned int fixups_written;
61533965Sjdp
61633965Sjdp  if (linux_hash_table (info)->dynobj == NULL)
61733965Sjdp    return true;
61833965Sjdp
61933965Sjdp  s = bfd_get_section_by_name (linux_hash_table (info)->dynobj,
62033965Sjdp			       ".linux-dynamic");
62133965Sjdp  BFD_ASSERT (s != NULL);
62233965Sjdp  os = s->output_section;
62333965Sjdp  fixups_written = 0;
62433965Sjdp
62533965Sjdp#ifdef LINUX_LINK_DEBUG
62633965Sjdp  printf ("Fixup table file offset: %x  VMA: %x\n",
62733965Sjdp	  os->filepos + s->output_offset,
62833965Sjdp	  os->vma + s->output_offset);
62933965Sjdp#endif
63033965Sjdp
63133965Sjdp  fixup_table = s->contents;
63233965Sjdp  bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table);
63333965Sjdp  fixup_table += 4;
63433965Sjdp
63533965Sjdp  /* Fill in fixup table.  */
63633965Sjdp  for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
63733965Sjdp    {
63833965Sjdp      if (f->builtin)
63933965Sjdp	continue;
64033965Sjdp
64133965Sjdp      if (f->h->root.root.type != bfd_link_hash_defined
64233965Sjdp	  && f->h->root.root.type != bfd_link_hash_defweak)
64333965Sjdp	{
64433965Sjdp	  (*_bfd_error_handler)
64533965Sjdp	    ("Symbol %s not defined for fixups\n",
64633965Sjdp	     f->h->root.root.root.string);
64733965Sjdp	  continue;
64833965Sjdp	}
64933965Sjdp
65033965Sjdp      is = f->h->root.root.u.def.section;
65133965Sjdp      section_offset = is->output_section->vma + is->output_offset;
65233965Sjdp      new_addr = f->h->root.root.u.def.value + section_offset;
65333965Sjdp
65433965Sjdp#ifdef LINUX_LINK_DEBUG
65533965Sjdp      printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string,
65633965Sjdp	      new_addr, f->value);
65733965Sjdp#endif
65833965Sjdp
65933965Sjdp      if (f->jump)
66033965Sjdp	{
66133965Sjdp	  /* Relative address */
66233965Sjdp	  new_addr = new_addr - (f->value + 5);
66333965Sjdp	  bfd_put_32 (output_bfd, new_addr, fixup_table);
66433965Sjdp	  fixup_table += 4;
66533965Sjdp	  bfd_put_32 (output_bfd, f->value + 1, fixup_table);
66633965Sjdp	  fixup_table += 4;
66733965Sjdp	}
66833965Sjdp      else
66933965Sjdp	{
67033965Sjdp	  bfd_put_32 (output_bfd, new_addr, fixup_table);
67133965Sjdp	  fixup_table += 4;
67233965Sjdp	  bfd_put_32 (output_bfd, f->value, fixup_table);
67333965Sjdp	  fixup_table += 4;
67433965Sjdp	}
67533965Sjdp      ++fixups_written;
67633965Sjdp    }
67733965Sjdp
67833965Sjdp  if (linux_hash_table (info)->local_builtins != 0)
67933965Sjdp    {
68033965Sjdp      /* Special marker so we know to switch to the other type of fixup */
68133965Sjdp      bfd_put_32 (output_bfd, 0, fixup_table);
68233965Sjdp      fixup_table += 4;
68333965Sjdp      bfd_put_32 (output_bfd, 0, fixup_table);
68433965Sjdp      fixup_table += 4;
68533965Sjdp      ++fixups_written;
68633965Sjdp      for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next)
68733965Sjdp	{
68833965Sjdp	  if (! f->builtin)
68933965Sjdp	    continue;
69033965Sjdp
69133965Sjdp	  if (f->h->root.root.type != bfd_link_hash_defined
69233965Sjdp	      && f->h->root.root.type != bfd_link_hash_defweak)
69333965Sjdp	    {
69433965Sjdp	      (*_bfd_error_handler)
69533965Sjdp		("Symbol %s not defined for fixups\n",
69633965Sjdp		 f->h->root.root.root.string);
69733965Sjdp	      continue;
69833965Sjdp	    }
69933965Sjdp
70033965Sjdp	  is = f->h->root.root.u.def.section;
70133965Sjdp	  section_offset = is->output_section->vma + is->output_offset;
70233965Sjdp	  new_addr = f->h->root.root.u.def.value + section_offset;
70333965Sjdp
70433965Sjdp#ifdef LINUX_LINK_DEBUG
70533965Sjdp	  printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string,
70633965Sjdp		  new_addr, f->value);
70733965Sjdp#endif
70833965Sjdp
70933965Sjdp	  bfd_put_32 (output_bfd, new_addr, fixup_table);
71033965Sjdp	  fixup_table += 4;
71133965Sjdp	  bfd_put_32 (output_bfd, f->value, fixup_table);
71233965Sjdp	  fixup_table += 4;
71333965Sjdp	  ++fixups_written;
71433965Sjdp	}
71533965Sjdp  }
71633965Sjdp
71733965Sjdp  if (linux_hash_table (info)->fixup_count != fixups_written)
71833965Sjdp    {
71933965Sjdp      (*_bfd_error_handler) ("Warning: fixup count mismatch\n");
72033965Sjdp      while (linux_hash_table (info)->fixup_count > fixups_written)
72133965Sjdp	{
72233965Sjdp	  bfd_put_32 (output_bfd, 0, fixup_table);
72333965Sjdp	  fixup_table += 4;
72433965Sjdp	  bfd_put_32 (output_bfd, 0, fixup_table);
72533965Sjdp	  fixup_table += 4;
72633965Sjdp	  ++fixups_written;
72733965Sjdp	}
72833965Sjdp    }
72933965Sjdp
73033965Sjdp  h = linux_link_hash_lookup (linux_hash_table (info),
73133965Sjdp			      "__BUILTIN_FIXUPS__",
73233965Sjdp			      false, false, false);
73333965Sjdp
73433965Sjdp  if (h != NULL
73533965Sjdp      && (h->root.root.type == bfd_link_hash_defined
73633965Sjdp	  || h->root.root.type == bfd_link_hash_defweak))
73733965Sjdp    {
73833965Sjdp      is = h->root.root.u.def.section;
73933965Sjdp      section_offset = is->output_section->vma + is->output_offset;
74033965Sjdp      new_addr = h->root.root.u.def.value + section_offset;
74133965Sjdp
74233965Sjdp#ifdef LINUX_LINK_DEBUG
74333965Sjdp      printf ("Builtin fixup table at %x\n", new_addr);
74433965Sjdp#endif
74533965Sjdp
74633965Sjdp      bfd_put_32 (output_bfd, new_addr, fixup_table);
74733965Sjdp    }
74833965Sjdp  else
74933965Sjdp    bfd_put_32 (output_bfd, 0, fixup_table);
75033965Sjdp
75133965Sjdp  if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0)
75233965Sjdp    return false;
75333965Sjdp
75433965Sjdp  if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd)
75533965Sjdp      != s->_raw_size)
75633965Sjdp    return false;
75733965Sjdp
75833965Sjdp  return true;
75933965Sjdp}
76033965Sjdp
76133965Sjdp#define MY_bfd_link_hash_table_create linux_link_hash_table_create
76233965Sjdp#define MY_add_one_symbol linux_add_one_symbol
76333965Sjdp#define MY_finish_dynamic_link linux_finish_dynamic_link
76433965Sjdp
76533965Sjdp#define MY_zmagic_contiguous 1
76633965Sjdp
76733965Sjdp#include "aout-target.h"
768