this symbol. */
unsigned int possibly_dynamic_relocs;
+ /* If the R_MIPS_32, R_MIPS_REL32, or R_MIPS_64 reloc is against
+ a readonly section. */
+ boolean readonly_reloc;
+
/* The index of the first dynamic relocation (in the .rel.dyn
section) against this symbol. */
unsigned int min_dyn_reloc_index;
(abfd->xvec == &bfd_elf32_tradlittlemips_vec)) ? ict_none : \
((ABI_N32_P (abfd) || ABI_64_P (abfd)) ? ict_irix6 : ict_irix5))
#endif
-/* Whether we are trying to be compatible with IRIX at all. */
+/* Whether we are trying to be compatible with IRIX at all. */
#define SGI_COMPAT(abfd) \
(IRIX_COMPAT (abfd) != ict_none)
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
- /* 26 bit branch address. */
+ /* 26 bit jump address. */
HOWTO (R_MIPS_26, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
}
/* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
- generated when addreses are 64 bits. The upper 32 bits are a simle
+ generated when addresses are 64 bits. The upper 32 bits are a simple
sign extension. */
static bfd_reloc_status_type
bfd *abfd ATTRIBUTE_UNUSED;
asymbol *sym;
{
- if (SGI_COMPAT(abfd))
- return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
+ if (SGI_COMPAT (abfd))
+ return (sym->flags & BSF_SECTION_SYM) == 0;
else
return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
- || bfd_is_und_section (bfd_get_section (sym))
- || bfd_is_com_section (bfd_get_section (sym)));
+ || bfd_is_und_section (bfd_get_section (sym))
+ || bfd_is_com_section (bfd_get_section (sym)));
}
\f
/* Set the right machine number for a MIPS ELF file. This is used for
/* Irix 5 and 6 is broken. Object file symbol tables are not always
sorted correctly such that local symbols precede global symbols,
and the sh_info field in the symbol table is not always right. */
- elf_bad_symtab (abfd) = true;
+ if (SGI_COMPAT(abfd))
+ elf_bad_symtab (abfd) = true;
bfd_default_set_arch_mach (abfd, bfd_arch_mips,
elf_mips_mach (elf_elfheader (abfd)->e_flags));
case bfd_mach_mips4000:
case bfd_mach_mips4300:
+ case bfd_mach_mips4400:
+ case bfd_mach_mips4600:
val = E_MIPS_ARCH_3;
break;
val = E_MIPS_ARCH_3 | E_MIPS_MACH_4650;
break;
+ case bfd_mach_mips5000:
case bfd_mach_mips8000:
+ case bfd_mach_mips10000:
+ case bfd_mach_mips12000:
val = E_MIPS_ARCH_4;
break;
boolean
_bfd_mips_elf_section_from_bfd_section (abfd, hdr, sec, retval)
bfd *abfd ATTRIBUTE_UNUSED;
- Elf32_Internal_Shdr *hdr ATTRIBUTE_UNUSED;
+ Elf_Internal_Shdr *hdr ATTRIBUTE_UNUSED;
asection *sec;
int *retval;
{
not been set. -1 means there is no associated ifd. */
ret->esym.ifd = -2;
ret->possibly_dynamic_relocs = 0;
+ ret->readonly_reloc = false;
ret->min_dyn_reloc_index = 0;
ret->no_fn_stub = false;
ret->fn_stub = NULL;
REL_HDR is read before its REL_HDR2. */
rel_hdr = &elf_section_data (input_section)->rel_hdr;
if ((size_t) (rel - relocs)
- >= (rel_hdr->sh_size / rel_hdr->sh_entsize
- * bed->s->int_rels_per_ext_rel))
+ >= (NUM_SHDR_ENTRIES (rel_hdr) * bed->s->int_rels_per_ext_rel))
rel_hdr = elf_section_data (input_section)->rel_hdr2;
if (rel_hdr->sh_entsize == MIPS_ELF_REL_SIZE (input_bfd))
{
asection **n;
if (elf_bad_symtab (abfd))
- symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+ symcount = NUM_SHDR_ENTRIES (symtab_hdr);
else
symcount = symtab_hdr->sh_info;
n = (asection **) bfd_zalloc (abfd,
if (r_symndx < extsymoff)
h = NULL;
- else if (r_symndx >= extsymoff + (symtab_hdr->sh_size / symtab_hdr->sh_entsize))
+ else if (r_symndx >= extsymoff + NUM_SHDR_ENTRIES (symtab_hdr))
{
(*_bfd_error_handler)
(_("Malformed reloc detected for section %s"), name);
return false;
}
}
+#define MIPS_READONLY_SECTION (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
if (info->shared)
- /* When creating a shared object, we must copy these
- reloc types into the output file as R_MIPS_REL32
- relocs. We make room for this reloc in the
- .rel.dyn reloc section. */
- mips_elf_allocate_dynamic_relocations (dynobj, 1);
+ {
+ /* When creating a shared object, we must copy these
+ reloc types into the output file as R_MIPS_REL32
+ relocs. We make room for this reloc in the
+ .rel.dyn reloc section. */
+ mips_elf_allocate_dynamic_relocations (dynobj, 1);
+ if ((sec->flags & MIPS_READONLY_SECTION)
+ == MIPS_READONLY_SECTION)
+ /* We tell the dynamic linker that there are
+ relocations against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
else
{
struct mips_elf_link_hash_entry *hmips;
defined in a dynamic object. */
hmips = (struct mips_elf_link_hash_entry *) h;
++hmips->possibly_dynamic_relocs;
+ if ((sec->flags & MIPS_READONLY_SECTION)
+ == MIPS_READONLY_SECTION)
+ /* We need it to tell the dynamic linker if there
+ are relocations against the text segment. */
+ hmips->readonly_reloc = true;
}
/* Even though we don't directly need a GOT entry for
dirmips = (struct mips_elf_link_hash_entry *) dir;
indmips = (struct mips_elf_link_hash_entry *) 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))
if (! info->relocateable
&& hmips->possibly_dynamic_relocs != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
- mips_elf_allocate_dynamic_relocations (dynobj,
- hmips->possibly_dynamic_relocs);
+ {
+ mips_elf_allocate_dynamic_relocations (dynobj,
+ hmips->possibly_dynamic_relocs);
+ if (hmips->readonly_reloc)
+ /* We tell the dynamic linker that there are relocations
+ against the text segment. */
+ info->flags |= DF_TEXTREL;
+ }
/* For a function, create a stub, if allowed. */
if (! hmips->no_fn_stub
int i;
bfd_size_type loadable_size = 0;
bfd_size_type local_gotno;
- struct _bfd *sub;
+ bfd *sub;
BFD_ASSERT (elf_section_data (s) != NULL);
g = (struct mips_got_info *) elf_section_data (s)->tdata;
return false;
}
}
+
if (reltext && SGI_COMPAT (output_bfd))
+ info->flags |= DF_TEXTREL;
+
+ if ((info->flags & DF_TEXTREL) != 0)
{
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_TEXTREL, 0))
return false;
- info->flags |= DF_TEXTREL;
}
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_PLTGOT, 0))
return true;
}
\f
+/* Support for core dump NOTE sections */
+static boolean
+_bfd_elf32_mips_grok_prstatus (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ int offset;
+ int raw_size;
+
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 256: /* Linux/MIPS */
+ /* pr_cursig */
+ elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+
+ /* pr_pid */
+ elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+
+ /* pr_reg */
+ offset = 72;
+ raw_size = 180;
+
+ break;
+ }
+
+ /* Make a ".reg/999" section. */
+ return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+ raw_size, note->descpos + offset);
+}
+
+static boolean _bfd_elf32_mips_grok_psinfo (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+{
+ switch (note->descsz)
+ {
+ default:
+ return false;
+
+ case 128: /* Linux/MIPS elf_prpsinfo */
+ elf_tdata (abfd)->core_program
+ = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
+ elf_tdata (abfd)->core_command
+ = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
+ }
+
+ /* Note that for some reason, a spurious space is tacked
+ onto the end of the args in some (at least one anyway)
+ implementations, so strip it off if it exists. */
+
+ {
+ char *command = elf_tdata (abfd)->core_command;
+ int n = strlen (command);
+
+ if (0 < n && command[n - 1] == ' ')
+ command[n - 1] = '\0';
+ }
+
+ return true;
+}
+\f
/* This is almost identical to bfd_generic_get_... except that some
MIPS relocations need to be handled specially. Sigh. */
_bfd_mips_elf_copy_indirect_symbol
#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
+#define elf_backend_grok_prstatus _bfd_elf32_mips_grok_prstatus
+#define elf_backend_grok_psinfo _bfd_elf32_mips_grok_psinfo
#define bfd_elf32_bfd_is_local_label_name \
mips_elf_is_local_label_name