h->esym.asym.value =
mips_elf_hash_table (einfo->info)->procedure_count;
}
- else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (einfo->abfd))
- {
- h->esym.asym.sc = scAbs;
- h->esym.asym.st = stLabel;
- h->esym.asym.value = elf_gp (einfo->abfd);
- }
else
h->esym.asym.sc = scUndefined;
}
bfd_boolean need_relocs = FALSE;
bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
- if (h && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
- && (!bfd_link_pic (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
+ if (h != NULL
+ && h->dynindx != -1
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+ && (bfd_link_dll (info) || !SYMBOL_REFERENCES_LOCAL (info, h)))
indx = h->dynindx;
- if ((bfd_link_pic (info) || indx != 0)
+ if ((bfd_link_dll (info) || indx != 0)
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
return 1;
case GOT_TLS_LDM:
- return bfd_link_pic (info) ? 1 : 0;
+ return bfd_link_dll (info) ? 1 : 0;
default:
return 0;
struct mips_elf_link_hash_entry *h,
bfd_vma value)
{
+ bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
struct mips_elf_link_hash_table *htab;
int indx;
asection *sreloc, *sgot;
sgot = htab->root.sgot;
indx = 0;
- if (h != NULL)
- {
- bfd_boolean dyn = elf_hash_table (info)->dynamic_sections_created;
-
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
- &h->root)
- && (!bfd_link_pic (info)
- || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
- indx = h->root.dynindx;
- }
+ if (h != NULL
+ && h->root.dynindx != -1
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), &h->root)
+ && (bfd_link_dll (info) || !SYMBOL_REFERENCES_LOCAL (info, &h->root)))
+ indx = h->root.dynindx;
if (entry->tls_initialized)
return;
- if ((bfd_link_pic (info) || indx != 0)
+ if ((bfd_link_dll (info) || indx != 0)
&& (h == NULL
|| ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
sgot->contents + got_offset
+ MIPS_ELF_GOT_SIZE (abfd));
- if (!bfd_link_pic (info))
+ if (!bfd_link_dll (info))
MIPS_ELF_PUT_WORD (abfd, 1,
sgot->contents + got_offset);
else
for (p = output_bfd->sections; p ; p = p->next)
if ((p->flags & SEC_EXCLUDE) == 0
&& (p->flags & SEC_ALLOC) != 0
+ && elf_hash_table (info)->dynamic_relocs
&& !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
++count;
}
}
else
{
+ bfd_boolean reject_undefined
+ = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->root.other) != STV_DEFAULT);
+
(*info->callbacks->undefined_symbol)
(info, h->root.root.root.string, input_bfd,
- input_section, relocation->r_offset,
- (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
- || ELF_ST_VISIBILITY (h->root.other));
- return bfd_reloc_undefined;
+ input_section, relocation->r_offset, reject_undefined);
+
+ if (reject_undefined)
+ return bfd_reloc_undefined;
+
+ symbol = 0;
}
target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
return FALSE;
h = (struct elf_link_hash_entry *) bh;
+ h->mark = 1;
h->non_elf = 0;
h->def_regular = 1;
h->type = STT_SECTION;
if (h->root.type == bfd_link_hash_undefweak)
{
- /* Do not copy relocations for undefined weak symbols with
- non-default visibility. */
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
- || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
+ /* Do not copy relocations for undefined weak symbols that
+ we are not going to export. */
+ if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
do_copy = FALSE;
/* Make sure undefined weak symbols are output as a dynamic
the symbol to the stub location. This is required to make
function pointers compare as equal between the normal
executable and the shared library. */
- if (!h->def_regular)
+ if (!h->def_regular
+ && !bfd_is_abs_section (htab->sstubs->output_section))
{
hmips->needs_lazy_stub = TRUE;
htab->lazy_stub_count++;
}
else
{
- if (sreldyn && sreldyn->size > 0)
+ if (sreldyn && sreldyn->size > 0
+ && !bfd_is_abs_section (sreldyn->output_section))
{
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_REL, 0))
return FALSE;
got_address_high = ((got_address + 0x8000) >> 16) & 0xffff;
got_address_low = got_address & 0xffff;
+ /* The PLT sequence is not safe for N64 if .got.plt entry's address
+ cannot be loaded in two instructions. */
+ if (ABI_64_P (output_bfd)
+ && ((got_address + 0x80008000) & ~(bfd_vma) 0xffffffff) != 0)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%pA' entry VMA of %#" PRIx64 " outside the 32-bit range "
+ "supported; consider using `-Ttext-segment=...'"),
+ output_bfd,
+ htab->root.sgotplt->output_section,
+ (int64_t) got_address);
+ bfd_set_error (bfd_error_no_error);
+ return FALSE;
+ }
+
/* Initially point the .got.plt entry at the PLT header. */
- loc = (htab->root.sgotplt->contents + got_index * MIPS_ELF_GOT_SIZE (dynobj));
+ loc = (htab->root.sgotplt->contents
+ + got_index * MIPS_ELF_GOT_SIZE (dynobj));
if (ABI_64_P (output_bfd))
bfd_put_64 (output_bfd, header_address, loc);
else
sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
sym->st_value = 1;
}
- else if (strcmp (name, "_gp_disp") == 0 && ! NEWABI_P (output_bfd))
- {
- sym->st_shndx = SHN_ABS;
- sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
- sym->st_value = elf_gp (output_bfd);
- }
else if (SGI_COMPAT (output_bfd))
{
if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0
/* The PLT sequence is not safe for N64 if .got.plt's address can
not be loaded in two instructions. */
- BFD_ASSERT ((gotplt_value & ~(bfd_vma) 0x7fffffff) == 0
- || ~(gotplt_value | 0x7fffffff) == 0);
+ if (ABI_64_P (output_bfd)
+ && ((gotplt_value + 0x80008000) & ~(bfd_vma) 0xffffffff) != 0)
+ {
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: `%pA' start VMA of %#" PRIx64 " outside the 32-bit range "
+ "supported; consider using `-Ttext-segment=...'"),
+ output_bfd,
+ htab->root.sgotplt->output_section,
+ (int64_t) gotplt_value);
+ bfd_set_error (bfd_error_no_error);
+ return FALSE;
+ }
/* Install the PLT header. */
loc = htab->root.splt->contents;
: sizeof (Elf32_External_Rel)));
/* Adjust the section size too. Tools like the prelinker
can reasonably expect the values to the same. */
+ BFD_ASSERT (!bfd_is_abs_section (s->output_section));
elf_section_data (s->output_section)->this_hdr.sh_size
= dyn.d_un.d_val;
break;
fputs ("\n\tXPA ASE", file);
if (mask & AFL_ASE_MIPS16E2)
fputs ("\n\tMIPS16e2 ASE", file);
+ if (mask & AFL_ASE_CRC)
+ fputs ("\n\tCRC ASE", file);
+ if (mask & AFL_ASE_GINV)
+ fputs ("\n\tGINV ASE", file);
+ if (mask & AFL_ASE_LOONGSON_MMI)
+ fputs ("\n\tLoongson MMI ASE", file);
if (mask == 0)
fprintf (file, "\n\t%s", _("None"));
else if ((mask & ~AFL_ASE_MASK) != 0)
return tdata->abiflags_valid ? &tdata->abiflags : NULL;
}
+/* MIPS libc ABI versions, used with the EI_ABIVERSION ELF file header
+ field. Taken from `libc-abis.h' generated at GNU libc build time.
+ Using a MIPS_ prefix as other libc targets use different values. */
+enum
+{
+ MIPS_LIBC_ABI_DEFAULT = 0,
+ MIPS_LIBC_ABI_MIPS_PLT,
+ MIPS_LIBC_ABI_UNIQUE,
+ MIPS_LIBC_ABI_MIPS_O32_FP64,
+ MIPS_LIBC_ABI_MAX
+};
+
void
_bfd_mips_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
{
BFD_ASSERT (htab != NULL);
if (htab->use_plts_and_copy_relocs && !htab->is_vxworks)
- i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+ i_ehdrp->e_ident[EI_ABIVERSION] = MIPS_LIBC_ABI_MIPS_PLT;
}
- _bfd_elf_post_process_headers (abfd, link_info);
-
if (mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64
|| mips_elf_tdata (abfd)->abiflags.fp_abi == Val_GNU_MIPS_ABI_FP_64A)
- i_ehdrp->e_ident[EI_ABIVERSION] = 3;
+ i_ehdrp->e_ident[EI_ABIVERSION] = MIPS_LIBC_ABI_MIPS_O32_FP64;
+
+ _bfd_elf_post_process_headers (abfd, link_info);
}
int
-_bfd_mips_elf_compact_eh_encoding (struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+_bfd_mips_elf_compact_eh_encoding
+ (struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
{
return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
}
/* Return the opcode for can't unwind. */
int
-_bfd_mips_elf_cant_unwind_opcode (struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+_bfd_mips_elf_cant_unwind_opcode
+ (struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
{
return COMPACT_EH_CANT_UNWIND_OPCODE;
}