+2019-08-09 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>
+
+ * elf-bfd.h (struct elf_backend_data): New members.
+ * elflink.c (_bfd_elf_link_create_dynamic_sections): Create
+ .gnu.hash section if necessary.
+ (struct collect_gnu_hash_codes): New member.
+ (elf_gnu_hash_process_symidx): New function name.
+ (elf_renumber_gnu_hash_syms): Ignore local and undefined
+ symbols. Record xlat location for every symbol which should have
+ a .MIPS.xhash entry.
+ (bfd_elf_size_dynamic_sections): Add DT_GNU_HASH dynamic tag to
+ dynamic section if necessary.
+ (GNU_HASH_SECTION_NAME): New define.
+ (bfd_elf_size_dynsym_hash_dynstr): Get .MIPS.xhash section.
+ Update the section size info.
+ * elfxx-mips.c (struct mips_elf_hash_sort_data): New members.
+ (struct mips_elf_link_hash_entry): New member.
+ (mips_elf_link_hash_newfunc): Initialize .MIPS.xhash translation
+ table location.
+ (mips_elf_sort_hash_table): Initialize the pointer to the
+ .MIPS.xhash section.
+ (mips_elf_sort_hash_table_f): Populate the .MIPS.xhash
+ translation table entry with the symbol dynindx.
+ (_bfd_mips_elf_section_from_shdr): Add SHT_MIPS_XHASH.
+ (_bfd_mips_elf_fake_sections): Initialize .MIPS.xhash section
+ info.
+ (_bfd_mips_elf_create_dynamic_sections): Create .MIPS.xhash
+ section.
+ (_bfd_mips_elf_size_dynamic_sections): Add DT_MIPS_XHASH tag to
+ dynamic section.
+ (_bfd_mips_elf_finish_synamic_sections): Add DT_MIPS_XHASH.
+ (_bfd_mips_elf_final_write_processing): Set .MIPS.xhash section
+ sh_link info.
+ (_bfd_mips_elf_get_target_dtag): Get DT_MIPS_XHASH tag.
+ (MIPS_LIBC_ABI_XHASH): New ABI version enum value.
+ (_bfd_mips_post_process_headers): Mark the ABI version as
+ MIPS_LIBC_ABI_XHASH if there exists a .MIPS.xhash section,
+ but not a .hash section.
+ (_bfd_mips_elf_record_xhash_symbol): New function. Record a
+ position in the translation table, associated with the hash
+ entry.
+ * elfxx-mips.h (literal_reloc_p): Define
+ elf_backend_record_xhash_symbol backend hook.
+ * elfxx-target.h: Initialize elf_backend_record_xhash_symbol
+ backend hook.
+
2019-08-07 Jose E. Marchesi <jose.marchesi@oracle.com>
* elf64-bpf.c (bpf_elf_relocate_section): New function.
/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
+ /* If non-NULL, called to register the location of XLAT_LOC within
+ .MIPS.xhash at which real final dynindx for H will be written.
+ If XLAT_LOC is zero, the symbol is not included in
+ .MIPS.xhash and no dynindx will be written. */
+ void (*record_xhash_symbol)
+ (struct elf_link_hash_entry *h, bfd_vma xlat_loc);
+
/* Return TRUE if type is a function symbol type. */
bfd_boolean (*is_function_type) (unsigned int type);
elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
}
- if (info->emit_gnu_hash)
+ if (info->emit_gnu_hash && bed->record_xhash_symbol == NULL)
{
s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash",
flags | SEC_READONLY);
unsigned long int *counts;
bfd_vma *bitmask;
bfd_byte *contents;
+ bfd_size_type xlat;
long int min_dynindx;
unsigned long int bucketcount;
unsigned long int symindx;
}
/* This function will be called though elf_link_hash_traverse to do
- final dynaminc symbol renumbering. */
+ final dynamic symbol renumbering in case of .gnu.hash.
+ If using .MIPS.xhash, invoke record_xhash_symbol to add symbol index
+ to the translation table. */
static bfd_boolean
-elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
+elf_gnu_hash_process_symidx (struct elf_link_hash_entry *h, void *data)
{
struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data;
unsigned long int bucket;
if (! (*s->bed->elf_hash_symbol) (h))
{
if (h->dynindx >= s->min_dynindx)
- h->dynindx = s->local_indx++;
+ {
+ if (s->bed->record_xhash_symbol != NULL)
+ {
+ (*s->bed->record_xhash_symbol) (h, 0);
+ s->local_indx++;
+ }
+ else
+ h->dynindx = s->local_indx++;
+ }
return TRUE;
}
bfd_put_32 (s->output_bfd, val,
s->contents + (s->indx[bucket] - s->symindx) * 4);
--s->counts[bucket];
- h->dynindx = s->indx[bucket]++;
+ if (s->bed->record_xhash_symbol != NULL)
+ {
+ bfd_vma xlat_loc = s->xlat + (s->indx[bucket]++ - s->symindx) * 4;
+
+ (*s->bed->record_xhash_symbol) (h, xlat_loc);
+ }
+ else
+ h->dynindx = s->indx[bucket]++;
return TRUE;
}
if ((info->emit_hash
&& !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0))
|| (info->emit_gnu_hash
- && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0))
+ && (bed->record_xhash_symbol == NULL
+ && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0)))
|| !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0)
|| !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
|| !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
elf_hash_table (info)->text_index_section = found;
}
+#define GNU_HASH_SECTION_NAME(bed) \
+ (bed)->record_xhash_symbol != NULL ? ".MIPS.xhash" : ".gnu.hash"
+
bfd_boolean
bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
{
return FALSE;
}
- s = bfd_get_linker_section (dynobj, ".gnu.hash");
+ s = bfd_get_linker_section (dynobj, GNU_HASH_SECTION_NAME (bed));
BFD_ASSERT (s != NULL);
if (cinfo.nsyms == 0)
{
- /* Empty .gnu.hash section is special. */
+ /* Empty .gnu.hash or .MIPS.xhash section is special. */
BFD_ASSERT (cinfo.min_dynindx == -1);
free (cinfo.hashcodes);
s->size = 5 * 4 + bed->s->arch_size / 8;
s->size = (4 + bucketcount + cinfo.nsyms) * 4;
s->size += cinfo.maskbits / 8;
+ if (bed->record_xhash_symbol != NULL)
+ s->size += cinfo.nsyms * 4;
contents = (unsigned char *) bfd_zalloc (output_bfd, s->size);
if (contents == NULL)
{
cinfo.contents = contents;
- /* Renumber dynamic symbols, populate .gnu.hash section. */
+ cinfo.xlat = contents + cinfo.nsyms * 4 - s->contents;
+ /* Renumber dynamic symbols, if populating .gnu.hash section.
+ If using .MIPS.xhash, populate the translation table. */
elf_link_hash_traverse (elf_hash_table (info),
- elf_renumber_gnu_hash_syms, &cinfo);
+ elf_gnu_hash_process_symidx, &cinfo);
contents = s->contents + 16;
for (i = 0; i < maskwords; ++i)
/* The greatest dynamic symbol table index corresponding to an external
symbol without a GOT entry. */
bfd_size_type max_non_got_dynindx;
+ /* If non-NULL, output BFD for .MIPS.xhash finalization. */
+ bfd *output_bfd;
+ /* If non-NULL, pointer to contents of .MIPS.xhash for filling in
+ real final dynindx. */
+ bfd_byte *mipsxhash;
};
/* We make up to two PLT entries if needed, one for standard MIPS code
being called returns a floating point value. */
asection *call_fp_stub;
+ /* If non-zero, location in .MIPS.xhash to write real final dynindx. */
+ bfd_vma mipsxhash_loc;
+
/* The highest GGA_* value that satisfies all references to this symbol. */
unsigned int global_got_area : 2;
ret->fn_stub = NULL;
ret->call_stub = NULL;
ret->call_fp_stub = NULL;
+ ret->mipsxhash_loc = 0;
ret->global_got_area = GGA_NONE;
ret->got_only_for_calls = TRUE;
ret->readonly_reloc = FALSE;
at the head of the table; see `_bfd_elf_link_renumber_dynsyms'. */
hsd.max_local_dynindx = count_section_dynsyms (abfd, info) + 1;
hsd.max_non_got_dynindx = htab->root.local_dynsymcount + 1;
+ hsd.output_bfd = abfd;
+ if (htab->root.dynobj != NULL
+ && htab->root.dynamic_sections_created
+ && info->emit_gnu_hash)
+ {
+ asection *s = bfd_get_linker_section (htab->root.dynobj, ".MIPS.xhash");
+ BFD_ASSERT (s != NULL);
+ hsd.mipsxhash = s->contents;
+ BFD_ASSERT (hsd.mipsxhash != NULL);
+ }
+ else
+ hsd.mipsxhash = NULL;
mips_elf_link_hash_traverse (htab, mips_elf_sort_hash_table_f, &hsd);
/* There should have been enough room in the symbol table to
break;
}
+ /* Populate the .MIPS.xhash translation table entry with
+ the symbol dynindx. */
+ if (h->mipsxhash_loc != 0 && hsd->mipsxhash != NULL)
+ bfd_put_32 (hsd->output_bfd, h->root.dynindx,
+ hsd->mipsxhash + h->mipsxhash_loc);
+
return TRUE;
}
&& ! CONST_STRNEQ (name, ".MIPS.post_rel"))
return FALSE;
break;
+ case SHT_MIPS_XHASH:
+ if (strcmp (name, ".MIPS.xhash") != 0)
+ return FALSE;
default:
break;
}
hdr->sh_flags |= SHF_ALLOC;
hdr->sh_entsize = 8;
}
+ else if (strcmp (name, ".MIPS.xhash") == 0)
+ {
+ hdr->sh_type = SHT_MIPS_XHASH;
+ hdr->sh_flags |= SHF_ALLOC;
+ hdr->sh_entsize = get_elf_backend_data(abfd)->s->arch_size == 64 ? 0 : 4;
+ }
/* The generic elf_fake_sections will set up REL_HDR using the default
kind of relocations. We used to set up a second header for the
return FALSE;
}
+ /* Create .MIPS.xhash section. */
+ if (info->emit_gnu_hash)
+ s = bfd_make_section_anyway_with_flags (abfd, ".MIPS.xhash",
+ flags | SEC_READONLY);
+
/* On IRIX5, we adjust add some additional symbols and change the
alignments of several sections. There is no ABI documentation
indicating that this is necessary on IRIX6, nor any evidence that
if (! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_GOTSYM, 0))
return FALSE;
+ if (info->emit_gnu_hash
+ && ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_XHASH, 0))
+ return FALSE;
+
if (IRIX_COMPAT (dynobj) == ict_irix5
&& ! MIPS_ELF_ADD_DYNAMIC_ENTRY (info, DT_MIPS_HIPAGENO, 0))
return FALSE;
swap_out_p = FALSE;
break;
+ case DT_MIPS_XHASH:
+ name = ".MIPS.xhash";
+ s = bfd_get_linker_section (dynobj, name);
+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
+ break;
+
default:
swap_out_p = FALSE;
if (htab->is_vxworks
(*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
break;
+ case SHT_MIPS_XHASH:
+ sec = bfd_get_section_by_name (abfd, ".dynsym");
+ if (sec != NULL)
+ (*hdrpp)->sh_link = elf_section_data (sec)->this_idx;
}
}
}
return "DT_MIPS_PLTGOT";
case DT_MIPS_RWPLT:
return "DT_MIPS_RWPLT";
+ case DT_MIPS_XHASH:
+ return "DT_MIPS_XHASH";
}
}
{ STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
{ STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_MIPS_GPREL },
{ STRING_COMMA_LEN (".ucode"), 0, SHT_MIPS_UCODE, 0 },
+ { STRING_COMMA_LEN (".MIPS.xhash"), 0, SHT_MIPS_XHASH, SHF_ALLOC },
{ NULL, 0, 0, 0, 0 }
};
MIPS_LIBC_ABI_UNIQUE,
MIPS_LIBC_ABI_MIPS_O32_FP64,
MIPS_LIBC_ABI_ABSOLUTE,
+ MIPS_LIBC_ABI_XHASH,
MIPS_LIBC_ABI_MAX
};
if (htab != NULL && htab->use_absolute_zero && htab->gnu_target)
i_ehdrp->e_ident[EI_ABIVERSION] = MIPS_LIBC_ABI_ABSOLUTE;
+ /* Mark that we need support for .MIPS.xhash in the dynamic linker,
+ if it is the only hash section that will be created. */
+ if (link_info && link_info->emit_gnu_hash && !link_info->emit_hash)
+ i_ehdrp->e_ident[EI_ABIVERSION] = MIPS_LIBC_ABI_XHASH;
+
_bfd_elf_post_process_headers (abfd, link_info);
}
{
return COMPACT_EH_CANT_UNWIND_OPCODE;
}
+
+/* Record a position XLAT_LOC in the xlat translation table, associated with
+ the hash entry H. The entry in the translation table will later be
+ populated with the real symbol dynindx. */
+
+void
+_bfd_mips_elf_record_xhash_symbol (struct elf_link_hash_entry *h,
+ bfd_vma xlat_loc)
+{
+ struct mips_elf_link_hash_entry *hmips;
+
+ hmips = (struct mips_elf_link_hash_entry *) h;
+ hmips->mipsxhash_loc = xlat_loc;
+}
extern int _bfd_mips_elf_compact_eh_encoding (struct bfd_link_info *);
extern int _bfd_mips_elf_cant_unwind_opcode (struct bfd_link_info *);
+extern void _bfd_mips_elf_record_xhash_symbol
+ (struct elf_link_hash_entry *h, bfd_vma xlat_loc);
+
static inline bfd_boolean
gprel16_reloc_p (unsigned int r_type)
{
#define elf_backend_post_process_headers _bfd_mips_post_process_headers
#define elf_backend_compact_eh_encoding _bfd_mips_elf_compact_eh_encoding
#define elf_backend_cant_unwind_opcode _bfd_mips_elf_cant_unwind_opcode
+#define elf_backend_record_xhash_symbol _bfd_mips_elf_record_xhash_symbol
#define elf_backend_always_renumber_dynsyms TRUE
#define elf_backend_hash_symbol _bfd_elf_hash_symbol
#endif
+#ifndef elf_backend_record_xhash_symbol
+#define elf_backend_record_xhash_symbol NULL
+#endif
+
#ifndef elf_backend_is_function_type
#define elf_backend_is_function_type _bfd_elf_is_function_type
#endif
elf_backend_common_section,
elf_backend_merge_symbol,
elf_backend_hash_symbol,
+ elf_backend_record_xhash_symbol,
elf_backend_is_function_type,
elf_backend_maybe_function_sym,
elf_backend_get_reloc_section,
+2019-08-09 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>
+
+ * readelf.c (get_mips_dynamic_type): Return MIPS_XHASH dynamic type.
+ (get_mips_section_type_name): Return MI{S_XHASH name string.
+ (dynamic_section_mips_val): Initialize the .MIPS.xhash dynamic
+ info.
+ (process_symbol_table): Initialize the .MIPS.xhash section
+ pointer. Adjust the readelf output to support the new section.
+ (process_object): Set the .MIPS.xhash dynamic info to zero.
+
2019-08-09 Tamar Christina <tamar.christina@arm.com>
* testsuite/binutils-all/arm/in-order-all.d: Skip on pe, wince, coff.
static char program_interpreter[PATH_MAX];
static bfd_vma dynamic_info[DT_ENCODING];
static bfd_vma dynamic_info_DT_GNU_HASH;
+static bfd_vma dynamic_info_DT_MIPS_XHASH;
static bfd_vma version_info[16];
static Elf_Internal_Dyn * dynamic_section;
static elf_section_list * symtab_shndx_list;
(ADDR) &= ~1; \
} \
while (0)
+
+/* Get the correct GNU hash section name. */
+#define GNU_HASH_SECTION_NAME \
+ dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
\f
/* Print a BFD_VMA to an internal buffer, for use in error messages.
BFD_FMA_FMT can't be used in translated strings. */
case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
case DT_MIPS_RWPLT: return "MIPS_RWPLT";
+ case DT_MIPS_XHASH: return "MIPS_XHASH";
default:
return NULL;
}
case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
+ case SHT_MIPS_XHASH: return "MIPS_XHASH";
default:
break;
}
print_vma (entry->d_un.d_val, DEC);
break;
+ case DT_MIPS_XHASH:
+ dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
+ dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
+ /* Falls through. */
+
default:
print_vma (entry->d_un.d_ptr, PREFIX_HEX);
}
bfd_vma ngnubuckets = 0;
bfd_vma * gnubuckets = NULL;
bfd_vma * gnuchains = NULL;
+ bfd_vma * mipsxlat = NULL;
bfd_vma gnusymidx = 0;
bfd_size_type ngnuchains = 0;
gnuchains = get_dynamic_data (filedata, maxchain, 4);
ngnuchains = maxchain;
+ if (gnuchains == NULL)
+ goto no_gnu_hash;
+
+ if (dynamic_info_DT_MIPS_XHASH)
+ {
+ if (fseek (filedata->handle,
+ (archive_file_offset
+ + offset_from_vma (filedata, (buckets_vma
+ + 4 * (ngnubuckets
+ + maxchain)), 4)),
+ SEEK_SET))
+ {
+ error (_("Unable to seek to start of dynamic information\n"));
+ goto no_gnu_hash;
+ }
+
+ mipsxlat = get_dynamic_data (filedata, maxchain, 4);
+ }
+
no_gnu_hash:
+ if (dynamic_info_DT_MIPS_XHASH && mipsxlat == NULL)
+ {
+ free (gnuchains);
+ gnuchains = NULL;
+ }
if (gnuchains == NULL)
{
free (gnubuckets);
if (dynamic_info_DT_GNU_HASH)
{
- printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
+ printf (_("\nSymbol table of `%s' for image:\n"),
+ GNU_HASH_SECTION_NAME);
if (is_32bit_elf)
printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
else
do
{
- print_dynamic_symbol (filedata, si, hn);
+ if (dynamic_info_DT_MIPS_XHASH)
+ print_dynamic_symbol (filedata, mipsxlat[off], hn);
+ else
+ print_dynamic_symbol (filedata, si, hn);
si++;
}
while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
unsigned long nzero_counts = 0;
unsigned long nsyms = 0;
- printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
+ printf (ngettext ("\nHistogram for `%s' bucket list length "
"(total of %lu bucket):\n",
- "\nHistogram for `.gnu.hash' bucket list length "
+ "\nHistogram for `%s' bucket list length "
"(total of %lu buckets):\n",
(unsigned long) ngnubuckets),
+ GNU_HASH_SECTION_NAME,
(unsigned long) ngnubuckets);
lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
free (lengths);
free (gnubuckets);
free (gnuchains);
+ free (mipsxlat);
}
return TRUE;
for (i = ARRAY_SIZE (dynamic_info); i--;)
dynamic_info[i] = 0;
dynamic_info_DT_GNU_HASH = 0;
+ dynamic_info_DT_MIPS_XHASH = 0;
/* Process the file. */
if (show_name)
+2019-08-09 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>
+
+ * elf/mips.h (SHT_GNU_XHASH): New define.
+ (DT_GNU_XHASH): New define.
+
2019-08-08 Yoshinori Sato <ysato@users.sourceforge.jp>
* opcode/h8300.h (EXPAND_UNOP_EXTENDED_B): Add MODEL.
/* ABI related flags section. */
#define SHT_MIPS_ABIFLAGS 0x7000002a
+/* GNU style symbol hash table with xlat. */
+#define SHT_MIPS_XHASH 0x7000002b
+
/* A section of type SHT_MIPS_LIBLIST contains an array of the
following structure. The sh_link field is the section index of the
string table. The sh_info field is the number of entries in the
/* Relative offset of run time loader map, used for debugging. */
#define DT_MIPS_RLD_MAP_REL 0x70000035
+
+/* Address of .MIPS.xhash section. */
+#define DT_MIPS_XHASH 0x70000036
\f
/* Flags which may appear in a DT_MIPS_FLAGS entry. */
+2019-08-09 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>
+
+ * emulparams/elf32bmip.sh: Add .MIPS.xhash section.
+ * emulparams/elf32bmipn32-defs.sh: Add .MIPS.xhash section.
+ * emulparams/elf64bmip-defs.sh: Add .MIPS.xhash section.
+ * emultempl/mipself.em: Remove mips_after_parse function.
+ * testsuite/ld-elf/hash.d: Update comment.
+ * testsuite/ld-mips-elf/hash1.d: New test.
+ * testsuite/ld-mips-elf/hash1.s: Ditto.
+ * testsuite/ld-mips-elf/hash1a.d: Remove.
+ * testsuite/ld-mips-elf/hash1b.d: Ditto.
+ * testsuite/ld-mips-elf/hash1c.d: Ditto
+ * testsuite/ld-mips-elf/hash2.d: New test.
+ * testsuite/ld-mips-elf/mips-elf.exp: New tests.
+ * testsuite/ld-mips-elf/start.s: New test.
+
2019-08-08 Nick Clifton <nickc@redhat.com>
PR 24887
INITIAL_READONLY_SECTIONS="${INITIAL_READONLY_SECTIONS}
.MIPS.abiflags ${RELOCATING-0} : { *(.MIPS.abiflags) }
.reginfo ${RELOCATING-0} : { *(.reginfo) }
+ .MIPS.xhash ${RELOCATING-0} : { *(.MIPS.xhash) }
"
OTHER_TEXT_SECTIONS='*(.mips16.fn.*) *(.mips16.call.*)'
# Unlike most targets, the MIPS backend puts all dynamic relocations
fi
INITIAL_READONLY_SECTIONS="${INITIAL_READONLY_SECTIONS}
.MIPS.abiflags ${RELOCATING-0} : { *(.MIPS.abiflags) }
+ .MIPS.xhash ${RELOCATING-0} : { *(.MIPS.xhash) }
.reginfo ${RELOCATING-0} : { *(.reginfo) }"
# Discard any .MIPS.content* or .MIPS.events* sections. The linker
# doesn't know how to adjust them.
COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
INITIAL_READONLY_SECTIONS="
.MIPS.abiflags ${RELOCATING-0} : { *(.MIPS.abiflags) }
+ .MIPS.xhash ${RELOCATING-0} : { *(.MIPS.xhash) }
.MIPS.options : { *(.MIPS.options) }
"
static bfd_boolean ignore_branch_isa;
static bfd_boolean compact_branches;
-static void
-mips_after_parse (void)
-{
- /* .gnu.hash and the MIPS ABI require .dynsym to be sorted in different
- ways. .gnu.hash needs symbols to be grouped by hash code whereas the
- MIPS ABI requires a mapping between the GOT and the symbol table. */
- if (link_info.emit_gnu_hash)
- {
- einfo (_("%X%P: .gnu.hash is incompatible with the MIPS ABI\n"));
- link_info.emit_hash = TRUE;
- link_info.emit_gnu_hash = FALSE;
- }
- gld${EMULATION_NAME}_after_parse ();
-}
-
struct hook_stub_info
{
lang_statement_list_type add;
break;
'
-LDEMUL_AFTER_PARSE=mips_after_parse
LDEMUL_BEFORE_ALLOCATION=mips_before_allocation
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=mips_create_output_section_statements
#ld: -shared --hash-style=gnu
#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi
#xfail: mips*-*-*
-# GNU hash is not supported for MIPS targets due to psABI restrictions
+# MIPS uses a different style of GNU hash due to psABI restrictions
# on dynsym table ordering.
#...
--- /dev/null
+#source: hash1.s
+#readelf: -d -I
+#ld: -nostdlib -shared --hash-style=gnu
+#target: [check_shared_lib_support]
+#xfail: mips*-*-irix*
+
+#...
+ +0x[0-9a-z]+ +\(MIPS_XHASH\) +0x[0-9a-z]+
+#...
+ +1 +1 +\( 50.0%\) +100.0%
+#...
- nop
+.globl foo
+
+.text
+
+foo:
+ jr $ra
+ nop
+++ /dev/null
-#source: hash1.s
-#ld: -shared --hash-style=sysv
-#objdump: -dr
-#target: [check_shared_lib_support]
-#pass
+++ /dev/null
-#source: hash1.s
-#ld: -shared --hash-style=both
-#target: [check_shared_lib_support]
-#error: .gnu.hash is incompatible with the MIPS ABI
+++ /dev/null
-#source: hash1.s
-#ld: -shared --hash-style=gnu
-#target: [check_shared_lib_support]
-#error: .gnu.hash is incompatible with the MIPS ABI
--- /dev/null
+#source: start.s
+#readelf: -d -s -D
+#ld: -shared --hash-style=gnu
+#target: [check_shared_lib_support]
+#xfail: mips*-*-irix*
+
+#...
+ +0x[0-9a-z]+ +\(MIPS_XHASH\) +0x[0-9a-z]+
+#...
+ +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] _start
+#...
+ +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] main
+#...
+ +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] start
+#...
+ +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] __start
+#...
run_dump_test_n32 "emit-relocs-1" {{as -EB} {ld -EB}}
-run_dump_test "hash1a"
-run_dump_test "hash1b"
-run_dump_test "hash1c"
+run_dump_test "hash1"
+run_dump_test "hash2"
if { $linux_gnu && $has_abi(o32) } {
# The number of symbols that are always included in the symbol table
--- /dev/null
+ .text
+ .globl start
+start:
+ .globl _start
+_start:
+ .globl __start
+__start:
+ .globl main
+main:
+ .globl _main
+_main:
+ .dc.a 0