Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Jun 2004 13:31:22 GMT
From:      Juli Mallett <jmallett@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 55088 for review
Message-ID:  <200406161331.i5GDVMEU027608@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=55088

Change 55088 by jmallett@jmallett_oingo on 2004/06/16 13:30:56

	Untested vendor synch of mips bu bits.

Affected files ...

.. //depot/projects/mips/contrib/binutils/bfd/coff-mips.c#8 add
.. //depot/projects/mips/contrib/binutils/bfd/cpu-mips.c#8 add
.. //depot/projects/mips/contrib/binutils/bfd/elf32-mips.c#8 add
.. //depot/projects/mips/contrib/binutils/bfd/elf64-mips.c#8 add
.. //depot/projects/mips/contrib/binutils/bfd/elfn32-mips.c#1 add
.. //depot/projects/mips/contrib/binutils/bfd/elfxx-mips.c#2 edit
.. //depot/projects/mips/contrib/binutils/bfd/elfxx-mips.h#2 edit
.. //depot/projects/mips/contrib/binutils/bfd/pe-mips.c#8 add
.. //depot/projects/mips/contrib/binutils/bfd/pei-mips.c#1 add
.. //depot/projects/mips/contrib/binutils/gas/config/e-mipsecoff.c#2 edit
.. //depot/projects/mips/contrib/binutils/gas/config/e-mipself.c#2 edit
.. //depot/projects/mips/contrib/binutils/gas/config/itbl-mips.h#2 edit
.. //depot/projects/mips/contrib/binutils/gas/config/tc-mips.c#2 edit
.. //depot/projects/mips/contrib/binutils/gas/config/tc-mips.h#2 edit
.. //depot/projects/mips/contrib/binutils/gas/config/te-tmips.h#2 edit
.. //depot/projects/mips/contrib/binutils/gas/doc/c-mips.texi#1 add
.. //depot/projects/mips/contrib/binutils/include/coff/mips.h#2 edit
.. //depot/projects/mips/contrib/binutils/include/elf/mips.h#3 edit
.. //depot/projects/mips/contrib/binutils/include/opcode/mips.h#8 add
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipsbig.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipsbsd.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipsidt.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipsidtl.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipslit.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipslnews.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emulparams/mipspe.sh#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emultempl/mipsecoff.em#2 edit
.. //depot/projects/mips/contrib/binutils/ld/emultempl/mipself.em#2 edit
.. //depot/projects/mips/contrib/binutils/ld/scripttempl/mips.sc#2 edit
.. //depot/projects/mips/contrib/binutils/opcodes/mips-dis.c#2 edit
.. //depot/projects/mips/contrib/binutils/opcodes/mips-opc.c#2 edit
.. //depot/projects/mips/contrib/binutils/opcodes/mips16-opc.c#2 edit

Differences ...

==== //depot/projects/mips/contrib/binutils/bfd/elfxx-mips.c#2 (text+ko) ====

@@ -1,6 +1,6 @@
 /* MIPS-specific support for ELF
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -9,27 +9,28 @@
    Traditional MIPS targets support added by Koundinya.K, Dansk Data
    Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
 
-This file is part of BFD, the Binary File Descriptor library.
+   This file is part of BFD, the Binary File Descriptor library.
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* This file handles functionality common to the different MIPS ABI's.  */
 
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
+#include "libiberty.h"
 #include "elf-bfd.h"
 #include "elfxx-mips.h"
 #include "elf/mips.h"
@@ -40,8 +41,36 @@
 #include "coff/ecoff.h"
 #include "coff/mips.h"
 
-/* This structure is used to hold .got information when linking.  It
-   is stored in the tdata field of the bfd_elf_section_data structure.  */
+#include "hashtab.h"
+
+/* This structure is used to hold .got entries while estimating got
+   sizes.  */
+struct mips_got_entry
+{
+  /* The input bfd in which the symbol is defined.  */
+  bfd *abfd;
+  /* The index of the symbol, as stored in the relocation r_info, if
+     we have a local symbol; -1 otherwise.  */
+  long symndx;
+  union
+  {
+    /* If abfd == NULL, an address that must be stored in the got.  */
+    bfd_vma address;
+    /* If abfd != NULL && symndx != -1, the addend of the relocation
+       that should be added to the symbol value.  */
+    bfd_vma addend;
+    /* If abfd != NULL && symndx == -1, the hash table entry
+       corresponding to a global symbol in the got (or, local, if
+       h->forced_local).  */
+    struct mips_elf_link_hash_entry *h;
+  } d;
+  /* The offset from the beginning of the .got section to the entry
+     corresponding to this symbol+addend.  If it's a global symbol
+     whose offset is yet to be decided, it's going to be -1.  */
+  long gotidx;
+};
+
+/* This structure is used to hold .got information when linking.  */
 
 struct mips_got_info
 {
@@ -54,8 +83,73 @@
   unsigned int local_gotno;
   /* The number of local .got entries we have used.  */
   unsigned int assigned_gotno;
+  /* A hash table holding members of the got.  */
+  struct htab *got_entries;
+  /* A hash table mapping input bfds to other mips_got_info.  NULL
+     unless multi-got was necessary.  */
+  struct htab *bfd2got;
+  /* In multi-got links, a pointer to the next got (err, rather, most
+     of the time, it points to the previous got).  */
+  struct mips_got_info *next;
+};
+
+/* Map an input bfd to a got in a multi-got link.  */
+
+struct mips_elf_bfd2got_hash {
+  bfd *bfd;
+  struct mips_got_info *g;
+};
+
+/* Structure passed when traversing the bfd2got hash table, used to
+   create and merge bfd's gots.  */
+
+struct mips_elf_got_per_bfd_arg
+{
+  /* A hashtable that maps bfds to gots.  */
+  htab_t bfd2got;
+  /* The output bfd.  */
+  bfd *obfd;
+  /* The link information.  */
+  struct bfd_link_info *info;
+  /* A pointer to the primary got, i.e., the one that's going to get
+     the implicit relocations from DT_MIPS_LOCAL_GOTNO and
+     DT_MIPS_GOTSYM.  */
+  struct mips_got_info *primary;
+  /* A non-primary got we're trying to merge with other input bfd's
+     gots.  */
+  struct mips_got_info *current;
+  /* The maximum number of got entries that can be addressed with a
+     16-bit offset.  */
+  unsigned int max_count;
+  /* The number of local and global entries in the primary got.  */
+  unsigned int primary_count;
+  /* The number of local and global entries in the current got.  */
+  unsigned int current_count;
+};
+
+/* Another structure used to pass arguments for got entries traversal.  */
+
+struct mips_elf_set_global_got_offset_arg
+{
+  struct mips_got_info *g;
+  int value;
+  unsigned int needed_relocs;
+  struct bfd_link_info *info;
 };
 
+struct _mips_elf_section_data
+{
+  struct bfd_elf_section_data elf;
+  union
+  {
+    struct mips_got_info *got_info;
+    bfd_byte *tdata;
+  } u;
+};
+
+#define mips_elf_section_data(sec) \
+  ((struct _mips_elf_section_data *) elf_section_data (sec))
+
 /* This structure is passed to mips_elf_sort_hash_table_f when sorting
    the dynamic symbols.  */
 
@@ -67,6 +161,10 @@
   /* The least dynamic symbol table index corresponding to a symbol
      with a GOT entry.  */
   long min_got_dynindx;
+  /* The greatest dynamic symbol table index corresponding to a symbol
+     with a GOT entry that is not referenced (e.g., a dynamic symbol
+     with dynamic relocations pointing to it from non-primary GOTs).  */
+  long max_unref_got_dynindx;
   /* The greatest dynamic symbol table index not corresponding to a
      symbol without a GOT entry.  */
   long max_non_got_dynindx;
@@ -88,17 +186,13 @@
 
   /* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against
      a readonly section.  */
-  boolean readonly_reloc;
+  bfd_boolean readonly_reloc;
 
-  /* The index of the first dynamic relocation (in the .rel.dyn
-     section) against this symbol.  */
-  unsigned int min_dyn_reloc_index;
-
   /* We must not create a stub for a symbol that has relocations
      related to taking the function's address, i.e. any but
      R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition",
      p. 4-20.  */
-  boolean no_fn_stub;
+  bfd_boolean no_fn_stub;
 
   /* If there is a stub that 32 bit functions should use to call this
      16 bit function, this points to the section containing the stub.  */
@@ -106,7 +200,7 @@
 
   /* Whether we need the fn_stub; this is set if this symbol appears
      in any relocs other than a 16 bit call.  */
-  boolean need_fn_stub;
+  bfd_boolean need_fn_stub;
 
   /* If there is a stub that 16 bit functions should use to call this
      32 bit function, this points to the section containing the stub.  */
@@ -117,7 +211,7 @@
   asection *call_fp_stub;
 
   /* Are we forced local?  .*/
-  boolean forced_local;
+  bfd_boolean forced_local;
 };
 
 /* MIPS ELF linker hash table.  */
@@ -136,11 +230,11 @@
   bfd_size_type compact_rel_size;
   /* This flag indicates that the value of DT_MIPS_RLD_MAP dynamic
      entry is set to the address of __rld_obj_head as in IRIX5.  */
-  boolean use_rld_obj_head;
+  bfd_boolean use_rld_obj_head;
   /* This is the value of the __rld_map or __rld_obj_head symbol.  */
   bfd_vma rld_value;
   /* This is set if we see any mips16 stub sections.  */
-  boolean mips16_stubs_seen;
+  bfd_boolean mips16_stubs_seen;
 };
 
 /* Structure used to pass information to mips_elf_output_extsym.  */
@@ -151,7 +245,7 @@
   struct bfd_link_info *info;
   struct ecoff_debug_info *debug;
   const struct ecoff_debug_swap *swap;
-  boolean failed;
+  bfd_boolean failed;
 };
 
 /* The names of the runtime procedure table symbols used on IRIX5.  */
@@ -260,110 +354,153 @@
    loader for use by the static exception system.  */
 
 typedef struct runtime_pdr {
-	bfd_vma	adr;		/* memory address of start of procedure */
-	long	regmask;	/* save register mask */
-	long	regoffset;	/* save register offset */
-	long	fregmask;	/* save floating point register mask */
-	long	fregoffset;	/* save floating point register offset */
-	long	frameoffset;	/* frame size */
-	short	framereg;	/* frame pointer register */
-	short	pcreg;		/* offset or reg of return pc */
-	long	irpss;		/* index into the runtime string table */
+	bfd_vma	adr;		/* Memory address of start of procedure.  */
+	long	regmask;	/* Save register mask.  */
+	long	regoffset;	/* Save register offset.  */
+	long	fregmask;	/* Save floating point register mask.  */
+	long	fregoffset;	/* Save floating point register offset.  */
+	long	frameoffset;	/* Frame size.  */
+	short	framereg;	/* Frame pointer register.  */
+	short	pcreg;		/* Offset or reg of return pc.  */
+	long	irpss;		/* Index into the runtime string table.  */
 	long	reserved;
-	struct exception_info *exception_info;/* pointer to exception array */
+	struct exception_info *exception_info;/* Pointer to exception array.  */
 } RPDR, *pRPDR;
 #define cbRPDR sizeof (RPDR)
 #define rpdNil ((pRPDR) 0)
 
 static struct bfd_hash_entry *mips_elf_link_hash_newfunc
-  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
+  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 static void ecoff_swap_rpdr_out
-  PARAMS ((bfd *, const RPDR *, struct rpdr_ext *));
-static boolean mips_elf_create_procedure_table
-  PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *,
-	   struct ecoff_debug_info *));
-static boolean mips_elf_check_mips16_stubs
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
+  (bfd *, const RPDR *, struct rpdr_ext *);
+static bfd_boolean mips_elf_create_procedure_table
+  (void *, bfd *, struct bfd_link_info *, asection *,
+   struct ecoff_debug_info *);
+static bfd_boolean mips_elf_check_mips16_stubs
+  (struct mips_elf_link_hash_entry *, void *);
 static void bfd_mips_elf32_swap_gptab_in
-  PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));
+  (bfd *, const Elf32_External_gptab *, Elf32_gptab *);
 static void bfd_mips_elf32_swap_gptab_out
-  PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *));
+  (bfd *, const Elf32_gptab *, Elf32_External_gptab *);
 static void bfd_elf32_swap_compact_rel_out
-  PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *));
+  (bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *);
 static void bfd_elf32_swap_crinfo_out
-  PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
-#if 0
-static void bfd_mips_elf_swap_msym_in
-  PARAMS ((bfd *, const Elf32_External_Msym *, Elf32_Internal_Msym *));
-#endif
-static void bfd_mips_elf_swap_msym_out
-  PARAMS ((bfd *, const Elf32_Internal_Msym *, Elf32_External_Msym *));
+  (bfd *, const Elf32_crinfo *, Elf32_External_crinfo *);
 static int sort_dynamic_relocs
-  PARAMS ((const void *, const void *));
-static boolean mips_elf_output_extsym
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
-static int gptab_compare PARAMS ((const void *, const void *));
-static asection * mips_elf_got_section PARAMS ((bfd *));
+  (const void *, const void *);
+static int sort_dynamic_relocs_64
+  (const void *, const void *);
+static bfd_boolean mips_elf_output_extsym
+  (struct mips_elf_link_hash_entry *, void *);
+static int gptab_compare
+  (const void *, const void *);
+static asection *mips_elf_rel_dyn_section
+  (bfd *, bfd_boolean);
+static asection *mips_elf_got_section
+  (bfd *, bfd_boolean);
 static struct mips_got_info *mips_elf_got_info
-  PARAMS ((bfd *, asection **));
+  (bfd *, asection **);
+static long mips_elf_get_global_gotsym_index
+  (bfd *abfd);
 static bfd_vma mips_elf_local_got_index
-  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma);
 static bfd_vma mips_elf_global_got_index
-  PARAMS ((bfd *, struct elf_link_hash_entry *));
+  (bfd *, bfd *, struct elf_link_hash_entry *);
 static bfd_vma mips_elf_got_page
-  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *);
 static bfd_vma mips_elf_got16_entry
-  PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, boolean));
+  (bfd *, bfd *, struct bfd_link_info *, bfd_vma, bfd_boolean);
 static bfd_vma mips_elf_got_offset_from_index
-  PARAMS ((bfd *, bfd *, bfd_vma));
-static bfd_vma mips_elf_create_local_got_entry
-  PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
-static boolean mips_elf_sort_hash_table
-  PARAMS ((struct bfd_link_info *, unsigned long));
-static boolean mips_elf_sort_hash_table_f
-  PARAMS ((struct mips_elf_link_hash_entry *, PTR));
-static boolean mips_elf_record_global_got_symbol
-  PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *,
-	   struct mips_got_info *));
+  (bfd *, bfd *, bfd *, bfd_vma);
+static struct mips_got_entry *mips_elf_create_local_got_entry
+  (bfd *, bfd *, struct mips_got_info *, asection *, bfd_vma);
+static bfd_boolean mips_elf_sort_hash_table
+  (struct bfd_link_info *, unsigned long);
+static bfd_boolean mips_elf_sort_hash_table_f
+  (struct mips_elf_link_hash_entry *, void *);
+static bfd_boolean mips_elf_record_local_got_symbol
+  (bfd *, long, bfd_vma, struct mips_got_info *);
+static bfd_boolean mips_elf_record_global_got_symbol
+  (struct elf_link_hash_entry *, bfd *, struct bfd_link_info *,
+   struct mips_got_info *);
 static const Elf_Internal_Rela *mips_elf_next_relocation
-  PARAMS ((bfd *, unsigned int, const Elf_Internal_Rela *,
-	   const Elf_Internal_Rela *));
-static boolean mips_elf_local_relocation_p
-  PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, boolean));
-static bfd_vma mips_elf_sign_extend PARAMS ((bfd_vma, int));
-static boolean mips_elf_overflow_p PARAMS ((bfd_vma, int));
-static bfd_vma mips_elf_high PARAMS ((bfd_vma));
-static bfd_vma mips_elf_higher PARAMS ((bfd_vma));
-static bfd_vma mips_elf_highest PARAMS ((bfd_vma));
-static boolean mips_elf_create_compact_rel_section
-  PARAMS ((bfd *, struct bfd_link_info *));
-static boolean mips_elf_create_got_section
-  PARAMS ((bfd *, struct bfd_link_info *));
-static asection *mips_elf_create_msym_section
-  PARAMS ((bfd *));
+  (bfd *, unsigned int, const Elf_Internal_Rela *, const Elf_Internal_Rela *);
+static bfd_boolean mips_elf_local_relocation_p
+  (bfd *, const Elf_Internal_Rela *, asection **, bfd_boolean);
+static bfd_boolean mips_elf_overflow_p
+  (bfd_vma, int);
+static bfd_vma mips_elf_high
+  (bfd_vma);
+static bfd_vma mips_elf_higher
+  (bfd_vma);
+static bfd_vma mips_elf_highest
+  (bfd_vma);
+static bfd_boolean mips_elf_create_compact_rel_section
+  (bfd *, struct bfd_link_info *);
+static bfd_boolean mips_elf_create_got_section
+  (bfd *, struct bfd_link_info *, bfd_boolean);
 static bfd_reloc_status_type mips_elf_calculate_relocation
-  PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *,
-	   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
-	   Elf_Internal_Sym *, asection **, bfd_vma *, const char **,
-	   boolean *));
+  (bfd *, bfd *, asection *, struct bfd_link_info *,
+   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
+   Elf_Internal_Sym *, asection **, bfd_vma *, const char **,
+   bfd_boolean *, bfd_boolean);
 static bfd_vma mips_elf_obtain_contents
-  PARAMS ((reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *));
-static boolean mips_elf_perform_relocation
-  PARAMS ((struct bfd_link_info *, reloc_howto_type *,
-	   const Elf_Internal_Rela *, bfd_vma, bfd *, asection *, bfd_byte *,
-	   boolean));
-static boolean mips_elf_stub_section_p
-  PARAMS ((bfd *, asection *));
+  (reloc_howto_type *, const Elf_Internal_Rela *, bfd *, bfd_byte *);
+static bfd_boolean mips_elf_perform_relocation
+  (struct bfd_link_info *, reloc_howto_type *, const Elf_Internal_Rela *,
+   bfd_vma, bfd *, asection *, bfd_byte *, bfd_boolean);
+static bfd_boolean mips_elf_stub_section_p
+  (bfd *, asection *);
 static void mips_elf_allocate_dynamic_relocations
-  PARAMS ((bfd *, unsigned int));
-static boolean mips_elf_create_dynamic_relocation
-  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
-	   struct mips_elf_link_hash_entry *, asection *,
-	   bfd_vma, bfd_vma *, asection *));
-static INLINE int elf_mips_isa PARAMS ((flagword));
-static INLINE char* elf_mips_abi_name PARAMS ((bfd *));
+  (bfd *, unsigned int);
+static bfd_boolean mips_elf_create_dynamic_relocation
+  (bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
+   struct mips_elf_link_hash_entry *, asection *, bfd_vma,
+   bfd_vma *, asection *);
+static void mips_set_isa_flags
+  (bfd *);
+static INLINE char *elf_mips_abi_name
+  (bfd *);
 static void mips_elf_irix6_finish_dynamic_symbol
-  PARAMS ((bfd *, const char *, Elf_Internal_Sym *));
+  (bfd *, const char *, Elf_Internal_Sym *);
+static bfd_boolean mips_mach_extends_p
+  (unsigned long, unsigned long);
+static bfd_boolean mips_32bit_flags_p
+  (flagword);
+static INLINE hashval_t mips_elf_hash_bfd_vma
+  (bfd_vma);
+static hashval_t mips_elf_got_entry_hash
+  (const void *);
+static int mips_elf_got_entry_eq
+  (const void *, const void *);
+
+static bfd_boolean mips_elf_multi_got
+  (bfd *, struct bfd_link_info *, struct mips_got_info *,
+   asection *, bfd_size_type);
+static hashval_t mips_elf_multi_got_entry_hash
+  (const void *);
+static int mips_elf_multi_got_entry_eq
+  (const void *, const void *);
+static hashval_t mips_elf_bfd2got_entry_hash
+  (const void *);
+static int mips_elf_bfd2got_entry_eq
+  (const void *, const void *);
+static int mips_elf_make_got_per_bfd
+  (void **, void *);
+static int mips_elf_merge_gots
+  (void **, void *);
+static int mips_elf_set_global_got_offset
+  (void **, void *);
+static int mips_elf_set_no_stub
+  (void **, void *);
+static int mips_elf_resolve_final_got_entry
+  (void **, void *);
+static void mips_elf_resolve_final_got_entries
+  (struct mips_got_info *);
+static bfd_vma mips_elf_adjust_gp
+  (bfd *, struct mips_got_info *, bfd *);
+static struct mips_got_info *mips_elf_got_for_ibfd
+  (struct mips_got_info *, bfd *);
 
 /* This will be used when we sort the dynamic relocation records.  */
 static bfd *reldyn_sorting_bfd;
@@ -375,7 +512,7 @@
 
 /* Nonzero if ABFD is using the N64 ABI.  */
 #define ABI_64_P(abfd) \
-  ((get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) != 0)
+  (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
 
 /* Nonzero if ABFD is using NewABI conventions.  */
 #define NEWABI_P(abfd) (ABI_N32_P (abfd) || ABI_64_P (abfd))
@@ -390,11 +527,10 @@
 
 /* The name of the options section.  */
 #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
-  (ABI_64_P (abfd) ? ".MIPS.options" : ".options")
+  (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
 
 /* The name of the stub section.  */
-#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
-  (ABI_64_P (abfd) ? ".MIPS.stubs" : ".stub")
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
 
 /* The size of an external REL relocation.  */
 #define MIPS_ELF_REL_SIZE(abfd) \
@@ -414,7 +550,7 @@
 
 /* The default alignment for sections, as a power of two.  */
 #define MIPS_ELF_LOG_FILE_ALIGN(abfd)				\
-  (get_elf_backend_data (abfd)->s->file_align == 8 ? 3 : 2)
+  (get_elf_backend_data (abfd)->s->log_file_align)
 
 /* Get word-sized data.  */
 #define MIPS_ELF_GET_WORD(abfd, ptr) \
@@ -427,21 +563,29 @@
    : bfd_put_32 (abfd, val, ptr))
 
 /* Add a dynamic symbol table-entry.  */
-#ifdef BFD64
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)			\
-  (ABI_64_P (elf_hash_table (info)->dynobj)				\
-   ? bfd_elf64_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val)	\
-   : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
-#else
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)			\
-  (ABI_64_P (elf_hash_table (info)->dynobj)				\
-   ? (boolean) (abort (), false)					\
-   : bfd_elf32_add_dynamic_entry (info, (bfd_vma) tag, (bfd_vma) val))
-#endif
+#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val)	\
+  _bfd_elf_add_dynamic_entry (info, tag, val)
 
 #define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela)			\
   (get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
 
+/* Determine whether the internal relocation of index REL_IDX is REL
+   (zero) or RELA (non-zero).  The assumption is that, if there are
+   two relocation sections for this section, one of them is REL and
+   the other is RELA.  If the index of the relocation we're testing is
+   in range for the first relocation section, check that the external
+   relocation size is that for RELA.  It is also assumed that, if
+   rel_idx is not in range for the first section, and this first
+   section contains REL relocs, then the relocation is in the second
+   section, that is RELA.  */
+#define MIPS_RELOC_RELA_P(abfd, sec, rel_idx)				\
+  ((NUM_SHDR_ENTRIES (&elf_section_data (sec)->rel_hdr)			\
+    * get_elf_backend_data (abfd)->s->int_rels_per_ext_rel		\
+    > (bfd_vma)(rel_idx))						\
+   == (elf_section_data (sec)->rel_hdr.sh_entsize			\
+       == (ABI_64_P (abfd) ? sizeof (Elf64_External_Rela)		\
+	   : sizeof (Elf32_External_Rela))))
+
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
    from smaller values.  Start with zero, widen, *then* decrement.  */
 #define MINUS_ONE	(((bfd_vma)0) - 1)
@@ -449,20 +593,27 @@
 /* The number of local .got entries we reserve.  */
 #define MIPS_RESERVED_GOTNO (2)
 
-/* Instructions which appear in a stub.  For some reason the stub is
-   slightly different on an SGI system.  */
-#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000)
+/* The offset of $gp from the beginning of the .got section.  */
+#define ELF_MIPS_GP_OFFSET(abfd) (0x7ff0)
+
+/* The maximum size of the GOT for it to be addressable using 16-bit
+   offsets from $gp.  */
+#define MIPS_ELF_GOT_MAX_SIZE(abfd) (ELF_MIPS_GP_OFFSET(abfd) + 0x7fff)
+
+/* Instructions which appear in a stub.  */
 #define STUB_LW(abfd)						\
-  (SGI_COMPAT (abfd)						\
-   ? (ABI_64_P (abfd)  						\
-      ? 0xdf998010		/* ld t9,0x8010(gp) */		\
-      : 0x8f998010)             /* lw t9,0x8010(gp) */		\
-   : 0x8f998010)		/* lw t9,0x8000(gp) */
+  ((ABI_64_P (abfd)  						\
+    ? 0xdf998010		/* ld t9,0x8010(gp) */		\
+    : 0x8f998010))              /* lw t9,0x8010(gp) */
 #define STUB_MOVE(abfd)                                         \
-  (SGI_COMPAT (abfd) ? 0x03e07825 : 0x03e07821)         /* move t7,ra */
-#define STUB_JALR 0x0320f809				/* jal t9 */
+   ((ABI_64_P (abfd)						\
+     ? 0x03e0782d		/* daddu t7,ra */		\
+     : 0x03e07821))		/* addu t7,ra */
+#define STUB_JALR 0x0320f809	/* jalr t9,ra */
 #define STUB_LI16(abfd)                                         \
-  (SGI_COMPAT (abfd) ? 0x34180000 : 0x24180000)         /* ori t8,zero,0 */
+  ((ABI_64_P (abfd)						\
+   ? 0x64180000			/* daddiu t8,zero,0 */		\
+   : 0x24180000))		/* addiu t8,zero,0 */
 #define MIPS_FUNCTION_STUB_SIZE (16)
 
 /* The name of the dynamic interpreter.  This is put in the .interp
@@ -474,6 +625,8 @@
     : "/usr/lib/libc.so.1")
 
 #ifdef BFD64
+#define MNAME(bfd,pre,pos) \
+  (ABI_64_P (bfd) ? CONCAT4 (pre,64,_,pos) : CONCAT4 (pre,32,_,pos))
 #define ELF_R_SYM(bfd, i)					\
   (ABI_64_P (bfd) ? ELF64_R_SYM (i) : ELF32_R_SYM (i))
 #define ELF_R_TYPE(bfd, i)					\
@@ -481,6 +634,7 @@
 #define ELF_R_INFO(bfd, s, t)					\
   (ABI_64_P (bfd) ? ELF64_R_INFO (s, t) : ELF32_R_INFO (s, t))
 #else
+#define MNAME(bfd,pre,pos) CONCAT4 (pre,32,_,pos)
 #define ELF_R_SYM(bfd, i)					\
   (ELF32_R_SYM (i))
 #define ELF_R_TYPE(bfd, i)					\
@@ -539,7 +693,7 @@
 #define mips_elf_link_hash_traverse(table, func, info)			\
   (elf_link_hash_traverse						\
    (&(table)->root,							\
-    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\
+    (bfd_boolean (*) (struct elf_link_hash_entry *, void *)) (func),	\
     (info)))
 
 /* Get the MIPS ELF linker hash table from a link_info structure.  */
@@ -550,28 +704,24 @@
 /* Create an entry in a MIPS ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-mips_elf_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+mips_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
+			    struct bfd_hash_table *table, const char *string)
 {
   struct mips_elf_link_hash_entry *ret =
     (struct mips_elf_link_hash_entry *) entry;
 
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct mips_elf_link_hash_entry *) NULL)
-    ret = ((struct mips_elf_link_hash_entry *)
-	   bfd_hash_allocate (table,
-			      sizeof (struct mips_elf_link_hash_entry)));
-  if (ret == (struct mips_elf_link_hash_entry *) NULL)
+  if (ret == NULL)
+    ret = bfd_hash_allocate (table, sizeof (struct mips_elf_link_hash_entry));
+  if (ret == NULL)
     return (struct bfd_hash_entry *) ret;
 
   /* Call the allocation method of the superclass.  */
   ret = ((struct mips_elf_link_hash_entry *)
 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
 				     table, string));
-  if (ret != (struct mips_elf_link_hash_entry *) NULL)
+  if (ret != NULL)
     {
       /* Set local fields.  */
       memset (&ret->esym, 0, sizeof (EXTR));
@@ -579,40 +729,51 @@
 	 not been set.  -1 means there is no associated ifd.  */
       ret->esym.ifd = -2;
       ret->possibly_dynamic_relocs = 0;
-      ret->readonly_reloc = false;
-      ret->min_dyn_reloc_index = 0;
-      ret->no_fn_stub = false;
+      ret->readonly_reloc = FALSE;
+      ret->no_fn_stub = FALSE;
       ret->fn_stub = NULL;
-      ret->need_fn_stub = false;
+      ret->need_fn_stub = FALSE;
       ret->call_stub = NULL;
       ret->call_fp_stub = NULL;
-      ret->forced_local = false;
+      ret->forced_local = FALSE;
     }
 
   return (struct bfd_hash_entry *) ret;
 }
+
+bfd_boolean
+_bfd_mips_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+  struct _mips_elf_section_data *sdata;
+  bfd_size_type amt = sizeof (*sdata);
+
+  sdata = bfd_zalloc (abfd, amt);
+  if (sdata == NULL)
+    return FALSE;
+  sec->used_by_bfd = sdata;
+
+  return _bfd_elf_new_section_hook (abfd, sec);
+}
 
 /* Read ECOFF debugging information from a .mdebug section into a
    ecoff_debug_info structure.  */
 
-boolean
-_bfd_mips_elf_read_ecoff_info (abfd, section, debug)
-     bfd *abfd;
-     asection *section;
-     struct ecoff_debug_info *debug;
+bfd_boolean
+_bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
+			       struct ecoff_debug_info *debug)
 {
   HDRR *symhdr;
   const struct ecoff_debug_swap *swap;
-  char *ext_hdr = NULL;
+  char *ext_hdr;
 
   swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
   memset (debug, 0, sizeof (*debug));
 
-  ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
+  ext_hdr = bfd_malloc (swap->external_hdr_size);
   if (ext_hdr == NULL && swap->external_hdr_size != 0)
     goto error_return;
 
-  if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
+  if (! bfd_get_section_contents (abfd, section, ext_hdr, 0,
 				  swap->external_hdr_size))
     goto error_return;
 
@@ -627,32 +788,32 @@
   else									\
     {									\
       bfd_size_type amt = (bfd_size_type) size * symhdr->count;		\
-      debug->ptr = (type) bfd_malloc (amt);				\
+      debug->ptr = bfd_malloc (amt);					\
       if (debug->ptr == NULL)						\
 	goto error_return;						\
-      if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0	\
+      if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0		\
 	  || bfd_bread (debug->ptr, amt, abfd) != amt)			\
 	goto error_return;						\
     }
 
   READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
-  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
-  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
-  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
-  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
+  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
+  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
+  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
+  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
   READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
 	union aux_ext *);
   READ (ss, cbSsOffset, issMax, sizeof (char), char *);
   READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
-  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
-  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
-  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
+  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *);
+  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
+  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, void *);
 #undef READ
 
   debug->fdr = NULL;
   debug->adjust = NULL;
 
-  return true;
+  return TRUE;
 
  error_return:
   if (ext_hdr != NULL)
@@ -679,16 +840,13 @@
     free (debug->external_rfd);
   if (debug->external_ext != NULL)
     free (debug->external_ext);
-  return false;
+  return FALSE;
 }
 
 /* Swap RPDR (runtime procedure table entry) for output.  */
 
 static void
-ecoff_swap_rpdr_out (abfd, in, ex)
-     bfd *abfd;
-     const RPDR *in;
-     struct rpdr_ext *ex;
+ecoff_swap_rpdr_out (bfd *abfd, const RPDR *in, struct rpdr_ext *ex)
 {
   H_PUT_S32 (abfd, in->adr, ex->p_adr);
   H_PUT_32 (abfd, in->regmask, ex->p_regmask);
@@ -708,19 +866,16 @@
 
 /* Create a runtime procedure table from the .mdebug section.  */
 
-static boolean
-mips_elf_create_procedure_table (handle, abfd, info, s, debug)
-     PTR handle;
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *s;
-     struct ecoff_debug_info *debug;
+static bfd_boolean
+mips_elf_create_procedure_table (void *handle, bfd *abfd,
+				 struct bfd_link_info *info, asection *s,
+				 struct ecoff_debug_info *debug)
 {
   const struct ecoff_debug_swap *swap;
   HDRR *hdr = &debug->symbolic_header;
   RPDR *rpdr, *rp;
   struct rpdr_ext *erp;
-  PTR rtproc;
+  void *rtproc;
   struct pdr_ext *epdr;
   struct sym_ext *esym;
   char *ss, **sv;
@@ -747,44 +902,44 @@
     {
       size = swap->external_pdr_size;
 
-      epdr = (struct pdr_ext *) bfd_malloc (size * count);
+      epdr = bfd_malloc (size * count);
       if (epdr == NULL)
 	goto error_return;
 
-      if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr))
+      if (! _bfd_ecoff_get_accumulated_pdr (handle, (bfd_byte *) epdr))
 	goto error_return;
 
       size = sizeof (RPDR);
-      rp = rpdr = (RPDR *) bfd_malloc (size * count);
+      rp = rpdr = bfd_malloc (size * count);
       if (rpdr == NULL)
 	goto error_return;
 
       size = sizeof (char *);
-      sv = (char **) bfd_malloc (size * count);
+      sv = bfd_malloc (size * count);
       if (sv == NULL)
 	goto error_return;
 
       count = hdr->isymMax;
       size = swap->external_sym_size;
-      esym = (struct sym_ext *) bfd_malloc (size * count);
+      esym = bfd_malloc (size * count);
       if (esym == NULL)
 	goto error_return;
 
-      if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym))
+      if (! _bfd_ecoff_get_accumulated_sym (handle, (bfd_byte *) esym))
 	goto error_return;
 
       count = hdr->issMax;
-      ss = (char *) bfd_malloc (count);
+      ss = bfd_malloc (count);
       if (ss == NULL)
 	goto error_return;
-      if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss))
+      if (! _bfd_ecoff_get_accumulated_ss (handle, ss))
 	goto error_return;
 
       count = hdr->ipdMax;
       for (i = 0; i < (unsigned long) count; i++, rp++)
 	{
-	  (*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr);
-	  (*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym);
+	  (*swap->swap_pdr_in) (abfd, epdr + i, &pdr);
+	  (*swap->swap_sym_in) (abfd, &esym[pdr.isym], &sym);
 	  rp->adr = sym.value;
 	  rp->regmask = pdr.regmask;
 	  rp->regoffset = pdr.regoffset;
@@ -801,7 +956,7 @@
 
   size = sizeof (struct rpdr_ext) * (count + 2) + sindex;
   size = BFD_ALIGN (size, 16);
-  rtproc = (PTR) bfd_alloc (abfd, size);
+  rtproc = bfd_alloc (abfd, size);
   if (rtproc == NULL)
     {
       mips_elf_hash_table (info)->procedure_count = 0;
@@ -810,7 +965,7 @@
 
   mips_elf_hash_table (info)->procedure_count = count + 2;
 
-  erp = (struct rpdr_ext *) rtproc;
+  erp = rtproc;
   memset (erp, 0, sizeof (struct rpdr_ext));
   erp++;
   str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2);
@@ -826,11 +981,11 @@
 
   /* Set the size and contents of .rtproc section.  */
   s->_raw_size = size;
-  s->contents = (bfd_byte *) rtproc;
+  s->contents = rtproc;
 
   /* Skip this section later on (I don't think this currently
      matters, but someday it might).  */
-  s->link_order_head = (struct bfd_link_order *) NULL;
+  s->link_order_head = NULL;
 
   if (epdr != NULL)
     free (epdr);
@@ -843,7 +998,7 @@
   if (sv != NULL)
     free (sv);
 
-  return true;
+  return TRUE;
 
  error_return:
   if (epdr != NULL)
@@ -856,16 +1011,15 @@
     free (ss);
   if (sv != NULL)
     free (sv);
-  return false;
+  return FALSE;
 }
 
 /* Check the mips16 stubs for a particular symbol, and see if we can
    discard them.  */
 
-static boolean
-mips_elf_check_mips16_stubs (h, data)
-     struct mips_elf_link_hash_entry *h;
-     PTR data ATTRIBUTE_UNUSED;
+static bfd_boolean
+mips_elf_check_mips16_stubs (struct mips_elf_link_hash_entry *h,
+			     void *data ATTRIBUTE_UNUSED)
 {
   if (h->root.root.type == bfd_link_hash_warning)
     h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
@@ -909,23 +1063,17 @@
       h->call_fp_stub->flags |= SEC_EXCLUDE;
     }
 
-  return true;
+  return TRUE;
 }
 
 bfd_reloc_status_type
-_bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry, input_section,
-			       relocateable, data, gp)
-     bfd *abfd;
-     asymbol *symbol;
-     arelent *reloc_entry;
-     asection *input_section;
-     boolean relocateable;
-     PTR data;
-     bfd_vma gp;
+_bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol,
+			       arelent *reloc_entry, asection *input_section,
+			       bfd_boolean relocatable, void *data, bfd_vma gp)
 {
   bfd_vma relocation;
-  unsigned long insn;
-  unsigned long val;
+  bfd_signed_vma val;
+  bfd_reloc_status_type status;
 
   if (bfd_is_com_section (symbol->section))
     relocation = 0;
@@ -938,37 +1086,230 @@
   if (reloc_entry->address > input_section->_cooked_size)
     return bfd_reloc_outofrange;
 
-  insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
+  /* Set val to the offset into the section or symbol.  */
+  val = reloc_entry->addend;
+
+  _bfd_mips_elf_sign_extend (val, 16);
+
+  /* Adjust val for the final section location and GP value.  If we
+     are producing relocatable output, we don't want to do this for
+     an external symbol.  */
+  if (! relocatable
+      || (symbol->flags & BSF_SECTION_SYM) != 0)

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406161331.i5GDVMEU027608>