{
            return ptr > base ? ptr : base + ptr;
        };
        /* Iterate over all entries of the dynamic section until the
         * end of the symbol table is reached. This is indicated by
         * an entry with d_tag == DT_NULL.
         */
        size_t sym_cnt = 0;
        for (const auto * it = dyn_begin; it->d_tag != DT_NULL; ++it)
        {
            ElfW(Addr) base_address = correct_address(info->dlpi_addr, it->d_un.d_ptr);
            
            
            
            
            
            
            
            if (it->d_tag == DT_GNU_HASH)
            {
                
                const uint32_t * buckets = nullptr;
                const uint32_t * hashval = nullptr;
                const ElfW(Word) * hash = reinterpret_cast<const ElfW(Word) *>(base_address);
                buckets = hash + 4 + (hash[2] * sizeof(size_t) / 4);
                for (ElfW(Word) i = 0; i < hash[0]; ++i)
                    if (buckets[i] > sym_cnt)
                        sym_cnt = buckets[i];
                if (sym_cnt)
                {