* elf32-i386.c (elf_i386_relocate_section): If -Bsymbolic, when
copying relocs into a shared object, treat a defined global symbol as a local symbol. * elf32-m68k.c (elf_m68k_relocate_section): Likewise. * elf32-mips.c (mips_elf_relocate_section): Likewise. * elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
This commit is contained in:
parent
bdd2e7f179
commit
53787b2316
@ -7,6 +7,13 @@ Mon Jan 29 14:27:24 1996 Kim Knuttila <krk@cygnus.com>
|
||||
|
||||
Mon Jan 29 13:06:28 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* elf32-i386.c (elf_i386_relocate_section): If -Bsymbolic, when
|
||||
copying relocs into a shared object, treat a defined global symbol
|
||||
as a local symbol.
|
||||
* elf32-m68k.c (elf_m68k_relocate_section): Likewise.
|
||||
* elf32-mips.c (mips_elf_relocate_section): Likewise.
|
||||
* elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
|
||||
|
||||
* elflink.h (elf_link_add_object_symbols): Only set weakdef to a
|
||||
real defined symbol, not to a weak defined symbol.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Intel 80386/80486-specific support for 32-bit ELF
|
||||
Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -916,6 +916,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
|| (info->shared
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
&& (r_type == R_386_32
|
||||
|| r_type == R_386_PC32)
|
||||
&& (input_section->flags & SEC_ALLOC) != 0))
|
||||
@ -1100,9 +1103,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
case R_386_PC32:
|
||||
if (info->shared
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
&& (r_type != R_386_PC32 || h != NULL))
|
||||
&& (r_type != R_386_PC32
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))))
|
||||
{
|
||||
Elf_Internal_Rel outrel;
|
||||
boolean relocate;
|
||||
|
||||
/* When generating a shared object, these relocations
|
||||
are copied into the output file to be resolved at run
|
||||
@ -1134,15 +1142,23 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
if (r_type == R_386_PC32)
|
||||
{
|
||||
BFD_ASSERT (h != NULL && h->dynindx != -1);
|
||||
relocate = false;
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (h == NULL)
|
||||
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
if (h == NULL
|
||||
|| (info->symbolic
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) != 0))
|
||||
{
|
||||
relocate = true;
|
||||
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (h->dynindx != -1);
|
||||
relocate = false;
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32);
|
||||
}
|
||||
}
|
||||
@ -1157,7 +1173,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
not want to fiddle with the addend. Otherwise, we
|
||||
need to include the symbol value so that it becomes
|
||||
an addend for the dynamic reloc. */
|
||||
if (h != NULL)
|
||||
if (! relocate)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Motorola 68k series support for 32-bit ELF
|
||||
Copyright 1993 Free Software Foundation, Inc.
|
||||
Copyright 1993, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -898,6 +898,9 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
|| (info->shared
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
&& (r_type == R_68K_8
|
||||
|| r_type == R_68K_16
|
||||
@ -1142,7 +1145,10 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
outrel.r_offset = (rel->r_offset
|
||||
+ input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
if (h != NULL)
|
||||
if (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
{
|
||||
BFD_ASSERT (h->dynindx != -1);
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
||||
@ -1159,11 +1165,15 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
long indx;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
|
||||
BFD_ASSERT (ELF_ST_TYPE (sym->st_info) == STT_SECTION);
|
||||
|
||||
sec = local_sections[r_symndx];
|
||||
if (h == NULL)
|
||||
sec = local_sections[r_symndx];
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|
||||
|| (h->root.type
|
||||
== bfd_link_hash_defweak));
|
||||
sec = h->root.u.def.section;
|
||||
}
|
||||
if (sec != NULL && bfd_is_abs_section (sec))
|
||||
indx = 0;
|
||||
else if (sec == NULL || sec->owner == NULL)
|
||||
|
542
bfd/elf32-mips.c
542
bfd/elf32-mips.c
@ -80,6 +80,10 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||
PARAMS ((bfd *, bfd_reloc_code_real_type));
|
||||
static void mips_info_to_howto_rel
|
||||
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
||||
static void bfd_mips_elf32_swap_gptab_in
|
||||
PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *));
|
||||
static void bfd_mips_elf32_swap_gptab_out
|
||||
PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *));
|
||||
static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *));
|
||||
static boolean mips_elf_object_p PARAMS ((bfd *));
|
||||
static boolean mips_elf_create_procedure_table
|
||||
@ -89,6 +93,9 @@ static int mips_elf_additional_program_headers PARAMS ((bfd *));
|
||||
static boolean mips_elf_modify_segment_map PARAMS ((bfd *));
|
||||
static void mips_elf_final_write_processing
|
||||
PARAMS ((bfd *, boolean));
|
||||
static boolean mips_elf_set_private_flags PARAMS ((bfd *, flagword));
|
||||
static boolean mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
static boolean mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
static boolean mips_elf_section_from_shdr
|
||||
PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
|
||||
static boolean mips_elf_fake_sections
|
||||
@ -125,11 +132,32 @@ static boolean mips_elf_adjust_dynindx
|
||||
static boolean mips_elf_relocate_section
|
||||
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
|
||||
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
|
||||
static boolean mips_elf_create_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
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 boolean mips_elf_check_relocs
|
||||
PARAMS ((bfd *, struct bfd_link_info *, asection *,
|
||||
const Elf_Internal_Rela *));
|
||||
static boolean mips_elf_adjust_dynamic_symbol
|
||||
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||
static boolean mips_elf_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean mips_elf_finish_dynamic_symbol
|
||||
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
|
||||
Elf_Internal_Sym *));
|
||||
static boolean mips_elf_finish_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean mips_elf_add_symbol_hook
|
||||
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
|
||||
const char **, flagword *, asection **, bfd_vma *));
|
||||
static bfd_reloc_status_type mips_elf_final_gp
|
||||
PARAMS ((bfd *, asymbol *, boolean, char **));
|
||||
static bfd_byte *elf32_mips_get_relocated_section_contents
|
||||
PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
|
||||
bfd_byte *, boolean, asymbol **));
|
||||
|
||||
/* This is true for Irix 5 executables, false for normal MIPS ELF ABI
|
||||
executables. FIXME: At the moment, we default to always generating
|
||||
@ -289,6 +317,11 @@ typedef struct
|
||||
#define mips_elf_set_cr_dist2to(x,v) ((x).dist2to = (v))
|
||||
#define mips_elf_set_cr_relvaddr(x,d) ((x).relvaddr = (d)<<2)
|
||||
|
||||
static void bfd_elf32_swap_compact_rel_out
|
||||
PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *));
|
||||
static void bfd_elf32_swap_crinfo_out
|
||||
PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *));
|
||||
|
||||
#define USE_REL 1 /* MIPS uses REL relocations instead of RELA */
|
||||
|
||||
enum reloc_type
|
||||
@ -1327,7 +1360,7 @@ bfd_mips_elf32_swap_gptab_out (abfd, in, ex)
|
||||
static void
|
||||
bfd_elf32_swap_compact_rel_out (abfd, in, ex)
|
||||
bfd *abfd;
|
||||
Elf32_compact_rel *in;
|
||||
const Elf32_compact_rel *in;
|
||||
Elf32_External_compact_rel *ex;
|
||||
{
|
||||
bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1);
|
||||
@ -1341,7 +1374,7 @@ bfd_elf32_swap_compact_rel_out (abfd, in, ex)
|
||||
static void
|
||||
bfd_elf32_swap_crinfo_out (abfd, in, ex)
|
||||
bfd *abfd;
|
||||
Elf32_crinfo *in;
|
||||
const Elf32_crinfo *in;
|
||||
Elf32_External_crinfo *ex;
|
||||
{
|
||||
unsigned long l;
|
||||
@ -1968,8 +2001,7 @@ mips_elf_additional_program_headers (abfd)
|
||||
++ret;
|
||||
}
|
||||
|
||||
if (bfd_get_section_by_name (abfd, ".interp") == NULL
|
||||
&& bfd_get_section_by_name (abfd, ".dynamic") != NULL
|
||||
if (bfd_get_section_by_name (abfd, ".dynamic") != NULL
|
||||
&& bfd_get_section_by_name (abfd, ".mdebug") != NULL)
|
||||
{
|
||||
/* We need a PT_MIPS_RTPROC segment. */
|
||||
@ -2409,6 +2441,8 @@ struct mips_elf_link_hash_table
|
||||
bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES];
|
||||
/* The number of .rtproc entries. */
|
||||
bfd_size_type procedure_count;
|
||||
/* The size of the .compact_rel section (if SGI_COMPAT). */
|
||||
bfd_size_type compact_rel_size;
|
||||
};
|
||||
|
||||
/* Look up an entry in a MIPS ELF linker hash table. */
|
||||
@ -2494,6 +2528,7 @@ mips_elf_link_hash_table_create (abfd)
|
||||
for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++)
|
||||
ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
|
||||
ret->procedure_count = 0;
|
||||
ret->compact_rel_size = 0;
|
||||
|
||||
return &ret->root.root;
|
||||
}
|
||||
@ -2512,6 +2547,15 @@ mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
|
||||
asection **secp;
|
||||
bfd_vma *valp;
|
||||
{
|
||||
if (SGI_COMPAT (abfd)
|
||||
&& (abfd->flags & DYNAMIC) != 0
|
||||
&& strcmp (*namep, "_rld_new_interface") == 0)
|
||||
{
|
||||
/* Skip Irix 5 rld entry name. */
|
||||
*namep = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (sym->st_shndx)
|
||||
{
|
||||
case SHN_COMMON:
|
||||
@ -2549,6 +2593,8 @@ mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
|
||||
*secp = mips_elf_text_section_ptr;
|
||||
break;
|
||||
|
||||
case SHN_MIPS_ACOMMON:
|
||||
/* Fall through. XXX Can we treat this as allocated data? */
|
||||
case SHN_MIPS_DATA:
|
||||
/* This section is used in a shared object. */
|
||||
if (mips_elf_data_section_ptr == NULL)
|
||||
@ -3865,7 +3911,7 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
/* If this is HI16 or GOT16 with an associated LO16,
|
||||
adjust the addend accordingly. Otherwise, just
|
||||
relocate. */
|
||||
if ((r_type != R_MIPS_HI16 || r_type == R_MIPS_GOT16)
|
||||
if ((r_type != R_MIPS_HI16 && r_type != R_MIPS_GOT16)
|
||||
|| (rel + 1) >= relend
|
||||
|| ELF32_R_TYPE ((rel + 1)->r_info) != R_MIPS_LO16)
|
||||
r = _bfd_relocate_contents (howto, input_bfd,
|
||||
@ -3953,6 +3999,19 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
relocation = 0;
|
||||
else if (info->shared && ! info->symbolic)
|
||||
relocation = 0;
|
||||
else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0)
|
||||
{
|
||||
/* If this is a dynamic link, we should have created
|
||||
a _DYNAMIC_LINK symbol in
|
||||
mips_elf_create_dynamic_sections. Otherwise, we
|
||||
should define the symbol with a value of 0.
|
||||
FIXME: It should probably get into the symbol
|
||||
table somehow as well. */
|
||||
BFD_ASSERT (! info->shared);
|
||||
BFD_ASSERT (bfd_get_section_by_name (output_bfd,
|
||||
".dynamic") == NULL);
|
||||
relocation = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! ((*info->callbacks->undefined_symbol)
|
||||
@ -4065,7 +4124,10 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
|
||||
|
||||
if (h != NULL)
|
||||
if (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
{
|
||||
BFD_ASSERT (h->dynindx != -1);
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_REL32);
|
||||
@ -4075,11 +4137,15 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
long indx;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
|
||||
BFD_ASSERT (ELF_ST_TYPE (sym->st_info) == STT_SECTION);
|
||||
|
||||
sec = local_sections[r_symndx];
|
||||
if (h == NULL)
|
||||
sec = local_sections[r_symndx];
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|
||||
|| (h->root.type
|
||||
== bfd_link_hash_defweak));
|
||||
sec = h->root.u.def.section;
|
||||
}
|
||||
if (sec != NULL && bfd_is_abs_section (sec))
|
||||
indx = 0;
|
||||
else if (sec == NULL || sec->owner == NULL)
|
||||
@ -4122,6 +4188,7 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
mips_elf_set_cr_type (cptrel, CRT_MIPS_REL32);
|
||||
else
|
||||
mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
|
||||
mips_elf_set_cr_dist2to (cptrel, 0);
|
||||
cptrel.konst = addend;
|
||||
|
||||
cr = (scpt->contents
|
||||
@ -4163,7 +4230,9 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
case R_MIPS_26:
|
||||
mips_elf_set_cr_type (cptrel, CRT_MIPS_JMPAD);
|
||||
cptrel.konst = addend;
|
||||
/* XXX How should we set dist2to in this case. */
|
||||
mips_elf_set_cr_dist2to (cptrel, 8);
|
||||
cptrel.konst = addend + relocation;
|
||||
cr = scpt->contents + sizeof (Elf32_External_compact_rel);
|
||||
bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
|
||||
((Elf32_External_crinfo *) cr
|
||||
@ -4176,6 +4245,7 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
case R_MIPS_GPREL32:
|
||||
mips_elf_set_cr_type (cptrel, CRT_MIPS_GPHI_LO);
|
||||
cptrel.konst = elf_gp (output_bfd) - cptrel.vaddr;
|
||||
mips_elf_set_cr_dist2to (cptrel, 4);
|
||||
cr = scpt->contents + sizeof (Elf32_External_compact_rel);
|
||||
bfd_elf32_swap_crinfo_out (output_bfd, &cptrel,
|
||||
((Elf32_External_crinfo *) cr
|
||||
@ -4233,7 +4303,6 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
|
||||
|
||||
/* Create dynamic sections when linking against a dynamic object. */
|
||||
static boolean mips_elf_create_got_section (bfd *, struct bfd_link_info *);
|
||||
|
||||
static boolean
|
||||
mips_elf_create_dynamic_sections (abfd, info)
|
||||
@ -4284,24 +4353,13 @@ mips_elf_create_dynamic_sections (abfd, info)
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
||||
h->type = STT_SECTION;
|
||||
|
||||
if (info->shared
|
||||
&& ! bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create .compact_rel section. */
|
||||
if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
|
||||
{
|
||||
flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY;
|
||||
|
||||
s = bfd_make_section (abfd, ".compact_rel");
|
||||
if (s == NULL
|
||||
|| ! bfd_set_section_flags (abfd, s, flags)
|
||||
|| ! bfd_set_section_alignment (abfd, s, 2))
|
||||
return false;
|
||||
}
|
||||
|
||||
s->_raw_size = sizeof (Elf32_compact_rel);
|
||||
/* We need to create a .compact_rel section. */
|
||||
if (! mips_elf_create_compact_rel_section (abfd, info))
|
||||
return false;
|
||||
|
||||
/* Change aligments of some sections. */
|
||||
s = bfd_get_section_by_name (abfd, ".hash");
|
||||
@ -4321,9 +4379,51 @@ mips_elf_create_dynamic_sections (abfd, info)
|
||||
bfd_set_section_alignment (abfd, s, 4);
|
||||
}
|
||||
|
||||
if (!info->shared)
|
||||
{
|
||||
h = NULL;
|
||||
if (! (_bfd_generic_link_add_one_symbol
|
||||
(info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr,
|
||||
(bfd_vma) 0, (const char *) NULL, false,
|
||||
get_elf_backend_data (abfd)->collect,
|
||||
(struct bfd_link_hash_entry **) &h)))
|
||||
return false;
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
|
||||
h->type = STT_SECTION;
|
||||
|
||||
if (! bfd_elf32_link_record_dynamic_symbol (info, h))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create the .compact_rel section. */
|
||||
|
||||
static boolean
|
||||
mips_elf_create_compact_rel_section (abfd, info)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
flagword flags;
|
||||
register asection *s;
|
||||
|
||||
if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL)
|
||||
{
|
||||
flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY;
|
||||
|
||||
s = bfd_make_section (abfd, ".compact_rel");
|
||||
if (s == NULL
|
||||
|| ! bfd_set_section_flags (abfd, s, flags)
|
||||
|| ! bfd_set_section_alignment (abfd, s, 2))
|
||||
return false;
|
||||
|
||||
s->_raw_size = sizeof (Elf32_External_compact_rel);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Create the .got section to hold the global offset table. */
|
||||
|
||||
static boolean
|
||||
@ -4350,9 +4450,7 @@ mips_elf_create_got_section (abfd, info)
|
||||
|
||||
/* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the
|
||||
linker script because we don't want to define the symbol if we
|
||||
are not creating a global offset table. XXX Should this be
|
||||
defined at the start of the .got section, even if .got section is
|
||||
accessed by using 16 bit signed offset? */
|
||||
are not creating a global offset table. */
|
||||
h = NULL;
|
||||
if (! (_bfd_generic_link_add_one_symbol
|
||||
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
|
||||
@ -4407,7 +4505,6 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
||||
const Elf_Internal_Rela *rel_end;
|
||||
asection *sgot;
|
||||
asection *sreloc;
|
||||
asection *scpt;
|
||||
|
||||
if (info->relocateable)
|
||||
return true;
|
||||
@ -4419,10 +4516,6 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
||||
|
||||
sgot = NULL;
|
||||
sreloc = NULL;
|
||||
if (SGI_COMPAT (abfd) && dynobj != NULL)
|
||||
scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
|
||||
else
|
||||
scpt = NULL;
|
||||
|
||||
rel_end = relocs + sec->reloc_count;
|
||||
for (rel = relocs; rel < rel_end; rel++)
|
||||
@ -4577,19 +4670,21 @@ mips_elf_check_relocs (abfd, info, sec, relocs)
|
||||
}
|
||||
|
||||
sreloc->_raw_size += sizeof (Elf32_External_Rel);
|
||||
|
||||
if (scpt != NULL)
|
||||
scpt->_raw_size += sizeof (Elf32_External_crinfo);
|
||||
}
|
||||
|
||||
if (SGI_COMPAT (abfd))
|
||||
mips_elf_hash_table (info)->compact_rel_size +=
|
||||
sizeof (Elf32_External_crinfo);
|
||||
|
||||
break;
|
||||
|
||||
case R_MIPS_26:
|
||||
case R_MIPS_GPREL16:
|
||||
case R_MIPS_LITERAL:
|
||||
case R_MIPS_GPREL32:
|
||||
if (scpt != NULL)
|
||||
scpt->_raw_size += sizeof (Elf32_External_crinfo);
|
||||
if (SGI_COMPAT (abfd))
|
||||
mips_elf_hash_table (info)->compact_rel_size +=
|
||||
sizeof (Elf32_External_crinfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -4800,9 +4895,10 @@ mips_elf_size_dynamic_sections (output_bfd, info)
|
||||
of .text section. So put a dummy. XXX */
|
||||
s->_raw_size += MIPS_FUNCTION_STUB_SIZE;
|
||||
}
|
||||
else if (strncmp (name, ".init", 5) != 0
|
||||
&& (! SGI_COMPAT (output_bfd)
|
||||
|| strncmp (name, ".compact_rel", 12) != 0))
|
||||
else if (SGI_COMPAT (output_bfd)
|
||||
&& strncmp (name, ".compact_rel", 12) == 0)
|
||||
s->_raw_size += mips_elf_hash_table (info)->compact_rel_size;
|
||||
else if (strncmp (name, ".init", 5) != 0)
|
||||
{
|
||||
/* It's not one of our sections, so don't allocate space. */
|
||||
continue;
|
||||
@ -4872,7 +4968,7 @@ mips_elf_size_dynamic_sections (output_bfd, info)
|
||||
if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLISTNO, 0))
|
||||
return false;
|
||||
|
||||
if (bfd_get_section_by_name (dynobj, ".conflict"))
|
||||
if (bfd_get_section_by_name (dynobj, ".conflict") != NULL)
|
||||
{
|
||||
if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICT, 0))
|
||||
return false;
|
||||
@ -4890,8 +4986,11 @@ mips_elf_size_dynamic_sections (output_bfd, info)
|
||||
if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_FLAGS, 0))
|
||||
return false;
|
||||
|
||||
#if 0
|
||||
/* Time stamps in executable files are a bad idea. */
|
||||
if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_TIME_STAMP, 0))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if 0 /* FIXME */
|
||||
if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_ICHECKSUM, 0))
|
||||
@ -4932,74 +5031,76 @@ mips_elf_size_dynamic_sections (output_bfd, info)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we are generating a shared library, we generate a section
|
||||
symbol for each output section. These are local symbols, which
|
||||
means that they must come first in the dynamic symbol table.
|
||||
/* If we use dynamic linking, we generate a section symbol for each
|
||||
output section. These are local symbols, which means that they
|
||||
must come first in the dynamic symbol table.
|
||||
That means we must increment the dynamic symbol index of every
|
||||
other dynamic symbol. */
|
||||
if (info->shared)
|
||||
{
|
||||
const char * const *namep;
|
||||
int c, i;
|
||||
bfd_size_type strindex;
|
||||
struct bfd_strtab_hash *dynstr;
|
||||
struct mips_got_info *g;
|
||||
{
|
||||
const char * const *namep;
|
||||
unsigned int c, i;
|
||||
bfd_size_type strindex;
|
||||
struct bfd_strtab_hash *dynstr;
|
||||
struct mips_got_info *g;
|
||||
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1;
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
mips_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1;
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
mips_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
|
||||
dynstr = elf_hash_table (info)->dynstr;
|
||||
BFD_ASSERT (dynstr != NULL);
|
||||
dynstr = elf_hash_table (info)->dynstr;
|
||||
BFD_ASSERT (dynstr != NULL);
|
||||
|
||||
for (i = 1, namep = mips_elf_dynsym_sec_names;
|
||||
*namep != NULL;
|
||||
i++, namep++)
|
||||
{
|
||||
s = bfd_get_section_by_name (output_bfd, *namep);
|
||||
if (s != NULL)
|
||||
for (i = 1, namep = mips_elf_dynsym_sec_names;
|
||||
*namep != NULL;
|
||||
i++, namep++)
|
||||
{
|
||||
s = bfd_get_section_by_name (output_bfd, *namep);
|
||||
if (s != NULL)
|
||||
elf_section_data (s)->dynindx = i;
|
||||
|
||||
strindex = _bfd_stringtab_add (dynstr, *namep, true, false);
|
||||
if (strindex == (bfd_size_type) -1)
|
||||
return false;
|
||||
|
||||
mips_elf_hash_table (info)->dynsym_sec_strindex[i] = strindex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = bfd_count_sections (output_bfd);
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
mips_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
|
||||
for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++)
|
||||
{
|
||||
elf_section_data (s)->dynindx = i;
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strindex = _bfd_stringtab_add (dynstr, *namep, true, false);
|
||||
if (strindex == (bfd_size_type) -1)
|
||||
return false;
|
||||
s = bfd_get_section_by_name (dynobj, ".got");
|
||||
BFD_ASSERT (s != NULL);
|
||||
BFD_ASSERT (elf_section_data (s) != NULL);
|
||||
g = (struct mips_got_info *) elf_section_data (s)->tdata;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
mips_elf_hash_table (info)->dynsym_sec_strindex[i] = strindex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = bfd_count_sections (output_bfd);
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
mips_elf_adjust_dynindx,
|
||||
(PTR) &c);
|
||||
elf_hash_table (info)->dynsymcount += c;
|
||||
|
||||
for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++)
|
||||
{
|
||||
elf_section_data (s)->dynindx = i;
|
||||
/* These symbols will have no names, so we don't need to
|
||||
fiddle with dynstr_index. */
|
||||
}
|
||||
}
|
||||
|
||||
s = bfd_get_section_by_name (dynobj, ".got");
|
||||
BFD_ASSERT (s != NULL);
|
||||
BFD_ASSERT (elf_section_data (s) != NULL);
|
||||
g = (struct mips_got_info *) elf_section_data (s)->tdata;
|
||||
BFD_ASSERT (g != NULL);
|
||||
|
||||
/* If there are no global got symbols, fake the last symbol so for
|
||||
safety. */
|
||||
if (g->global_gotsym)
|
||||
g->global_gotsym += c;
|
||||
else
|
||||
g->global_gotsym = elf_hash_table (info)->dynsymcount - 1;
|
||||
}
|
||||
/* If there are no global got symbols, fake the last symbol so for
|
||||
safety. */
|
||||
if (g->global_gotsym)
|
||||
g->global_gotsym += c;
|
||||
else
|
||||
g->global_gotsym = elf_hash_table (info)->dynsymcount - 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5012,7 +5113,7 @@ mips_elf_adjust_dynindx (h, cparg)
|
||||
struct elf_link_hash_entry *h;
|
||||
PTR cparg;
|
||||
{
|
||||
int *cp = (int *) cparg;
|
||||
unsigned int *cp = (unsigned int *) cparg;
|
||||
|
||||
if (h->dynindx != -1)
|
||||
h->dynindx += *cp;
|
||||
@ -5108,8 +5209,13 @@ mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
if (strcmp (name, "_DYNAMIC") == 0
|
||||
|| strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
|
||||
sym->st_shndx = SHN_ABS;
|
||||
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
else if (strcmp (name, "_DYNAMIC_LINK") == 0)
|
||||
{
|
||||
sym->st_shndx = SHN_ABS;
|
||||
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
|
||||
sym->st_value = 1;
|
||||
}
|
||||
else if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
if (strcmp (name, "_gp_disp") == 0)
|
||||
{
|
||||
@ -5132,8 +5238,7 @@ mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
sym->st_value = mips_elf_hash_table (info)->procedure_count;
|
||||
sym->st_shndx = SHN_ABS;
|
||||
}
|
||||
|
||||
if (sym->st_shndx != SHN_UNDEF)
|
||||
else if (sym->st_shndx != SHN_UNDEF)
|
||||
{
|
||||
if (h->type == STT_FUNC)
|
||||
sym->st_shndx = SHN_MIPS_TEXT;
|
||||
@ -5321,128 +5426,130 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
|
||||
|
||||
elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
|
||||
|
||||
if (info->shared)
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
unsigned int i;
|
||||
bfd_vma last;
|
||||
Elf_Internal_Sym sym;
|
||||
long dindx;
|
||||
const char *name;
|
||||
const char * const * namep = mips_elf_dynsym_sec_names;
|
||||
Elf32_compact_rel cpt;
|
||||
{
|
||||
asection *sdynsym;
|
||||
asection *s;
|
||||
unsigned int i;
|
||||
bfd_vma last;
|
||||
Elf_Internal_Sym sym;
|
||||
long dindx;
|
||||
const char *name;
|
||||
const char * const * namep = mips_elf_dynsym_sec_names;
|
||||
Elf32_compact_rel cpt;
|
||||
|
||||
/* Set up the section symbols for the output sections. SGI set
|
||||
STT_NOTYPE attribute for these symbols. Should we do so? */
|
||||
/* Set up the section symbols for the output sections. SGI sets
|
||||
the STT_NOTYPE attribute for these symbols. Should we do so? */
|
||||
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
BFD_ASSERT (sdynsym != NULL);
|
||||
sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
|
||||
if (sdynsym != NULL)
|
||||
{
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
|
||||
sym.st_other = 0;
|
||||
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE);
|
||||
sym.st_other = 0;
|
||||
i = 0;
|
||||
while ((name = *namep++) != NULL)
|
||||
{
|
||||
s = bfd_get_section_by_name (output_bfd, name);
|
||||
if (s != NULL)
|
||||
{
|
||||
sym.st_value = s->vma;
|
||||
dindx = elf_section_data (s)->dynindx;
|
||||
last = s->vma + s->_raw_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym.st_value = last;
|
||||
dindx++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while ((name = *namep++) != NULL)
|
||||
{
|
||||
s = bfd_get_section_by_name (output_bfd, name);
|
||||
if (s)
|
||||
{
|
||||
sym.st_value = s->vma;
|
||||
dindx = elf_section_data (s)->dynindx;
|
||||
last = s->vma + s->_raw_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym.st_value = last;
|
||||
dindx++;
|
||||
}
|
||||
sym.st_shndx = (i < MIPS_TEXT_DYNSYM_SECNO
|
||||
? SHN_MIPS_TEXT
|
||||
: SHN_MIPS_DATA);
|
||||
++i;
|
||||
sym.st_name =
|
||||
mips_elf_hash_table (info)->dynsym_sec_strindex[dindx];
|
||||
|
||||
sym.st_shndx = (i < MIPS_TEXT_DYNSYM_SECNO
|
||||
? SHN_MIPS_TEXT
|
||||
: SHN_MIPS_DATA);
|
||||
++i;
|
||||
sym.st_name =
|
||||
mips_elf_hash_table (info)->dynsym_sec_strindex[dindx];
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ dindx));
|
||||
}
|
||||
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ dindx));
|
||||
}
|
||||
/* Set the sh_info field of the output .dynsym section to
|
||||
the index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
SIZEOF_MIPS_DYNSYM_SECNAMES;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to
|
||||
the index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
SIZEOF_MIPS_DYNSYM_SECNAMES;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym.st_size = 0;
|
||||
sym.st_name = 0;
|
||||
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
|
||||
sym.st_other = 0;
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
|
||||
for (s = output_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
int indx;
|
||||
sym.st_value = s->vma;
|
||||
|
||||
sym.st_value = s->vma;
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
|
||||
indx = elf_section_data (s)->this_idx;
|
||||
BFD_ASSERT (indx > 0);
|
||||
sym.st_shndx = indx;
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
}
|
||||
|
||||
bfd_elf32_swap_symbol_out (output_bfd, &sym,
|
||||
(((Elf32_External_Sym *)
|
||||
sdynsym->contents)
|
||||
+ elf_section_data (s)->dynindx));
|
||||
}
|
||||
/* Set the sh_info field of the output .dynsym section to
|
||||
the index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
bfd_count_sections (output_bfd) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the sh_info field of the output .dynsym section to
|
||||
the index of the first global symbol. */
|
||||
elf_section_data (sdynsym->output_section)->this_hdr.sh_info =
|
||||
bfd_count_sections (output_bfd) + 1;
|
||||
}
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
/* Write .compact_rel section out. */
|
||||
s = bfd_get_section_by_name (dynobj, ".compact_rel");
|
||||
if (s != NULL)
|
||||
{
|
||||
cpt.id1 = 1;
|
||||
cpt.num = s->reloc_count;
|
||||
cpt.id2 = 2;
|
||||
cpt.offset = (s->output_section->filepos
|
||||
+ sizeof (Elf32_External_compact_rel));
|
||||
cpt.reserved0 = 0;
|
||||
cpt.reserved1 = 0;
|
||||
bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
|
||||
((Elf32_External_compact_rel *)
|
||||
s->contents));
|
||||
|
||||
if (SGI_COMPAT (output_bfd))
|
||||
{
|
||||
/* Write .compact_rel section out. */
|
||||
s = bfd_get_section_by_name (dynobj, ".compact_rel");
|
||||
BFD_ASSERT (s != NULL);
|
||||
/* Clean up a dummy stub function entry in .text. */
|
||||
s = bfd_get_section_by_name (dynobj, ".stub");
|
||||
if (s != NULL)
|
||||
{
|
||||
file_ptr dummy_offset;
|
||||
|
||||
cpt.id1 = 1;
|
||||
cpt.num = s->reloc_count;
|
||||
cpt.id2 = 2;
|
||||
cpt.offset = (s->output_section->filepos
|
||||
+ sizeof (Elf32_External_compact_rel));
|
||||
cpt.reserved0 = 0;
|
||||
cpt.reserved1 = 0;
|
||||
bfd_elf32_swap_compact_rel_out (output_bfd, &cpt,
|
||||
((Elf32_External_compact_rel *)
|
||||
s->contents));
|
||||
BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE);
|
||||
dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE;
|
||||
memset (s->contents + dummy_offset, 0,
|
||||
MIPS_FUNCTION_STUB_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up a dummy stub function entry in .text. */
|
||||
s = bfd_get_section_by_name (dynobj, ".stub");
|
||||
if (s != NULL)
|
||||
{
|
||||
file_ptr dummy_offset;
|
||||
|
||||
BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE);
|
||||
dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE;
|
||||
memset (s->contents + dummy_offset, 0, MIPS_FUNCTION_STUB_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up a first relocation in .rel.dyn. */
|
||||
s = bfd_get_section_by_name (dynobj, ".rel.dyn");
|
||||
if (s)
|
||||
memset (s->contents, 0, sizeof (Elf32_External_Rel));
|
||||
}
|
||||
/* Clean up a first relocation in .rel.dyn. */
|
||||
s = bfd_get_section_by_name (dynobj, ".rel.dyn");
|
||||
if (s != NULL)
|
||||
memset (s->contents, 0, sizeof (Elf32_External_Rel));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -5712,7 +5819,6 @@ static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap =
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data \
|
||||
mips_elf_merge_private_bfd_data
|
||||
#define bfd_elf32_bfd_set_private_flags mips_elf_set_private_flags
|
||||
#define elf_backend_relocate_section mips_elf_relocate_section
|
||||
#define elf_backend_add_symbol_hook mips_elf_add_symbol_hook
|
||||
#define elf_backend_create_dynamic_sections \
|
||||
mips_elf_create_dynamic_sections
|
||||
|
@ -22,9 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "bfdlink.h"
|
||||
#include "libbfd.h"
|
||||
#include "elf-bfd.h"
|
||||
/* start-sanitize-v8plus */
|
||||
#include "elf/sparc.h"
|
||||
/* end-sanitize-v8plus */
|
||||
|
||||
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
|
||||
PARAMS ((bfd *, bfd_reloc_code_real_type));
|
||||
@ -47,15 +45,11 @@ static boolean elf32_sparc_finish_dynamic_symbol
|
||||
Elf_Internal_Sym *));
|
||||
static boolean elf32_sparc_finish_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
/* start-sanitize-v8plus */
|
||||
static boolean elf32_sparc_set_private_flags PARAMS ((bfd *, flagword));
|
||||
static boolean elf32_sparc_copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
static boolean elf32_sparc_merge_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||
static boolean elf32_sparc_object_p
|
||||
PARAMS ((bfd *));
|
||||
static void elf32_sparc_final_write_processing
|
||||
PARAMS ((bfd *, boolean));
|
||||
/* end-sanitize-v8plus */
|
||||
|
||||
enum reloc_type
|
||||
{
|
||||
@ -914,6 +908,9 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
|| (info->shared
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
&& (r_type == R_SPARC_8
|
||||
|| r_type == R_SPARC_16
|
||||
@ -1131,7 +1128,10 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
outrel.r_offset = (rel->r_offset
|
||||
+ input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
if (h != NULL)
|
||||
if (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||
{
|
||||
BFD_ASSERT (h->dynindx != -1);
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
||||
@ -1148,8 +1148,15 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
long indx;
|
||||
|
||||
sym = local_syms + r_symndx;
|
||||
sec = local_sections[r_symndx];
|
||||
if (h == NULL)
|
||||
sec = local_sections[r_symndx];
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|
||||
|| (h->root.type
|
||||
== bfd_link_hash_defweak));
|
||||
sec = h->root.u.def.section;
|
||||
}
|
||||
if (sec != NULL && bfd_is_abs_section (sec))
|
||||
indx = 0;
|
||||
else if (sec == NULL || sec->owner == NULL)
|
||||
@ -1491,45 +1498,13 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
|
||||
|
||||
return true;
|
||||
}
|
||||
/* start-sanitize-v8plus */
|
||||
|
||||
/* Function to set e_flags. */
|
||||
/* Functions for dealing with the e_flags field.
|
||||
|
||||
static boolean
|
||||
elf32_sparc_set_private_flags (abfd, flags)
|
||||
bfd *abfd;
|
||||
flagword flags;
|
||||
{
|
||||
/* Once the flags have been set, you (apparently) can't change them. */
|
||||
BFD_ASSERT (!elf_flags_init (abfd)
|
||||
|| elf_elfheader (abfd)->e_flags == flags);
|
||||
|
||||
elf_elfheader (abfd)->e_flags = flags;
|
||||
elf_flags_init (abfd) = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Copy backend specific data from one object module to another. */
|
||||
|
||||
static boolean
|
||||
elf32_sparc_copy_private_bfd_data (ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
/* This function is selected based on the input vector. We only
|
||||
want to copy information over if the output BFD also uses Elf
|
||||
format. */
|
||||
if (bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
||||
return true;
|
||||
|
||||
/* Once the flags have been set, you (apparently) can't change them. */
|
||||
BFD_ASSERT (!elf_flags_init (obfd)
|
||||
|| elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
|
||||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = true;
|
||||
return true;
|
||||
}
|
||||
We don't define set_private_flags or copy_private_bfd_data because
|
||||
the only currently defined values are based on the bfd mach number,
|
||||
so we use the latter instead and defer setting e_flags until the
|
||||
file is written out. */
|
||||
|
||||
/* Merge backend specific data from an object file to the output
|
||||
object file when linking. */
|
||||
@ -1539,8 +1514,6 @@ elf32_sparc_merge_private_bfd_data (ibfd, obfd)
|
||||
bfd *ibfd;
|
||||
bfd *obfd;
|
||||
{
|
||||
flagword old_flags;
|
||||
flagword new_flags;
|
||||
boolean error;
|
||||
|
||||
/* This function is selected based on the input vector. We only
|
||||
@ -1551,6 +1524,13 @@ elf32_sparc_merge_private_bfd_data (ibfd, obfd)
|
||||
|
||||
error = false;
|
||||
|
||||
#if 0
|
||||
/* ??? The native linker doesn't do this so we can't (otherwise gcc would
|
||||
have to know which linker is being used). Instead, the native linker
|
||||
bumps up the architecture level when it has to. However, I still think
|
||||
warnings like these are good, so it would be nice to have them turned on
|
||||
by some option. */
|
||||
|
||||
/* If the output machine is normal sparc, we can't allow v9 input files. */
|
||||
if (bfd_get_mach (obfd) == bfd_mach_sparc
|
||||
&& (bfd_get_mach (ibfd) == bfd_mach_sparc_v8plus
|
||||
@ -1570,30 +1550,17 @@ elf32_sparc_merge_private_bfd_data (ibfd, obfd)
|
||||
("%s: compiled for a v8plusa system and target is v8plus",
|
||||
bfd_get_filename (ibfd));
|
||||
}
|
||||
|
||||
new_flags = elf_elfheader (ibfd)->e_flags;
|
||||
old_flags = elf_elfheader (obfd)->e_flags;
|
||||
if (!elf_flags_init (obfd)) /* First call, no flags set */
|
||||
#else
|
||||
if (bfd_get_mach (ibfd) >= bfd_mach_sparc_v9)
|
||||
{
|
||||
elf_flags_init (obfd) = true;
|
||||
elf_elfheader (obfd)->e_flags = new_flags;
|
||||
}
|
||||
else if (new_flags == old_flags) /* Compatible flags are ok */
|
||||
;
|
||||
else /* Potentially incompatible flags */
|
||||
{
|
||||
new_flags &= ~ (EF_SPARC_32PLUS | EF_SPARC_SUN_US1);
|
||||
old_flags &= ~ (EF_SPARC_32PLUS | EF_SPARC_SUN_US1);
|
||||
|
||||
/* Warn about any other mismatches */
|
||||
if (new_flags != old_flags)
|
||||
{
|
||||
error = true;
|
||||
(*_bfd_error_handler)
|
||||
("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)",
|
||||
bfd_get_filename (ibfd), (long) new_flags, (long) old_flags);
|
||||
}
|
||||
error = true;
|
||||
(*_bfd_error_handler)
|
||||
("%s: compiled for a 64 bit system and target is 32 bit",
|
||||
bfd_get_filename (ibfd));
|
||||
}
|
||||
else if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
|
||||
bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
|
||||
#endif
|
||||
|
||||
if (error)
|
||||
{
|
||||
@ -1611,7 +1578,16 @@ elf32_sparc_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if (elf_elfheader (abfd)->e_machine == EM_SPARC32PLUS)
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v8plus);
|
||||
{
|
||||
if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1)
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
|
||||
bfd_mach_sparc_v8plusa);
|
||||
else if (elf_elfheader (abfd)->e_flags & EF_SPARC_32PLUS)
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc,
|
||||
bfd_mach_sparc_v8plus);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
|
||||
}
|
||||
@ -1624,24 +1600,30 @@ elf32_sparc_final_write_processing (abfd, linker)
|
||||
bfd *abfd;
|
||||
boolean linker;
|
||||
{
|
||||
if (bfd_get_mach (abfd) == bfd_mach_sparc_v8plus)
|
||||
switch (bfd_get_mach (abfd))
|
||||
{
|
||||
case bfd_mach_sparc :
|
||||
break; /* nothing to do */
|
||||
case bfd_mach_sparc_v8plus :
|
||||
elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
|
||||
#if 0 /* FIXME: Not sure how to handle EF_SPARC_32PLUS_US1 */
|
||||
elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
|
||||
#endif
|
||||
elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS;
|
||||
break;
|
||||
case bfd_mach_sparc_v8plusa :
|
||||
elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS;
|
||||
elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK;
|
||||
elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
/* end-sanitize-v8plus */
|
||||
|
||||
#define TARGET_BIG_SYM bfd_elf32_sparc_vec
|
||||
#define TARGET_BIG_NAME "elf32-sparc"
|
||||
#define ELF_ARCH bfd_arch_sparc
|
||||
#define ELF_MACHINE_CODE EM_SPARC
|
||||
/* start-sanitize-v8plus */
|
||||
#define ELF_MACHINE_ALT1 EM_SPARC32PLUS
|
||||
/* end-sanitize-v8plus */
|
||||
#define ELF_MAXPAGESIZE 0x10000
|
||||
#define elf_backend_create_dynamic_sections \
|
||||
_bfd_elf_create_dynamic_sections
|
||||
@ -1655,16 +1637,11 @@ elf32_sparc_final_write_processing (abfd, linker)
|
||||
elf32_sparc_finish_dynamic_symbol
|
||||
#define elf_backend_finish_dynamic_sections \
|
||||
elf32_sparc_finish_dynamic_sections
|
||||
/* start-sanitize-v8plus */
|
||||
#define bfd_elf32_bfd_set_private_flags elf32_sparc_set_private_flags
|
||||
#define bfd_elf32_bfd_copy_private_bfd_data \
|
||||
elf32_sparc_copy_private_bfd_data
|
||||
#define bfd_elf32_bfd_merge_private_bfd_data \
|
||||
elf32_sparc_merge_private_bfd_data
|
||||
#define elf_backend_object_p elf32_sparc_object_p
|
||||
#define elf_backend_final_write_processing \
|
||||
elf32_sparc_final_write_processing
|
||||
/* end-sanitize-v8plus */
|
||||
#define elf_backend_want_got_plt 0
|
||||
#define elf_backend_plt_readonly 0
|
||||
#define elf_backend_want_plt_sym 1
|
||||
|
Loading…
Reference in New Issue
Block a user