PERFORCE change 55088 for review
Juli Mallett
jmallett at FreeBSD.org
Wed Jun 16 13:32:21 GMT 2004
http://perforce.freebsd.org/chv.cgi?CH=55088
Change 55088 by jmallett at 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 at cygnus.com>.
@@ -9,27 +9,28 @@
Traditional MIPS targets support added by Koundinya.K, Dansk Data
Elektronik & Operations Research Group. <kk at 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) <<<
More information about the p4-projects
mailing list