* elf-bfd.h (struct elf_link_hash_table): Add hgot field.
* elf.c (_bfd_elf_link_hash_table_init): Initialize hgot field. * elflink.c (_bfd_elf_create_got_section): Store the _GLOBAL_OFFSET_TABLE_ hash table entry in the hgot field. * elf32-sparc.c (elf32_sparc_check_relocs): If the size of the global offset table goes over 0x1000, set the value of _GLOBAL_OFFSET_TABLE_ to 0x1000 into the section. (elf32_sparc_relocate_section): Subtract the offset of _GLOBAL_OFFSET_TABLE_ when handling GOT relocations. PR 9323.
This commit is contained in:
parent
1dad72bde5
commit
19bfbcbecf
@ -1,5 +1,15 @@
|
||||
Tue Apr 2 00:33:18 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* elf-bfd.h (struct elf_link_hash_table): Add hgot field.
|
||||
* elf.c (_bfd_elf_link_hash_table_init): Initialize hgot field.
|
||||
* elflink.c (_bfd_elf_create_got_section): Store the
|
||||
_GLOBAL_OFFSET_TABLE_ hash table entry in the hgot field.
|
||||
* elf32-sparc.c (elf32_sparc_check_relocs): If the size of the
|
||||
global offset table goes over 0x1000, set the value of
|
||||
_GLOBAL_OFFSET_TABLE_ to 0x1000 into the section.
|
||||
(elf32_sparc_relocate_section): Subtract the offset of
|
||||
_GLOBAL_OFFSET_TABLE_ when handling GOT relocations.
|
||||
|
||||
* elfcode.h: Don't include <string.h>.
|
||||
|
||||
Mon Apr 1 10:39:24 1996 Jeffrey A Law (law@cygnus.com)
|
||||
|
@ -126,6 +126,10 @@ struct elf_link_hash_entry
|
||||
#define ELF_LINK_HASH_NEEDS_COPY 040
|
||||
/* Symbol needs a procedure linkage table entry. */
|
||||
#define ELF_LINK_HASH_NEEDS_PLT 0100
|
||||
/* Symbol appears in a non-ELF input file. */
|
||||
#define ELF_LINK_NON_ELF 0200
|
||||
/* Note: If you add more flags, you must change the type of
|
||||
elf_link_hash_flags. */
|
||||
};
|
||||
|
||||
/* ELF linker hash table. */
|
||||
@ -152,6 +156,8 @@ struct elf_link_hash_table
|
||||
/* A linked list of DT_NEEDED names found in dynamic objects
|
||||
included in the link. */
|
||||
struct bfd_link_needed_list *needed;
|
||||
/* The _GLOBAL_OFFSET_TABLE_ symbol. */
|
||||
struct elf_link_hash_entry *hgot;
|
||||
};
|
||||
|
||||
/* Look up an entry in an ELF linker hash table. */
|
||||
@ -446,9 +452,6 @@ struct elf_backend_data
|
||||
unsigned want_got_plt : 1;
|
||||
unsigned plt_readonly : 1;
|
||||
unsigned want_plt_sym : 1;
|
||||
|
||||
/* Put ELF and program headers in the first loadable segment. */
|
||||
unsigned want_hdr_in_seg : 1;
|
||||
};
|
||||
|
||||
/* Information stored for each BFD section in an ELF file. This
|
||||
@ -578,9 +581,13 @@ struct elf_obj_tdata
|
||||
|
||||
/* The linker ELF emulation code needs to let the backend ELF linker
|
||||
know what filename should be used for a dynamic object if the
|
||||
dynamic object is found using a search. This field is used to
|
||||
hold that information. */
|
||||
const char *dt_needed_name;
|
||||
dynamic object is found using a search. The emulation code then
|
||||
sometimes needs to know what name was actually used. Until the
|
||||
file has been added to the linker symbol table, this field holds
|
||||
the name the linker wants. After it has been added, it holds the
|
||||
name actually used, which will be the DT_SONAME entry if there is
|
||||
one. */
|
||||
const char *dt_name;
|
||||
|
||||
/* Irix 5 often screws up the symbol table, sorting local symbols
|
||||
after global symbols. This flag is set if the symbol table in
|
||||
@ -624,7 +631,7 @@ struct elf_obj_tdata
|
||||
#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes)
|
||||
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got_offsets)
|
||||
#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
|
||||
#define elf_dt_needed_name(bfd) (elf_tdata(bfd) -> dt_needed_name)
|
||||
#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
|
||||
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
|
||||
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
|
||||
#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])
|
||||
|
@ -583,6 +583,7 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
|
||||
table->dynstr = NULL;
|
||||
table->bucketcount = 0;
|
||||
table->needed = NULL;
|
||||
table->hgot = NULL;
|
||||
return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
|
||||
}
|
||||
|
||||
@ -2078,11 +2079,9 @@ assign_file_positions_for_segments (abfd)
|
||||
if (i == 0)
|
||||
abort ();
|
||||
p->p_memsz += adjust;
|
||||
off += adjust;
|
||||
if ((flags & SEC_LOAD) != 0)
|
||||
{
|
||||
p->p_filesz += adjust;
|
||||
off += adjust;
|
||||
}
|
||||
p->p_filesz += adjust;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "elf-bfd.h"
|
||||
#include "elf/sparc.h"
|
||||
|
||||
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||
static reloc_howto_type *elf32_sparc_reloc_type_lookup
|
||||
PARAMS ((bfd *, bfd_reloc_code_real_type));
|
||||
static void elf_info_to_howto
|
||||
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
||||
@ -50,70 +50,86 @@ static boolean elf32_sparc_object_p
|
||||
PARAMS ((bfd *));
|
||||
static void elf32_sparc_final_write_processing
|
||||
PARAMS ((bfd *, boolean));
|
||||
|
||||
/* The howto table and associated functions.
|
||||
??? elf64-sparc.c has its own copy for the moment to ease transition
|
||||
since some of the relocation values have changed. At some point we'll
|
||||
want elf64-sparc.c to switch over and use this table.
|
||||
??? Do we want to recognize (or flag as errors) some of the 64 bit entries
|
||||
if the target is elf32-sparc.
|
||||
*/
|
||||
|
||||
enum reloc_type
|
||||
{
|
||||
R_SPARC_NONE = 0,
|
||||
R_SPARC_8, R_SPARC_16, R_SPARC_32,
|
||||
R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
|
||||
R_SPARC_WDISP30, R_SPARC_WDISP22,
|
||||
R_SPARC_HI22, R_SPARC_22,
|
||||
R_SPARC_13, R_SPARC_LO10,
|
||||
R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
|
||||
R_SPARC_PC10, R_SPARC_PC22,
|
||||
R_SPARC_WPLT30,
|
||||
R_SPARC_COPY,
|
||||
R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
|
||||
R_SPARC_RELATIVE,
|
||||
R_SPARC_UA32,
|
||||
R_SPARC_max
|
||||
};
|
||||
static bfd_reloc_status_type sparc_elf_notsupported_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
static bfd_reloc_status_type sparc_elf_wdisp16_reloc
|
||||
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
|
||||
|
||||
#if 0
|
||||
static CONST char *CONST reloc_type_names[] =
|
||||
reloc_howto_type _bfd_sparc_elf_howto_table[] =
|
||||
{
|
||||
"R_SPARC_NONE",
|
||||
"R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
|
||||
"R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
|
||||
"R_SPARC_WDISP30", "R_SPARC_WDISP22",
|
||||
"R_SPARC_HI22", "R_SPARC_22",
|
||||
"R_SPARC_13", "R_SPARC_LO10",
|
||||
"R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
|
||||
"R_SPARC_PC10", "R_SPARC_PC22",
|
||||
"R_SPARC_WPLT30",
|
||||
"R_SPARC_COPY",
|
||||
"R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
|
||||
"R_SPARC_RELATIVE",
|
||||
"R_SPARC_UA32",
|
||||
};
|
||||
HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true),
|
||||
HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true),
|
||||
HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true),
|
||||
HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true),
|
||||
HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true),
|
||||
HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true),
|
||||
HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true),
|
||||
HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true),
|
||||
HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true),
|
||||
HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true),
|
||||
HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true),
|
||||
/* ??? If we need to handle R_SPARC_64 then we need (figuratively)
|
||||
--enable-64-bit-bfd. That causes objdump to print address as 64 bits
|
||||
which we really don't want on an elf32-sparc system. There may be other
|
||||
consequences which we may not want (at least not until it's proven they're
|
||||
necessary) so for now these are only enabled ifdef BFD64. */
|
||||
#ifdef BFD64
|
||||
HOWTO(R_SPARC_64, 0,4,00,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,~ (bfd_vma) 0, true),
|
||||
/* ??? These don't make sense except in 64 bit systems so they're disabled
|
||||
ifndef BFD64 too (for now). */
|
||||
HOWTO(R_SPARC_OLO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true),
|
||||
#else
|
||||
HOWTO(R_SPARC_64, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_64", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_OLO10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_OLO10", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HH22", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HM10", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LM22", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HH22", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HM10", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_PC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_LM22", false,0,0x00000000,true),
|
||||
#endif
|
||||
|
||||
static reloc_howto_type elf_sparc_howto_table[] =
|
||||
{
|
||||
HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_NONE", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_8", false,0,0x000000ff,true),
|
||||
HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_16", false,0,0x0000ffff,true),
|
||||
HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_32", false,0,0xffffffff,true),
|
||||
HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_DISP8", false,0,0x000000ff,true),
|
||||
HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_DISP16", false,0,0x0000ffff,true),
|
||||
HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_DISP32", false,0,0x00ffffff,true),
|
||||
HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
|
||||
HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_WDISP22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_HI22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_13", false,0,0x00001fff,true),
|
||||
HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_LO10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_GOT10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_GOT13", false,0,0x00001fff,true),
|
||||
HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_GOT22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_PC10", false,0,0x000003ff,true),
|
||||
HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc,"R_SPARC_PC22", false,0,0x003fffff,true),
|
||||
HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc,"R_SPARC_WPLT30", false,0,0x3fffffff,true),
|
||||
HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_COPY", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_RELATIVE",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc,"R_SPARC_UA32", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true),
|
||||
HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true),
|
||||
HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true),
|
||||
HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true),
|
||||
HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true),
|
||||
};
|
||||
|
||||
struct elf_reloc_map {
|
||||
@ -127,6 +143,8 @@ static CONST struct elf_reloc_map sparc_reloc_map[] =
|
||||
{ BFD_RELOC_16, R_SPARC_16, },
|
||||
{ BFD_RELOC_8, R_SPARC_8 },
|
||||
{ BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
|
||||
/* ??? This might cause us to need separate functions in elf{32,64}-sparc.c
|
||||
(we could still have just one table), but is this reloc ever used? */
|
||||
{ BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */
|
||||
{ BFD_RELOC_32, R_SPARC_32 },
|
||||
{ BFD_RELOC_32_PCREL, R_SPARC_DISP32 },
|
||||
@ -146,11 +164,28 @@ static CONST struct elf_reloc_map sparc_reloc_map[] =
|
||||
{ BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT },
|
||||
{ BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE },
|
||||
{ BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 },
|
||||
/* ??? Doesn't dwarf use this? */
|
||||
/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */
|
||||
{BFD_RELOC_SPARC_10, R_SPARC_10},
|
||||
{BFD_RELOC_SPARC_11, R_SPARC_11},
|
||||
{BFD_RELOC_SPARC_64, R_SPARC_64},
|
||||
{BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10},
|
||||
{BFD_RELOC_SPARC_HH22, R_SPARC_HH22},
|
||||
{BFD_RELOC_SPARC_HM10, R_SPARC_HM10},
|
||||
{BFD_RELOC_SPARC_LM22, R_SPARC_LM22},
|
||||
{BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22},
|
||||
{BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10},
|
||||
{BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22},
|
||||
{BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16},
|
||||
{BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19},
|
||||
{BFD_RELOC_SPARC_GLOB_JMP, R_SPARC_GLOB_JMP},
|
||||
{BFD_RELOC_SPARC_7, R_SPARC_7},
|
||||
{BFD_RELOC_SPARC_5, R_SPARC_5},
|
||||
{BFD_RELOC_SPARC_6, R_SPARC_6},
|
||||
};
|
||||
|
||||
static reloc_howto_type *
|
||||
bfd_elf32_bfd_reloc_type_lookup (abfd, code)
|
||||
elf32_sparc_reloc_type_lookup (abfd, code)
|
||||
bfd *abfd;
|
||||
bfd_reloc_code_real_type code;
|
||||
{
|
||||
@ -158,11 +193,14 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
|
||||
for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
|
||||
{
|
||||
if (sparc_reloc_map[i].bfd_reloc_val == code)
|
||||
return &elf_sparc_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
|
||||
return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We need to use ELF32_R_TYPE so we have our own copy of this function,
|
||||
and elf64-sparc.c has its own copy. */
|
||||
|
||||
static void
|
||||
elf_info_to_howto (abfd, cache_ptr, dst)
|
||||
bfd *abfd;
|
||||
@ -170,9 +208,85 @@ elf_info_to_howto (abfd, cache_ptr, dst)
|
||||
Elf_Internal_Rela *dst;
|
||||
{
|
||||
BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max);
|
||||
cache_ptr->howto = &elf_sparc_howto_table[ELF32_R_TYPE(dst->r_info)];
|
||||
cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
|
||||
}
|
||||
|
||||
/* For unsupported relocs. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
sparc_elf_notsupported_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd,
|
||||
error_message)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
char **error_message;
|
||||
{
|
||||
return bfd_reloc_notsupported;
|
||||
}
|
||||
|
||||
/* Handle the WDISP16 reloc. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
sparc_elf_wdisp16_reloc (abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
data,
|
||||
input_section,
|
||||
output_bfd,
|
||||
error_message)
|
||||
bfd *abfd;
|
||||
arelent *reloc_entry;
|
||||
asymbol *symbol;
|
||||
PTR data;
|
||||
asection *input_section;
|
||||
bfd *output_bfd;
|
||||
char **error_message;
|
||||
{
|
||||
bfd_vma relocation;
|
||||
bfd_vma x;
|
||||
|
||||
if (output_bfd != (bfd *) NULL
|
||||
&& (symbol->flags & BSF_SECTION_SYM) == 0
|
||||
&& (! reloc_entry->howto->partial_inplace
|
||||
|| reloc_entry->addend == 0))
|
||||
{
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
if (output_bfd != NULL)
|
||||
return bfd_reloc_continue;
|
||||
|
||||
if (reloc_entry->address > input_section->_cooked_size)
|
||||
return bfd_reloc_outofrange;
|
||||
|
||||
relocation = (symbol->value
|
||||
+ symbol->section->output_section->vma
|
||||
+ symbol->section->output_offset);
|
||||
relocation += reloc_entry->addend;
|
||||
relocation -= (input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
relocation -= reloc_entry->address;
|
||||
|
||||
x = bfd_get_32 (abfd, (char *) data + reloc_entry->address);
|
||||
x |= ((((relocation >> 2) & 0xc000) << 6)
|
||||
| ((relocation >> 2) & 0x3fff));
|
||||
bfd_put_32 (abfd, x, (char *) data + reloc_entry->address);
|
||||
|
||||
if ((bfd_signed_vma) relocation < - 0x40000
|
||||
|| (bfd_signed_vma) relocation > 0x3ffff)
|
||||
return bfd_reloc_overflow;
|
||||
else
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
/* Functions for the SPARC ELF linker. */
|
||||
|
||||
@ -339,6 +453,13 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
|
||||
|
||||
sgot->_raw_size += 4;
|
||||
|
||||
/* If the .got section is more than 0x1000 bytes, we add
|
||||
0x1000 to the value of _GLOBAL_OFFSET_TABLE_, so that 13
|
||||
bit relocations have a greater chance of working. */
|
||||
if (sgot->_raw_size >= 0x1000
|
||||
&& elf_hash_table (info)->hgot->root.u.def.value == 0)
|
||||
elf_hash_table (info)->hgot->root.u.def.value = 0x1000;
|
||||
|
||||
break;
|
||||
|
||||
case R_SPARC_WPLT30:
|
||||
@ -378,6 +499,8 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
|
||||
case R_SPARC_DISP32:
|
||||
case R_SPARC_WDISP30:
|
||||
case R_SPARC_WDISP22:
|
||||
case R_SPARC_WDISP19:
|
||||
case R_SPARC_WDISP16:
|
||||
if (h == NULL)
|
||||
break;
|
||||
/* Fall through. */
|
||||
@ -821,6 +944,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
struct elf_link_hash_entry **sym_hashes;
|
||||
bfd_vma *local_got_offsets;
|
||||
bfd_vma got_base;
|
||||
asection *sgot;
|
||||
asection *splt;
|
||||
asection *sreloc;
|
||||
@ -832,6 +956,11 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
sym_hashes = elf_sym_hashes (input_bfd);
|
||||
local_got_offsets = elf_local_got_offsets (input_bfd);
|
||||
|
||||
if (elf_hash_table (info)->hgot == NULL)
|
||||
got_base = 0;
|
||||
else
|
||||
got_base = elf_hash_table (info)->hgot->root.u.def.value;
|
||||
|
||||
sgot = NULL;
|
||||
splt = NULL;
|
||||
sreloc = NULL;
|
||||
@ -855,7 +984,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return false;
|
||||
}
|
||||
howto = elf_sparc_howto_table + r_type;
|
||||
howto = _bfd_sparc_elf_howto_table + r_type;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
|
||||
@ -893,6 +1022,9 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
else
|
||||
{
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
{
|
||||
@ -920,6 +1052,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|| r_type == R_SPARC_DISP32
|
||||
|| r_type == R_SPARC_WDISP30
|
||||
|| r_type == R_SPARC_WDISP22
|
||||
|| r_type == R_SPARC_WDISP19
|
||||
|| r_type == R_SPARC_WDISP16
|
||||
|| r_type == R_SPARC_HI22
|
||||
|| r_type == R_SPARC_22
|
||||
|| r_type == R_SPARC_13
|
||||
@ -1000,7 +1134,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
}
|
||||
}
|
||||
|
||||
relocation = sgot->output_offset + off;
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1045,7 +1179,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
|
||||
relocation = sgot->output_offset + off;
|
||||
relocation = sgot->output_offset + off - got_base;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1085,6 +1219,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
case R_SPARC_DISP32:
|
||||
case R_SPARC_WDISP30:
|
||||
case R_SPARC_WDISP22:
|
||||
case R_SPARC_WDISP19:
|
||||
case R_SPARC_WDISP16:
|
||||
if (h == NULL)
|
||||
break;
|
||||
/* Fall through. */
|
||||
@ -1194,9 +1330,30 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
break;
|
||||
}
|
||||
|
||||
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset,
|
||||
relocation, rel->r_addend);
|
||||
if (r_type != R_SPARC_WDISP16)
|
||||
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset,
|
||||
relocation, rel->r_addend);
|
||||
else
|
||||
{
|
||||
bfd_vma x;
|
||||
|
||||
relocation += rel->r_addend;
|
||||
relocation -= (input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
relocation -= rel->r_offset;
|
||||
|
||||
x = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
x |= ((((relocation >> 2) & 0xc000) << 6)
|
||||
| ((relocation >> 2) & 0x3fff));
|
||||
bfd_put_32 (input_bfd, x, contents + rel->r_offset);
|
||||
|
||||
if ((bfd_signed_vma) relocation < - 0x40000
|
||||
|| (bfd_signed_vma) relocation > 0x3ffff)
|
||||
r = bfd_reloc_overflow;
|
||||
else
|
||||
r = bfd_reloc_ok;
|
||||
}
|
||||
|
||||
if (r != bfd_reloc_ok)
|
||||
{
|
||||
@ -1625,6 +1782,8 @@ elf32_sparc_final_write_processing (abfd, linker)
|
||||
#define ELF_MACHINE_CODE EM_SPARC
|
||||
#define ELF_MACHINE_ALT1 EM_SPARC32PLUS
|
||||
#define ELF_MAXPAGESIZE 0x10000
|
||||
|
||||
#define bfd_elf32_bfd_reloc_type_lookup elf32_sparc_reloc_type_lookup
|
||||
#define elf_backend_create_dynamic_sections \
|
||||
_bfd_elf_create_dynamic_sections
|
||||
#define elf_backend_check_relocs elf32_sparc_check_relocs
|
||||
|
Loading…
Reference in New Issue
Block a user