diff --git a/core/elf.cc b/core/elf.cc index cb93204478..e471d1152a 100644 --- a/core/elf.cc +++ b/core/elf.cc @@ -789,6 +789,8 @@ elf64_hash(const char *name) return h; } +constexpr Elf64_Versym old_version_symbol_mask = Elf64_Versym(1) << 15; + Elf64_Sym* object::lookup_symbol_old(const char* name) { auto symtab = dynamic_ptr(DT_SYMTAB); @@ -842,10 +844,14 @@ Elf64_Sym* object::lookup_symbol_gnu(const char* name) if (idx == 0) { return nullptr; } + auto version_symtab = dynamic_exists(DT_VERSYM) ? dynamic_ptr(DT_VERSYM) : nullptr; do { if ((chains[idx] & ~1) != (hashval & ~1)) { continue; } + if (version_symtab && version_symtab[idx] & old_version_symbol_mask) { //Ignore old version symbols + continue; + } if (strcmp(&strtab[symtab[idx].st_name], name) == 0) { return &symtab[idx]; } diff --git a/include/osv/elf.hh b/include/osv/elf.hh index 775d8c8d5f..4725182e2b 100644 --- a/include/osv/elf.hh +++ b/include/osv/elf.hh @@ -194,6 +194,7 @@ enum { DT_RUNPATH = 29, // d_val The string table offset of a shared library search path string. DT_FLAGS = 30, // value is various flags, bits from DF_*. DT_FLAGS_1 = 0x6ffffffb, // value is various flags, bits from DF_1_*. + DT_VERSYM = 0x6ffffff0, // d_ptr Address of the version symbol table. DT_LOOS = 0x60000000, // Defines a range of dynamic table tags that are reserved for // environment-specific use. DT_HIOS = 0x6FFFFFFF, //