diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -362,6 +362,9 @@ getVersionDefinitions(const Elf_Shdr *Sec) const; Expected> getVersionDependencies(const Elf_Shdr *Sec) const; + + Expected> + getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const; }; template @@ -1050,6 +1053,41 @@ return this->getSymbolVersionByIndex(Versym->vs_index, IsDefault); } +template +Expected> +ELFDumper::getRelocationTarget(const Elf_Shdr *SymTab, + const Elf_Rela &R) const { + const ELFFile *Obj = ObjF->getELFFile(); + Expected SymOrErr = Obj->getRelocationSymbol(&R, SymTab); + if (!SymOrErr) + return SymOrErr.takeError(); + const Elf_Sym *Sym = *SymOrErr; + if (!Sym) + return std::make_pair(nullptr, ""); + + // The st_name field of a STT_SECTION is usually 0 (empty string). + // This code block returns the section name. + if (Sym->getType() == ELF::STT_SECTION) { + Expected SecOrErr = + Obj->getSection(Sym, SymTab, ShndxTable); + if (!SecOrErr) + return SecOrErr.takeError(); + + Expected NameOrErr = Obj->getSectionName(*SecOrErr); + if (!NameOrErr) + return NameOrErr.takeError(); + return std::make_pair(Sym, NameOrErr->str()); + } + + Expected StrTableOrErr = Obj->getStringTableForSymtab(*SymTab); + if (!StrTableOrErr) + return StrTableOrErr.takeError(); + + std::string SymbolName = + getFullSymbolName(Sym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); + return std::make_pair(Sym, SymbolName); +} + static std::string maybeDemangle(StringRef Name) { return opts::Demangle ? demangle(std::string(Name)) : Name.str(); } @@ -3281,22 +3319,11 @@ template void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab, const Elf_Rela &R, bool IsRela) { - const Elf_Sym *Sym = - unwrapOrError(this->FileName, Obj->getRelocationSymbol(&R, SymTab)); - std::string TargetName; - if (Sym && Sym->getType() == ELF::STT_SECTION) { - const Elf_Shdr *Sec = unwrapOrError( - this->FileName, - Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable())); - TargetName = - std::string(unwrapOrError(this->FileName, Obj->getSectionName(Sec))); - } else if (Sym) { - StringRef StrTable = - unwrapOrError(this->FileName, Obj->getStringTableForSymtab(*SymTab)); - TargetName = this->dumper()->getFullSymbolName( - Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */); - } - printRelocation(Obj, Sym, TargetName, R, IsRela); + const typename ELFT::Sym *Sym; + std::string Name; + std::tie(Sym, Name) = unwrapOrError( + this->FileName, this->dumper()->getRelocationTarget(SymTab, R)); + printRelocation(Obj, Sym, Name, R, IsRela); } template @@ -5709,23 +5736,13 @@ template void LLVMStyle::printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab) { + std::string TargetName = + unwrapOrError(this->FileName, + this->dumper()->getRelocationTarget(SymTab, Rel)) + .second; + SmallString<32> RelocName; Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); - std::string TargetName; - const Elf_Sym *Sym = - unwrapOrError(this->FileName, Obj->getRelocationSymbol(&Rel, SymTab)); - if (Sym && Sym->getType() == ELF::STT_SECTION) { - const Elf_Shdr *Sec = unwrapOrError( - this->FileName, - Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable())); - TargetName = - std::string(unwrapOrError(this->FileName, Obj->getSectionName(Sec))); - } else if (Sym) { - StringRef StrTable = - unwrapOrError(this->FileName, Obj->getStringTableForSymtab(*SymTab)); - TargetName = this->dumper()->getFullSymbolName( - Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */); - } if (opts::ExpandRelocs) { DictScope Group(W, "Relocation");