[llvm-readelf/llvm-objdump] - Improve/refactor the implementation of SHT_LLVM_ADDRSIG section dumping.

This patch:

* Adds a llvm-readobj/llvm-readelf test file for SHT_LLVM_ADDRSIG sections. (we do not have any)
* Enables dumping of SHT_LLVM_ADDRSIG with --all.
* Changes the logic to report a warning instead of an error when something goes wrong during dumping
  (allows to continue dumping SHT_LLVM_ADDRSIG and other sections on error).
* Refactors a piece of logic to a new toULEB128Array helper which might be used for GNU-style
  dumping implementation.

Differential revision: https://reviews.llvm.org/D68383

llvm-svn: 373890
This commit is contained in:
George Rimar 2019-10-07 10:29:38 +00:00
parent 2fa81d201f
commit 5ce8c39149
4 changed files with 143 additions and 28 deletions

View File

@ -14,6 +14,7 @@
# ALL: Version symbols {
# ALL: SHT_GNU_verdef {
# ALL: SHT_GNU_verneed {
# ALL: Addrsig [
# ALL: Notes [
# ALL: StackSizes [

View File

@ -0,0 +1,84 @@
## Show that llvm-readobj can dump SHT_LLVM_ADDRSIG sections.
# RUN: yaml2obj --docnum=1 %s -o %t1.o
# RUN: llvm-readobj --addrsig %t1.o | FileCheck -DFILE=%t1.o %s --check-prefix LLVM
# RUN: not llvm-readelf --addrsig %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix GNU
# LLVM: Addrsig [
# LLVM-NEXT: Sym: foo (1)
# LLVM-NEXT: Sym: bar (2)
# LLVM-NEXT: ]
# GNU: error: '[[FILE]]': --addrsig: not implemented
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .llvm_addrsig
Type: SHT_LLVM_ADDRSIG
Symbols:
- Name: foo
- Name: bar
Symbols:
- Name: foo
- Name: bar
## Check that llvm-readobj dumps any SHT_LLVM_ADDRSIG section when --all
## is specified for LLVM style, but not for GNU style.
## TODO: Refine the llvm-readelf check when GNU-style dumping is implemented.
# RUN: llvm-readobj --all %t1.o | FileCheck %s --check-prefix LLVM
# RUN: llvm-readelf --all %t1.o 2>&1 | FileCheck %s --implicit-check-not=warning --implicit-check-not=error
## Check we report a warning when SHT_LLVM_ADDRSIG is broken (e.g. contains a malformed uleb128).
# RUN: yaml2obj --docnum=2 %s -o %t2.o
# RUN: llvm-readobj --addrsig %t2.o 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=MALFORMED
# MALFORMED: warning: '[[FILE]]': malformed uleb128, extends past end
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .llvm_addrsig
Type: SHT_LLVM_ADDRSIG
Content: "FF"
## Check we report a warning when SHT_LLVM_ADDRSIG references a symbol that can't be
## dumped (e.g. the index value is larger than the number of symbols in .symtab).
# RUN: yaml2obj --docnum=3 %s -o %t3.o
# RUN: llvm-readobj --addrsig %t3.o 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALID-INDEX
# INVALID-INDEX: Addrsig [
# INVALID-INDEX-NEXT: Sym: foo (1)
# INVALID-INDEX-EMPTY:
# INVALID-INDEX-NEXT: warning: '[[FILE]]': unable to get symbol from section [index 2]: invalid symbol index (255)
# INVALID-INDEX-NEXT: Sym: <?> (255)
# INVALID-INDEX-NEXT: Sym: bar (2)
# INVALID-INDEX-NEXT: ]
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .llvm_addrsig
Type: SHT_LLVM_ADDRSIG
Symbols:
- Index: 1
- Index: 255
- Index: 2
Symbols:
- Name: foo
- Name: bar

View File

@ -302,7 +302,7 @@ public:
void getSectionNameIndex(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
StringRef &SectionName,
unsigned &SectionIndex) const;
std::string getStaticSymbolName(uint32_t Index) const;
Expected<std::string> getStaticSymbolName(uint32_t Index) const;
std::string getDynamicString(uint64_t Value) const;
StringRef getSymbolVersionByIndex(StringRef StrTab,
uint32_t VersionSymbolIndex,
@ -754,17 +754,22 @@ static std::string maybeDemangle(StringRef Name) {
}
template <typename ELFT>
std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
Expected<std::string>
ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
StringRef StrTable = unwrapOrError(
ObjF->getFileName(), Obj->getStringTableForSymtab(*DotSymtabSec));
Elf_Sym_Range Syms =
unwrapOrError(ObjF->getFileName(), Obj->symbols(DotSymtabSec));
if (Index >= Syms.size())
reportError(createError("Invalid symbol index"), ObjF->getFileName());
const Elf_Sym *Sym = &Syms[Index];
return maybeDemangle(
unwrapOrError(ObjF->getFileName(), Sym->getName(StrTable)));
Expected<const typename ELFT::Sym *> SymOrErr =
Obj->getSymbol(DotSymtabSec, Index);
if (!SymOrErr)
return SymOrErr.takeError();
Expected<StringRef> StrTabOrErr = Obj->getStringTableForSymtab(*DotSymtabSec);
if (!StrTabOrErr)
return StrTabOrErr.takeError();
Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);
if (!NameOrErr)
return NameOrErr.takeError();
return maybeDemangle(*NameOrErr);
}
template <typename ELFT>
@ -4047,7 +4052,7 @@ void GNUStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
template <class ELFT>
void GNUStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
OS << "GNUStyle::printAddrsig not implemented\n";
reportError(createError("--addrsig: not implemented"), this->FileName);
}
static StringRef getGenericNoteTypeName(const uint32_t NT) {
@ -5723,14 +5728,35 @@ void LLVMStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
this->dumper()->getDotCGProfileSec()));
for (const Elf_CGProfile &CGPE : CGProfile) {
DictScope D(W, "CGProfileEntry");
W.printNumber("From", this->dumper()->getStaticSymbolName(CGPE.cgp_from),
CGPE.cgp_from);
W.printNumber("To", this->dumper()->getStaticSymbolName(CGPE.cgp_to),
CGPE.cgp_to);
W.printNumber(
"From",
unwrapOrError(this->FileName,
this->dumper()->getStaticSymbolName(CGPE.cgp_from)),
CGPE.cgp_from);
W.printNumber(
"To",
unwrapOrError(this->FileName,
this->dumper()->getStaticSymbolName(CGPE.cgp_to)),
CGPE.cgp_to);
W.printNumber("Weight", CGPE.cgp_weight);
}
}
static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {
std::vector<uint64_t> Ret;
const uint8_t *Cur = Data.begin();
const uint8_t *End = Data.end();
while (Cur != End) {
unsigned Size;
const char *Err;
Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));
if (Err)
return createError(Err);
Cur += Size;
}
return Ret;
}
template <class ELFT>
void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
ListScope L(W, "Addrsig");
@ -5739,18 +5765,20 @@ void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
ArrayRef<uint8_t> Contents = unwrapOrError(
this->FileName,
Obj->getSectionContents(this->dumper()->getDotAddrsigSec()));
const uint8_t *Cur = Contents.begin();
const uint8_t *End = Contents.end();
while (Cur != End) {
unsigned Size;
const char *Err;
uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
if (Err)
reportError(createError(Err), this->FileName);
Expected<std::vector<uint64_t>> V = toULEB128Array(Contents);
if (!V) {
reportWarning(V.takeError(), this->FileName);
return;
}
W.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex),
SymIndex);
Cur += Size;
for (uint64_t Sym : *V) {
Expected<std::string> NameOrErr = this->dumper()->getStaticSymbolName(Sym);
if (NameOrErr) {
W.printNumber("Sym", *NameOrErr, Sym);
continue;
}
reportWarning(NameOrErr.takeError(), this->FileName);
W.printNumber("Sym", "<?>", Sym);
}
}

View File

@ -691,8 +691,10 @@ int main(int argc, const char *argv[]) {
opts::UnwindInfo = true;
opts::SectionGroups = true;
opts::HashHistogram = true;
if (opts::Output == opts::LLVM)
if (opts::Output == opts::LLVM) {
opts::Addrsig = true;
opts::PrintStackSizes = true;
}
}
if (opts::Headers) {