Skip to content

Commit 8f0f7db

Browse files
author
Georgii Rymar
committed
[llvm-readobj] - Split the printHashSymbols. NFCI.
This introduces `printHashTableSymbols` and `printGNUHashTableSymbols` to split the `printHashSymbols`. It makes the code more readable and consistent. Differential revision: https://reviews.llvm.org/D83040
1 parent cdf2eef commit 8f0f7db

File tree

1 file changed

+78
-65
lines changed

1 file changed

+78
-65
lines changed

llvm/tools/llvm-readobj/ELFDumper.cpp

Lines changed: 78 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,10 @@ template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> {
851851
void printHashHistogram(const Elf_Hash &HashTable);
852852
void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable);
853853

854+
void printHashTableSymbols(const ELFO *Obj, const Elf_Hash &HashTable);
855+
void printGnuHashTableSymbols(const ELFO *Obj,
856+
const Elf_GnuHash &GnuHashTable);
857+
854858
struct Field {
855859
std::string Str;
856860
unsigned Column;
@@ -4068,78 +4072,62 @@ void GNUStyle<ELFT>::printSymbols(const ELFO *Obj, bool PrintSymbols,
40684072
this->dumper()->printSymbolsHelper(false);
40694073
}
40704074

4071-
template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {
4072-
if (this->dumper()->getDynamicStringTable().empty())
4073-
return;
4074-
auto StringTable = this->dumper()->getDynamicStringTable();
4075-
Elf_Sym_Range DynSyms = this->dumper()->dynamic_symbols();
4076-
4077-
auto PrintHashTable = [&](const Elf_Hash *SysVHash) {
4078-
if (ELFT::Is64Bits)
4079-
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
4080-
else
4081-
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
4082-
OS << "\n";
4083-
4084-
const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
4085-
if (!FirstSym) {
4086-
Optional<DynRegionInfo> DynSymRegion = this->dumper()->getDynSymRegion();
4087-
this->reportUniqueWarning(
4088-
createError(Twine("unable to print symbols for the .hash table: the "
4089-
"dynamic symbol table ") +
4090-
(DynSymRegion ? "is empty" : "was not found")));
4091-
return;
4092-
}
4093-
4094-
auto Buckets = SysVHash->buckets();
4095-
auto Chains = SysVHash->chains();
4096-
for (uint32_t Buc = 0; Buc < SysVHash->nbucket; Buc++) {
4097-
if (Buckets[Buc] == ELF::STN_UNDEF)
4098-
continue;
4099-
std::vector<bool> Visited(SysVHash->nchain);
4100-
for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash->nchain; Ch = Chains[Ch]) {
4101-
if (Ch == ELF::STN_UNDEF)
4102-
break;
4103-
4104-
if (Visited[Ch]) {
4105-
reportWarning(
4106-
createError(".hash section is invalid: bucket " + Twine(Ch) +
4107-
": a cycle was detected in the linked chain"),
4108-
this->FileName);
4109-
break;
4110-
}
4111-
4112-
printHashedSymbol(Obj, FirstSym, Ch, StringTable, Buc);
4113-
Visited[Ch] = true;
4114-
}
4115-
}
4116-
};
4117-
4118-
if (const Elf_Hash *SysVHash = this->dumper()->getHashTable()) {
4119-
OS << "\n Symbol table of .hash for image:\n";
4120-
if (Error E = checkHashTable<ELFT>(Obj, SysVHash))
4121-
this->reportUniqueWarning(std::move(E));
4122-
else
4123-
PrintHashTable(SysVHash);
4124-
}
4125-
4126-
// Try printing the .gnu.hash table.
4127-
const Elf_GnuHash *GnuHash = this->dumper()->getGnuHashTable();
4128-
if (!GnuHash)
4075+
template <class ELFT>
4076+
void GNUStyle<ELFT>::printHashTableSymbols(const ELFO *Obj,
4077+
const Elf_Hash &SysVHash) {
4078+
StringRef StringTable = this->dumper()->getDynamicStringTable();
4079+
if (StringTable.empty())
41294080
return;
41304081

4131-
OS << "\n Symbol table of .gnu.hash for image:\n";
41324082
if (ELFT::Is64Bits)
41334083
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
41344084
else
41354085
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
41364086
OS << "\n";
41374087

4138-
if (Error E = checkGNUHashTable<ELFT>(Obj, GnuHash)) {
4139-
this->reportUniqueWarning(std::move(E));
4088+
Elf_Sym_Range DynSyms = this->dumper()->dynamic_symbols();
4089+
const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
4090+
if (!FirstSym) {
4091+
Optional<DynRegionInfo> DynSymRegion = this->dumper()->getDynSymRegion();
4092+
this->reportUniqueWarning(
4093+
createError(Twine("unable to print symbols for the .hash table: the "
4094+
"dynamic symbol table ") +
4095+
(DynSymRegion ? "is empty" : "was not found")));
41404096
return;
41414097
}
41424098

4099+
auto Buckets = SysVHash.buckets();
4100+
auto Chains = SysVHash.chains();
4101+
for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) {
4102+
if (Buckets[Buc] == ELF::STN_UNDEF)
4103+
continue;
4104+
std::vector<bool> Visited(SysVHash.nchain);
4105+
for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) {
4106+
if (Ch == ELF::STN_UNDEF)
4107+
break;
4108+
4109+
if (Visited[Ch]) {
4110+
reportWarning(createError(".hash section is invalid: bucket " +
4111+
Twine(Ch) +
4112+
": a cycle was detected in the linked chain"),
4113+
this->FileName);
4114+
break;
4115+
}
4116+
4117+
printHashedSymbol(Obj, FirstSym, Ch, StringTable, Buc);
4118+
Visited[Ch] = true;
4119+
}
4120+
}
4121+
}
4122+
4123+
template <class ELFT>
4124+
void GNUStyle<ELFT>::printGnuHashTableSymbols(const ELFO *Obj,
4125+
const Elf_GnuHash &GnuHash) {
4126+
StringRef StringTable = this->dumper()->getDynamicStringTable();
4127+
if (StringTable.empty())
4128+
return;
4129+
4130+
Elf_Sym_Range DynSyms = this->dumper()->dynamic_symbols();
41434131
const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0];
41444132
if (!FirstSym) {
41454133
Optional<DynRegionInfo> DynSymRegion = this->dumper()->getDynSymRegion();
@@ -4150,22 +4138,47 @@ template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {
41504138
return;
41514139
}
41524140

4153-
auto Buckets = GnuHash->buckets();
4154-
for (uint32_t Buc = 0; Buc < GnuHash->nbuckets; Buc++) {
4141+
ArrayRef<Elf_Word> Buckets = GnuHash.buckets();
4142+
for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) {
41554143
if (Buckets[Buc] == ELF::STN_UNDEF)
41564144
continue;
41574145
uint32_t Index = Buckets[Buc];
4158-
uint32_t GnuHashable = Index - GnuHash->symndx;
4146+
uint32_t GnuHashable = Index - GnuHash.symndx;
41594147
// Print whole chain
41604148
while (true) {
41614149
printHashedSymbol(Obj, FirstSym, Index++, StringTable, Buc);
41624150
// Chain ends at symbol with stopper bit
4163-
if ((GnuHash->values(DynSyms.size())[GnuHashable++] & 1) == 1)
4151+
if ((GnuHash.values(DynSyms.size())[GnuHashable++] & 1) == 1)
41644152
break;
41654153
}
41664154
}
41674155
}
41684156

4157+
template <class ELFT> void GNUStyle<ELFT>::printHashSymbols(const ELFO *Obj) {
4158+
if (const Elf_Hash *SysVHash = this->dumper()->getHashTable()) {
4159+
OS << "\n Symbol table of .hash for image:\n";
4160+
if (Error E = checkHashTable<ELFT>(Obj, SysVHash))
4161+
this->reportUniqueWarning(std::move(E));
4162+
else
4163+
printHashTableSymbols(Obj, *SysVHash);
4164+
}
4165+
4166+
// Try printing the .gnu.hash table.
4167+
if (const Elf_GnuHash *GnuHash = this->dumper()->getGnuHashTable()) {
4168+
OS << "\n Symbol table of .gnu.hash for image:\n";
4169+
if (ELFT::Is64Bits)
4170+
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
4171+
else
4172+
OS << " Num Buc: Value Size Type Bind Vis Ndx Name";
4173+
OS << "\n";
4174+
4175+
if (Error E = checkGNUHashTable<ELFT>(Obj, GnuHash))
4176+
this->reportUniqueWarning(std::move(E));
4177+
else
4178+
printGnuHashTableSymbols(Obj, *GnuHash);
4179+
}
4180+
}
4181+
41694182
static inline std::string printPhdrFlags(unsigned Flag) {
41704183
std::string Str;
41714184
Str = (Flag & PF_R) ? "R" : " ";

0 commit comments

Comments
 (0)