diff options
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | elf/dl-addr.c | 5 | ||||
-rw-r--r-- | elf/dl-lookup.c | 10 | ||||
-rw-r--r-- | elf/elf.h | 5 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 17 | ||||
-rw-r--r-- | sysdeps/mips/ldsodefs.h | 15 | ||||
-rw-r--r-- | sysdeps/mips/linkmap.h | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/mips/ldsodefs.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/mips/libc-abis | 2 |
9 files changed, 70 insertions, 8 deletions
@@ -1,3 +1,24 @@ +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. diff --git a/elf/dl-addr.c b/elf/dl-addr.c index 9d285d7..3f2297a 100644 --- a/elf/dl-addr.c +++ b/elf/dl-addr.c @@ -42,7 +42,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, 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. */ @@ -57,6 +57,7 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, { /* 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 @@ -65,8 +66,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, matchsym, addr) && symtab[symndx].st_name < strtabsize) matchsym = (ElfW(Sym) *) &symtab[symndx]; - - ++symndx; } while ((*hasharr++ & 1u) == 0); } diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index eb23cca..f9d6c36 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -403,7 +403,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash, 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, @@ -909,10 +909,10 @@ _dl_setup_hash (struct link_map *map) { 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++; @@ -927,6 +927,10 @@ _dl_setup_hash (struct link_map *map) 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; } @@ -1715,6 +1715,7 @@ typedef struct #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. */ @@ -1962,7 +1963,9 @@ typedef struct 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. */ diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index b1fc5c3..1e193b0 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -47,6 +47,23 @@ __BEGIN_DECLS #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) diff --git a/sysdeps/mips/ldsodefs.h b/sysdeps/mips/ldsodefs.h index f0acb02..95cd38e 100644 --- a/sysdeps/mips/ldsodefs.h +++ b/sysdeps/mips/ldsodefs.h @@ -26,6 +26,21 @@ struct La_mips_32_retval; 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 *, \ diff --git a/sysdeps/mips/linkmap.h b/sysdeps/mips/linkmap.h index 1fb9678..1e640c3 100644 --- a/sysdeps/mips/linkmap.h +++ b/sysdeps/mips/linkmap.h @@ -3,4 +3,5 @@ struct link_map_machine 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 */ }; diff --git a/sysdeps/unix/sysv/linux/mips/ldsodefs.h b/sysdeps/unix/sysv/linux/mips/ldsodefs.h index 28257f8..ce7b2f9 100644 --- a/sysdeps/unix/sysv/linux/mips/ldsodefs.h +++ b/sysdeps/unix/sysv/linux/mips/ldsodefs.h @@ -34,7 +34,7 @@ extern void _dl_static_init (struct link_map *map); #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 */ diff --git a/sysdeps/unix/sysv/linux/mips/libc-abis b/sysdeps/unix/sysv/linux/mips/libc-abis index eaea558..c0b67da 100644 --- a/sysdeps/unix/sysv/linux/mips/libc-abis +++ b/sysdeps/unix/sysv/linux/mips/libc-abis @@ -16,3 +16,5 @@ UNIQUE MIPS_O32_FP64 mips*-*-linux* # Absolute (SHN_ABS) symbols working correctly. ABSOLUTE +# GNU-style hash table with translation table. +MIPS_XHASH |