+2019-08-29 Mihailo Stojanovic <mihailo.stojanovic@rt-rk.com>
+
+ * elf/dl-addr.c (determine_info): Calculate the symbol index
+ using the newly defined ELF_MACHINE_HASH_SYMIDX macro.
+ * elf/dl-lookup.c (do_lookup_x): Ditto.
+ (_dl_setup_hash): Initialize MIPS xhash translation table.
+ * elf/elf.h (SHT_MIPS_XHASH): New define.
+ (DT_MIPS_XHASH): New define.
+ * sysdeps/generic/ldsodefs.h (ELF_MACHINE_GNU_HASH_ADDRIDX): New
+ define.
+ (ELF_MACHINE_HASH_SYMIDX): Ditto.
+ (ELF_MACHINE_XHASH_SETUP): Ditto.
+ * sysdeps/mips/ldsodefs.h (ELF_MACHINE_GNU_HASH_ADDRIDX): New
+ define.
+ (ELF_MACHINE_HASH_SYMIDX): Ditto.
+ (ELF_MACHINE_XHASH_SETUP): Ditto.
+ * sysdeps/mips/linkmap.h (struct link_map_machine): New member.
+ * sysdeps/unix/sysv/linux/mips/ldsodefs.h: Increment valid ABI
+ version.
+ * sysdeps/unix/sysv/linux/mips/libc-abis: New ABI version.
+
2019-08-29 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* sysdeps/sh/preconfigure.ac: New file.
ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
const ElfW(Sym) *matchsym = NULL;
- if (match->l_info[ADDRIDX (DT_GNU_HASH)] != NULL)
+ if (match->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL)
{
/* We look at all symbol table entries referenced by the hash
table. */
{
/* The hash table never references local symbols so
we can omit that test here. */
+ symndx = ELF_MACHINE_HASH_SYMIDX (match, hasharr);
if ((symtab[symndx].st_shndx != SHN_UNDEF
|| symtab[symndx].st_value != 0)
&& symtab[symndx].st_shndx != SHN_ABS
matchsym, addr)
&& symtab[symndx].st_name < strtabsize)
matchsym = (ElfW(Sym) *) &symtab[symndx];
-
- ++symndx;
}
while ((*hasharr++ & 1u) == 0);
}
do
if (((*hasharr ^ new_hash) >> 1) == 0)
{
- symidx = hasharr - map->l_gnu_chain_zero;
+ symidx = ELF_MACHINE_HASH_SYMIDX (map, hasharr);
sym = check_match (undef_name, ref, version, flags,
type_class, &symtab[symidx], symidx,
strtab, map, &versioned_sym,
{
Elf_Symndx *hash;
- if (__glibc_likely (map->l_info[ADDRIDX (DT_GNU_HASH)] != NULL))
+ if (__glibc_likely (map->l_info[ELF_MACHINE_GNU_HASH_ADDRIDX] != NULL))
{
Elf32_Word *hash32
- = (void *) D_PTR (map, l_info[ADDRIDX (DT_GNU_HASH)]);
+ = (void *) D_PTR (map, l_info[ELF_MACHINE_GNU_HASH_ADDRIDX]);
map->l_nbuckets = *hash32++;
Elf32_Word symbias = *hash32++;
Elf32_Word bitmask_nwords = *hash32++;
map->l_gnu_buckets = hash32;
hash32 += map->l_nbuckets;
map->l_gnu_chain_zero = hash32 - symbias;
+
+ /* Initialize MIPS xhash translation table. */
+ ELF_MACHINE_XHASH_SETUP (hash32, symbias, map);
+
return;
}
#define SHT_MIPS_EH_REGION 0x70000027
#define SHT_MIPS_XLATE_OLD 0x70000028
#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_XHASH 0x7000002b
/* Legal values for sh_flags field of Elf32_Shdr. */
in a PIE as it stores a relative offset from the address of the tag
rather than an absolute address. */
#define DT_MIPS_RLD_MAP_REL 0x70000035
-#define DT_MIPS_NUM 0x36
+/* GNU-style hash table with xlat. */
+#define DT_MIPS_XHASH 0x70000036
+#define DT_MIPS_NUM 0x37
/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
#define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
+/* Type of GNU hash which the machine uses. */
+#ifndef ELF_MACHINE_GNU_HASH_ADDRIDX
+# define ELF_MACHINE_GNU_HASH_ADDRIDX ADDRIDX (DT_GNU_HASH)
+#endif
+
+/* Calculate the index of a symbol in GNU hash. */
+#ifndef ELF_MACHINE_HASH_SYMIDX
+# define ELF_MACHINE_HASH_SYMIDX(map, hasharr) \
+ ((hasharr) - (map)->l_gnu_chain_zero)
+#endif
+
+/* Setup MIPS xhash. Defined only for MIPS. */
+#ifndef ELF_MACHINE_XHASH_SETUP
+# define ELF_MACHINE_XHASH_SETUP(hash32, symbias, map) \
+ ((void) (hash32), (void) (symbias), (void) (map))
+#endif
+
/* We use this macro to refer to ELF types independent of the native wordsize.
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
struct La_mips_64_regs;
struct La_mips_64_retval;
+#define ELF_MACHINE_GNU_HASH_ADDRIDX (DT_MIPS_XHASH - DT_LOPROC + DT_NUM)
+
+/* Calculate the index of a symbol in MIPS xhash. */
+#define ELF_MACHINE_HASH_SYMIDX(map, hasharr) \
+ ((map)->l_mach.mips_xlat_zero[(hasharr) - (map)->l_gnu_chain_zero])
+
+/* Setup MIPS xhash. */
+#define ELF_MACHINE_XHASH_SETUP(hash32, symbias, map) \
+ do \
+ { \
+ (hash32) += (map)->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val - (symbias); \
+ (map)->l_mach.mips_xlat_zero = (hash32) - (symbias); \
+ } \
+ while (0)
+
#define ARCH_PLTENTER_MEMBERS \
Elf32_Addr (*mips_o32_gnu_pltenter) (Elf32_Sym *, unsigned int, \
uintptr_t *, uintptr_t *, \
ElfW(Addr) plt; /* Address of .plt */
ElfW(Word) fpabi; /* FP ABI of the object */
unsigned int odd_spreg; /* Does the object require odd_spreg support? */
+ const Elf32_Word *mips_xlat_zero; /* .MIPS.xhash */
};
#undef VALID_ELF_ABIVERSION
#define VALID_ELF_ABIVERSION(osabi,ver) \
(ver == 0 \
- || (osabi == ELFOSABI_SYSV && ver < 5) \
+ || (osabi == ELFOSABI_SYSV && ver < 6) \
|| (osabi == ELFOSABI_GNU && ver < LIBC_ABI_MAX))
#endif /* ldsodefs.h */
MIPS_O32_FP64 mips*-*-linux*
# Absolute (SHN_ABS) symbols working correctly.
ABSOLUTE
+# GNU-style hash table with translation table.
+MIPS_XHASH