forked from OSchip/llvm-project
[ELF] - Never create .gnu_hash with NBuckets == 0.
Currently, we can end up with NBuckets==0 and android loader does not like it (PR36537). Seems we can go with a minimal amount of changes here for simplicity and be consistent with gold and so just always use >= 1 value for NBuckets. Differential revision: https://reviews.llvm.org/D44422 llvm-svn: 327481
This commit is contained in:
parent
271ed6eb0d
commit
2ab9362bf5
|
@ -1799,15 +1799,19 @@ void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
|
||||||
return SS->CopyRelSec == nullptr && !SS->NeedsPltAddr;
|
return SS->CopyRelSec == nullptr && !SS->NeedsPltAddr;
|
||||||
return !S.Sym->isDefined();
|
return !S.Sym->isDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Even if the hash table does not contain symbols, we still want to keep the
|
||||||
|
// section to indicate to a loader that the file exports no symbols. We can't
|
||||||
|
// have zero buckets because the android loader doesn't support that. We chose
|
||||||
|
// load factor 4 for the on-disk hash table. For each hash collision, the
|
||||||
|
// dynamic linker will compare a uint32_t hash value. Since the integer
|
||||||
|
// comparison is quite fast, we believe we can make the load factor even
|
||||||
|
// larger. 4 is just a conservative choice.
|
||||||
|
NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);
|
||||||
|
|
||||||
if (Mid == V.end())
|
if (Mid == V.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We chose load factor 4 for the on-disk hash table. For each hash
|
|
||||||
// collision, the dynamic linker will compare a uint32_t hash value.
|
|
||||||
// Since the integer comparison is quite fast, we believe we can make
|
|
||||||
// the load factor even larger. 4 is just a conservative choice.
|
|
||||||
NBuckets = std::max<size_t>((V.end() - Mid) / 4, 1);
|
|
||||||
|
|
||||||
for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
|
for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
|
||||||
Symbol *B = Ent.Sym;
|
Symbol *B = Ent.Sym;
|
||||||
uint32_t Hash = hashGnu(B->getName());
|
uint32_t Hash = hashGnu(B->getName());
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
// RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF %s
|
// RUN: llvm-readelf -l %t.so | FileCheck --check-prefix=DIFF %s
|
||||||
|
|
||||||
// CHECK-NOT: LOAD
|
// CHECK-NOT: LOAD
|
||||||
// CHECK: LOAD 0x000000 0x00000000 0x00000000 0x00169 0x00169 R 0x1000
|
// CHECK: LOAD 0x000000 0x00000000 0x00000000 0x0016d 0x0016d R 0x1000
|
||||||
// CHECK: LOAD 0x001000 0x00001000 0x00001000 0x{{.*}} 0x{{.*}} R E 0x1000
|
// CHECK: LOAD 0x001000 0x00001000 0x00001000 0x{{.*}} 0x{{.*}} R E 0x1000
|
||||||
// CHECK: LOAD 0x002000 0x00002000 0x00002000 0x{{.*}} 0x{{.*}} E 0x1000
|
// CHECK: LOAD 0x002000 0x00002000 0x00002000 0x{{.*}} 0x{{.*}} E 0x1000
|
||||||
// CHECK: LOAD 0x003000 0x00003000 0x00003000 0x00038 0x00038 RW 0x1000
|
// CHECK: LOAD 0x003000 0x00003000 0x00003000 0x00038 0x00038 RW 0x1000
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
// CHECK: 04 .dynamic
|
// CHECK: 04 .dynamic
|
||||||
|
|
||||||
// DIFF-NOT: LOAD
|
// DIFF-NOT: LOAD
|
||||||
// DIFF: LOAD 0x000000 0x00000000 0x00000000 0x00149 0x00149 R 0x1000
|
// DIFF: LOAD 0x000000 0x00000000 0x00000000 0x0014d 0x0014d R 0x1000
|
||||||
// DIFF: LOAD 0x001000 0x00001000 0x00001000 0x0000c 0x0000c R E 0x1000
|
// DIFF: LOAD 0x001000 0x00001000 0x00001000 0x0000c 0x0000c R E 0x1000
|
||||||
// DIFF: LOAD 0x002000 0x00002000 0x00002000 0x00038 0x00038 RW 0x1000
|
// DIFF: LOAD 0x002000 0x00002000 0x00002000 0x00038 0x00038 RW 0x1000
|
||||||
// DIFF-NOT: LOAD
|
// DIFF-NOT: LOAD
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
# CHECK-NEXT: Tag Type Name/Value
|
# CHECK-NEXT: Tag Type Name/Value
|
||||||
# CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120
|
# CHECK-NEXT: 0x0000000000000006 SYMTAB 0x120
|
||||||
# CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes)
|
# CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes)
|
||||||
# CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D0
|
# CHECK-NEXT: 0x0000000000000005 STRTAB 0x1D8
|
||||||
# CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes)
|
# CHECK-NEXT: 0x000000000000000A STRSZ 1 (bytes)
|
||||||
# CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138
|
# CHECK-NEXT: 0x000000006FFFFEF5 GNU_HASH 0x138
|
||||||
# CHECK-NEXT: 0x0000000000000004 HASH 0x150
|
# CHECK-NEXT: 0x0000000000000004 HASH 0x154
|
||||||
# CHECK-NEXT: 0x0000000000000000 NULL 0x0
|
# CHECK-NEXT: 0x0000000000000000 NULL 0x0
|
||||||
# CHECK-NEXT: ]
|
# CHECK-NEXT: ]
|
||||||
|
|
|
@ -51,12 +51,12 @@
|
||||||
# EMPTY-NEXT: }
|
# EMPTY-NEXT: }
|
||||||
# EMPTY-NEXT: ]
|
# EMPTY-NEXT: ]
|
||||||
# EMPTY: GnuHashTable {
|
# EMPTY: GnuHashTable {
|
||||||
# EMPTY-NEXT: Num Buckets: 0
|
# EMPTY-NEXT: Num Buckets: 1
|
||||||
# EMPTY-NEXT: First Hashed Symbol Index: 2
|
# EMPTY-NEXT: First Hashed Symbol Index: 2
|
||||||
# EMPTY-NEXT: Num Mask Words: 1
|
# EMPTY-NEXT: Num Mask Words: 1
|
||||||
# EMPTY-NEXT: Shift Count: 5
|
# EMPTY-NEXT: Shift Count: 5
|
||||||
# EMPTY-NEXT: Bloom Filter: [0x0]
|
# EMPTY-NEXT: Bloom Filter: [0x0]
|
||||||
# EMPTY-NEXT: Buckets: []
|
# EMPTY-NEXT: Buckets: [0]
|
||||||
# EMPTY-NEXT: Values: []
|
# EMPTY-NEXT: Values: []
|
||||||
# EMPTY-NEXT: }
|
# EMPTY-NEXT: }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue