Question

In a .hash section, for some x, if chain[x] != SHN_UNDEF, it should hold hash(name(bucket[x])) === hash(name(bucket[chain[x]])) % nbucket

But why it's not the case for my shared object file?
For example, name(bucket[224]) == "_ZN9VADEnergyD0Ev" whose (ELF hash % nbucket) is 224,
name(bucket[8]) == "speex_bits_write_whole_bytes" whose (ELF hash % nbucket) is 8,
but chain[224] == 8.

(the file is avalible here)

Or my code for reading elf is wrong?

nbucket = ((int *)hash)[0];
nchain = ((int *)hash)[1];
memcpy(bucket, hash + 8, nbucket * 4);
memcpy(succ, hash + nbucket * 4 + 8, nchain * 4);

for (i = 0; i < nbucket; i++) {
    printf("%d %d\n", bucket[i], succ[i]);
    if (bucket[i] && succ[i])
        pred[succ[i]] = i;
}

printf("%d %d\n", nbucket, nchain);
#define sym_name(x, symtbl, strtbl) (strtbl + symtbl[x].st_name)
for (i = 0; i < nbucket; i++) {
    if (pred[i] == 0) {
        printf("=======\n");
        for (j = i; j; j = succ[j]) {
            char *sname = sym_name(bucket[j], dynsym, dynstr);
            printf("%d,succ=%d ", j, succ[j]);
            printf("%d:%s\n", _dl_elf_hash(sname) % nbucket, sname);
        }
    }
}
Was it helpful?

Solution

It's my fault. It should be

hash(name(bucket[x])) === hash(name(chain[bucket[x]])) % nbucket

and

nbucket = ((int *)hash)[0];
nchain = ((int *)hash)[1];
memcpy(bucket, hash + 8, nbucket * 4);
memcpy(succ, hash + nbucket * 4 + 8, nchain * 4);

for (i = 0; i < nbucket; i++) {
    printf("%d %d\n", bucket[i], succ[i]);
    if (bucket[i] && succ[i])
        pred[succ[i]] = i;
}

printf("%d %d\n", nbucket, nchain);
#define sym_name(x, symtbl, strtbl) (strtbl + symtbl[x].st_name)
for (i = 0; i < nbucket; i++) {
    printf("=======\n");
    for (j = bucket[i]; j; j = succ[j]) {
        char *sname = sym_name(j, dynsym, dynstr);
        printf("%d,succ=%d ", j, succ[j]);
        printf("%d:%s\n", _dl_elf_hash(sname) % nbucket, sname);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top