summaryrefslogtreecommitdiff
path: root/bfd/elfxx-mips.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elfxx-mips.c')
-rw-r--r--bfd/elfxx-mips.c214
1 files changed, 55 insertions, 159 deletions
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 478a0dbed87..4c5496516a8 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -188,10 +188,6 @@ struct mips_elf_link_hash_entry
a readonly section. */
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",
@@ -390,12 +386,6 @@ 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 *));
-#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 *));
static int sort_dynamic_relocs
PARAMS ((const void *, const void *));
static int sort_dynamic_relocs_64
@@ -442,8 +432,6 @@ static bfd_boolean mips_elf_create_compact_rel_section
PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean mips_elf_create_got_section
PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean));
-static asection *mips_elf_create_msym_section
- PARAMS ((bfd *));
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 *,
@@ -730,7 +718,6 @@ mips_elf_link_hash_newfunc (entry, table, string)
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->fn_stub = NULL;
ret->need_fn_stub = FALSE;
@@ -1192,31 +1179,6 @@ bfd_elf32_swap_crinfo_out (abfd, in, ex)
H_PUT_32 (abfd, in->konst, ex->konst);
H_PUT_32 (abfd, in->vaddr, ex->vaddr);
}
-
-#if 0
-/* Swap in an MSYM entry. */
-
-static void
-bfd_mips_elf_swap_msym_in (abfd, ex, in)
- bfd *abfd;
- const Elf32_External_Msym *ex;
- Elf32_Internal_Msym *in;
-{
- in->ms_hash_value = H_GET_32 (abfd, ex->ms_hash_value);
- in->ms_info = H_GET_32 (abfd, ex->ms_info);
-}
-#endif
-/* Swap out an MSYM entry. */
-
-static void
-bfd_mips_elf_swap_msym_out (abfd, in, ex)
- bfd *abfd;
- const Elf32_Internal_Msym *in;
- Elf32_External_Msym *ex;
-{
- H_PUT_32 (abfd, in->ms_hash_value, ex->ms_hash_value);
- H_PUT_32 (abfd, in->ms_info, ex->ms_info);
-}
/* A .reginfo section holds a single Elf32_RegInfo structure. These
routines swap this structure in and out. They are used outside of
@@ -2917,34 +2879,6 @@ mips_elf_create_got_section (abfd, info, maybe_exclude)
return TRUE;
}
-
-/* Returns the .msym section for ABFD, creating it if it does not
- already exist. Returns NULL to indicate error. */
-
-static asection *
-mips_elf_create_msym_section (abfd)
- bfd *abfd;
-{
- asection *s;
-
- s = bfd_get_section_by_name (abfd, ".msym");
- if (!s)
- {
- s = bfd_make_section (abfd, ".msym");
- if (!s
- || !bfd_set_section_flags (abfd, s,
- SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_LINKER_CREATED
- | SEC_READONLY)
- || !bfd_set_section_alignment (abfd, s,
- MIPS_ELF_LOG_FILE_ALIGN (abfd)))
- return NULL;
- }
-
- return s;
-}
/* Calculate the value produced by the RELOCATION (which comes from
the INPUT_BFD). The ADDEND is the addend to use for this
@@ -3875,9 +3809,17 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
}
#endif
- if (outrel[0].r_offset == (bfd_vma) -1
- || outrel[0].r_offset == (bfd_vma) -2)
+ if (outrel[0].r_offset == (bfd_vma) -1)
+ /* The relocation field has been deleted. */
skip = TRUE;
+ else if (outrel[0].r_offset == (bfd_vma) -2)
+ {
+ /* The relocation field has been converted into a relative value of
+ some sort. Functions like _bfd_elf_write_section_eh_frame expect
+ the field to be fully relocated, so add in the symbol's value. */
+ skip = TRUE;
+ *addendp += symbol;
+ }
/* If we've decided to skip this relocation, just output an empty
record. Note that R_MIPS_NONE == 0, so that this call to memset
@@ -3887,18 +3829,27 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
else
{
long indx;
+ bfd_boolean defined_p;
/* We must now calculate the dynamic symbol table index to use
in the relocation. */
if (h != NULL
&& (! info->symbolic || (h->root.elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))
- {
- indx = h->root.dynindx;
+ & ELF_LINK_HASH_DEF_REGULAR) == 0)
/* h->root.dynindx may be -1 if this symbol was marked to
become local. */
- if (indx == -1)
- indx = 0;
+ && h->root.dynindx != -1)
+ {
+ indx = h->root.dynindx;
+ if (SGI_COMPAT (output_bfd))
+ defined_p = ((h->root.elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0);
+ else
+ /* ??? glibc's ld.so just adds the final GOT entry to the
+ relocation field. It therefore treats relocs against
+ defined symbols in the same way as relocs against
+ undefined symbols. */
+ defined_p = FALSE;
}
else
{
@@ -3927,14 +3878,20 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
section-relative relocations. It's not like they're
useful, after all. This should be a bit more efficient
as well. */
- indx = 0;
+ /* ??? Although this behavior is compatible with glibc's ld.so,
+ the ABI says that relocations against STN_UNDEF should have
+ a symbol value of 0. Irix rld honors this, so relocations
+ against STN_UNDEF have no effect. */
+ if (!SGI_COMPAT (output_bfd))
+ indx = 0;
+ defined_p = TRUE;
}
/* If the relocation was previously an absolute relocation and
this symbol will not be referred to by the relocation, we must
adjust it by the value we give it in the dynamic symbol table.
Otherwise leave the job up to the dynamic linker. */
- if (!indx && r_type != R_MIPS_REL32)
+ if (defined_p && r_type != R_MIPS_REL32)
*addendp += symbol;
/* The relocation is always an REL32 relocation because we don't
@@ -3985,13 +3942,6 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
(output_bfd, &outrel[0],
(sreloc->contents + sreloc->reloc_count * sizeof (Elf32_External_Rel)));
- /* Record the index of the first relocation referencing H. This
- information is later emitted in the .msym section. */
- if (h != NULL
- && (h->min_dyn_reloc_index == 0
- || sreloc->reloc_count < h->min_dyn_reloc_index))
- h->min_dyn_reloc_index = sreloc->reloc_count;
-
/* We've now added another relocation. */
++sreloc->reloc_count;
@@ -4892,13 +4842,6 @@ _bfd_mips_elf_create_dynamic_sections (abfd, info)
if (! mips_elf_rel_dyn_section (elf_hash_table (info)->dynobj, TRUE))
return FALSE;
- /* Create the .msym section on IRIX6. It is used by the dynamic
- linker to speed up dynamic relocations, and to avoid computing
- the ELF hash for symbols. */
- if (IRIX_COMPAT (abfd) == ict_irix6
- && !mips_elf_create_msym_section (abfd))
- return FALSE;
-
/* Create .stub section. */
if (bfd_get_section_by_name (abfd,
MIPS_ELF_STUB_SECTION_NAME (abfd)) == NULL)
@@ -5495,6 +5438,7 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
case R_MIPS_CALL16:
case R_MIPS_CALL_HI16:
case R_MIPS_CALL_LO16:
+ case R_MIPS_JALR:
break;
}
@@ -6060,10 +6004,6 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
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 (strcmp (name, ".msym") == 0)
- s->_raw_size = (sizeof (Elf32_External_Msym)
- * (elf_hash_table (info)->dynsymcount
- + bfd_count_sections (output_bfd)));
else if (strncmp (name, ".init", 5) != 0)
{
/* It's not one of our sections, so don't allocate space. */
@@ -6208,10 +6148,6 @@ _bfd_mips_elf_size_dynamic_sections (output_bfd, info)
(dynobj, MIPS_ELF_OPTIONS_SECTION_NAME (dynobj)))
&& !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_OPTIONS, 0))
return FALSE;
-
- if (bfd_get_section_by_name (dynobj, ".msym")
- && !MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_MSYM, 0))
- return FALSE;
}
return TRUE;
@@ -6644,6 +6580,7 @@ mips_elf_irix6_finish_dynamic_symbol (abfd, name, sym)
/* All of these symbols are given type STT_SECTION by the
IRIX6 linker. */
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
+ sym->st_other = STO_PROTECTED;
/* The IRIX linker puts these symbols in special sections. */
if (i == 0)
@@ -6668,14 +6605,11 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd *dynobj;
bfd_vma gval;
asection *sgot;
- asection *smsym;
struct mips_got_info *g, *gg;
const char *name;
- struct mips_elf_link_hash_entry *mh;
dynobj = elf_hash_table (info)->dynobj;
gval = sym->st_value;
- mh = (struct mips_elf_link_hash_entry *) h;
if (h->plt.offset != (bfd_vma) -1)
{
@@ -6731,22 +6665,7 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_vma offset;
bfd_vma value;
- if (sym->st_value)
- value = sym->st_value;
- else
- {
- /* For an entity defined in a shared object, this will be
- NULL. (For functions in shared objects for
- which we have created stubs, ST_VALUE will be non-NULL.
- That's because such the functions are now no longer defined
- in a shared object.) */
-
- if ((info->shared && h->root.type == bfd_link_hash_undefined)
- || h->root.type == bfd_link_hash_undefweak)
- value = 0;
- else
- value = h->root.u.def.value;
- }
+ value = sym->st_value;
offset = mips_elf_global_got_index (dynobj, output_bfd, h);
MIPS_ELF_PUT_WORD (output_bfd, value, sgot->contents + offset);
}
@@ -6804,21 +6723,6 @@ _bfd_mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
}
}
- /* Create a .msym entry, if appropriate. */
- smsym = bfd_get_section_by_name (dynobj, ".msym");
- if (smsym)
- {
- Elf32_Internal_Msym msym;
-
- msym.ms_hash_value = bfd_elf_hash (h->root.root.string);
- /* It is undocumented what the `1' indicates, but IRIX6 uses
- this value. */
- msym.ms_info = ELF32_MS_INFO (mh->min_dyn_reloc_index, 1);
- bfd_mips_elf_swap_msym_out
- (dynobj, &msym,
- ((Elf32_External_Msym *) smsym->contents) + h->dynindx);
- }
-
/* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
name = h->root.root.string;
if (strcmp (name, "_DYNAMIC") == 0
@@ -7141,33 +7045,9 @@ _bfd_mips_elf_finish_dynamic_sections (output_bfd, info)
}
{
- asection *smsym;
asection *s;
Elf32_compact_rel cpt;
- /* ??? The section symbols for the output sections were set up in
- _bfd_elf_final_link. SGI sets the STT_NOTYPE attribute for these
- symbols. Should we do so? */
-
- smsym = bfd_get_section_by_name (dynobj, ".msym");
- if (smsym != NULL)
- {
- Elf32_Internal_Msym msym;
-
- msym.ms_hash_value = 0;
- msym.ms_info = ELF32_MS_INFO (0, 1);
-
- for (s = output_bfd->sections; s != NULL; s = s->next)
- {
- long dynindx = elf_section_data (s)->dynindx;
-
- bfd_mips_elf_swap_msym_out
- (output_bfd, &msym,
- (((Elf32_External_Msym *) smsym->contents)
- + dynindx));
- }
- }
-
if (SGI_COMPAT (output_bfd))
{
/* Write .compact_rel section out. */
@@ -7283,6 +7163,7 @@ mips_set_isa_flags (abfd)
break;
case bfd_mach_mips5000:
+ case bfd_mach_mips7000:
case bfd_mach_mips8000:
case bfd_mach_mips10000:
case bfd_mach_mips12000:
@@ -7760,10 +7641,6 @@ _bfd_mips_elf_copy_indirect_symbol (bed, dir, ind)
dirmips->possibly_dynamic_relocs += indmips->possibly_dynamic_relocs;
if (indmips->readonly_reloc)
dirmips->readonly_reloc = TRUE;
- if (dirmips->min_dyn_reloc_index == 0
- || (indmips->min_dyn_reloc_index != 0
- && indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
- dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index;
if (indmips->no_fn_stub)
dirmips->no_fn_stub = TRUE;
}
@@ -9069,6 +8946,7 @@ static const struct mips_mach_extension mips_mach_extensions[] = {
{ bfd_mach_mips5, bfd_mach_mips8000 },
{ bfd_mach_mips10000, bfd_mach_mips8000 },
{ bfd_mach_mips5000, bfd_mach_mips8000 },
+ { bfd_mach_mips7000, bfd_mach_mips8000 },
/* VR4100 extensions. */
{ bfd_mach_mips4120, bfd_mach_mips4100 },
@@ -9412,3 +9290,21 @@ _bfd_mips_elf_print_private_bfd_data (abfd, ptr)
return TRUE;
}
+
+struct bfd_elf_special_section const _bfd_mips_elf_special_sections[]=
+{
+ { ".sdata", 0, NULL, 0,
+ SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { ".sbss", 0, NULL, 0,
+ SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { ".lit4", 0, NULL, 0,
+ SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { ".lit8", 0, NULL, 0,
+ SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
+ { ".ucode", 0, NULL, 0,
+ SHT_MIPS_UCODE, 0 },
+ { ".mdebug", 0, NULL, 0,
+ SHT_MIPS_DEBUG, 0 },
+ { NULL, 0, NULL, 0,
+ 0, 0 }
+};