Skip to content

Commit 5ce8c39

Browse files
author
George Rimar
committed
[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
1 parent 2fa81d2 commit 5ce8c39

File tree

4 files changed

+143
-28
lines changed

4 files changed

+143
-28
lines changed

llvm/test/tools/llvm-readobj/all.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# ALL: Version symbols {
1515
# ALL: SHT_GNU_verdef {
1616
# ALL: SHT_GNU_verneed {
17+
# ALL: Addrsig [
1718
# ALL: Notes [
1819
# ALL: StackSizes [
1920

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
## Show that llvm-readobj can dump SHT_LLVM_ADDRSIG sections.
2+
3+
# RUN: yaml2obj --docnum=1 %s -o %t1.o
4+
# RUN: llvm-readobj --addrsig %t1.o | FileCheck -DFILE=%t1.o %s --check-prefix LLVM
5+
# RUN: not llvm-readelf --addrsig %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix GNU
6+
7+
# LLVM: Addrsig [
8+
# LLVM-NEXT: Sym: foo (1)
9+
# LLVM-NEXT: Sym: bar (2)
10+
# LLVM-NEXT: ]
11+
12+
# GNU: error: '[[FILE]]': --addrsig: not implemented
13+
14+
--- !ELF
15+
FileHeader:
16+
Class: ELFCLASS64
17+
Data: ELFDATA2LSB
18+
Type: ET_DYN
19+
Machine: EM_X86_64
20+
Sections:
21+
- Name: .llvm_addrsig
22+
Type: SHT_LLVM_ADDRSIG
23+
Symbols:
24+
- Name: foo
25+
- Name: bar
26+
Symbols:
27+
- Name: foo
28+
- Name: bar
29+
30+
## Check that llvm-readobj dumps any SHT_LLVM_ADDRSIG section when --all
31+
## is specified for LLVM style, but not for GNU style.
32+
## TODO: Refine the llvm-readelf check when GNU-style dumping is implemented.
33+
34+
# RUN: llvm-readobj --all %t1.o | FileCheck %s --check-prefix LLVM
35+
# RUN: llvm-readelf --all %t1.o 2>&1 | FileCheck %s --implicit-check-not=warning --implicit-check-not=error
36+
37+
## Check we report a warning when SHT_LLVM_ADDRSIG is broken (e.g. contains a malformed uleb128).
38+
39+
# RUN: yaml2obj --docnum=2 %s -o %t2.o
40+
# RUN: llvm-readobj --addrsig %t2.o 2>&1 | FileCheck %s -DFILE=%t2.o --check-prefix=MALFORMED
41+
42+
# MALFORMED: warning: '[[FILE]]': malformed uleb128, extends past end
43+
44+
--- !ELF
45+
FileHeader:
46+
Class: ELFCLASS64
47+
Data: ELFDATA2LSB
48+
Type: ET_DYN
49+
Machine: EM_X86_64
50+
Sections:
51+
- Name: .llvm_addrsig
52+
Type: SHT_LLVM_ADDRSIG
53+
Content: "FF"
54+
55+
## Check we report a warning when SHT_LLVM_ADDRSIG references a symbol that can't be
56+
## dumped (e.g. the index value is larger than the number of symbols in .symtab).
57+
58+
# RUN: yaml2obj --docnum=3 %s -o %t3.o
59+
# RUN: llvm-readobj --addrsig %t3.o 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=INVALID-INDEX
60+
61+
# INVALID-INDEX: Addrsig [
62+
# INVALID-INDEX-NEXT: Sym: foo (1)
63+
# INVALID-INDEX-EMPTY:
64+
# INVALID-INDEX-NEXT: warning: '[[FILE]]': unable to get symbol from section [index 2]: invalid symbol index (255)
65+
# INVALID-INDEX-NEXT: Sym: <?> (255)
66+
# INVALID-INDEX-NEXT: Sym: bar (2)
67+
# INVALID-INDEX-NEXT: ]
68+
69+
--- !ELF
70+
FileHeader:
71+
Class: ELFCLASS64
72+
Data: ELFDATA2LSB
73+
Type: ET_DYN
74+
Machine: EM_X86_64
75+
Sections:
76+
- Name: .llvm_addrsig
77+
Type: SHT_LLVM_ADDRSIG
78+
Symbols:
79+
- Index: 1
80+
- Index: 255
81+
- Index: 2
82+
Symbols:
83+
- Name: foo
84+
- Name: bar

llvm/tools/llvm-readobj/ELFDumper.cpp

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
302302
void getSectionNameIndex(const Elf_Sym *Symbol, const Elf_Sym *FirstSym,
303303
StringRef &SectionName,
304304
unsigned &SectionIndex) const;
305-
std::string getStaticSymbolName(uint32_t Index) const;
305+
Expected<std::string> getStaticSymbolName(uint32_t Index) const;
306306
std::string getDynamicString(uint64_t Value) const;
307307
StringRef getSymbolVersionByIndex(StringRef StrTab,
308308
uint32_t VersionSymbolIndex,
@@ -754,17 +754,22 @@ static std::string maybeDemangle(StringRef Name) {
754754
}
755755

756756
template <typename ELFT>
757-
std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
757+
Expected<std::string>
758+
ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
758759
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
759-
StringRef StrTable = unwrapOrError(
760-
ObjF->getFileName(), Obj->getStringTableForSymtab(*DotSymtabSec));
761-
Elf_Sym_Range Syms =
762-
unwrapOrError(ObjF->getFileName(), Obj->symbols(DotSymtabSec));
763-
if (Index >= Syms.size())
764-
reportError(createError("Invalid symbol index"), ObjF->getFileName());
765-
const Elf_Sym *Sym = &Syms[Index];
766-
return maybeDemangle(
767-
unwrapOrError(ObjF->getFileName(), Sym->getName(StrTable)));
760+
Expected<const typename ELFT::Sym *> SymOrErr =
761+
Obj->getSymbol(DotSymtabSec, Index);
762+
if (!SymOrErr)
763+
return SymOrErr.takeError();
764+
765+
Expected<StringRef> StrTabOrErr = Obj->getStringTableForSymtab(*DotSymtabSec);
766+
if (!StrTabOrErr)
767+
return StrTabOrErr.takeError();
768+
769+
Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr);
770+
if (!NameOrErr)
771+
return NameOrErr.takeError();
772+
return maybeDemangle(*NameOrErr);
768773
}
769774

770775
template <typename ELFT>
@@ -4047,7 +4052,7 @@ void GNUStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
40474052

40484053
template <class ELFT>
40494054
void GNUStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
4050-
OS << "GNUStyle::printAddrsig not implemented\n";
4055+
reportError(createError("--addrsig: not implemented"), this->FileName);
40514056
}
40524057

40534058
static StringRef getGenericNoteTypeName(const uint32_t NT) {
@@ -5723,14 +5728,35 @@ void LLVMStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
57235728
this->dumper()->getDotCGProfileSec()));
57245729
for (const Elf_CGProfile &CGPE : CGProfile) {
57255730
DictScope D(W, "CGProfileEntry");
5726-
W.printNumber("From", this->dumper()->getStaticSymbolName(CGPE.cgp_from),
5727-
CGPE.cgp_from);
5728-
W.printNumber("To", this->dumper()->getStaticSymbolName(CGPE.cgp_to),
5729-
CGPE.cgp_to);
5731+
W.printNumber(
5732+
"From",
5733+
unwrapOrError(this->FileName,
5734+
this->dumper()->getStaticSymbolName(CGPE.cgp_from)),
5735+
CGPE.cgp_from);
5736+
W.printNumber(
5737+
"To",
5738+
unwrapOrError(this->FileName,
5739+
this->dumper()->getStaticSymbolName(CGPE.cgp_to)),
5740+
CGPE.cgp_to);
57305741
W.printNumber("Weight", CGPE.cgp_weight);
57315742
}
57325743
}
57335744

5745+
static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) {
5746+
std::vector<uint64_t> Ret;
5747+
const uint8_t *Cur = Data.begin();
5748+
const uint8_t *End = Data.end();
5749+
while (Cur != End) {
5750+
unsigned Size;
5751+
const char *Err;
5752+
Ret.push_back(decodeULEB128(Cur, &Size, End, &Err));
5753+
if (Err)
5754+
return createError(Err);
5755+
Cur += Size;
5756+
}
5757+
return Ret;
5758+
}
5759+
57345760
template <class ELFT>
57355761
void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
57365762
ListScope L(W, "Addrsig");
@@ -5739,18 +5765,20 @@ void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
57395765
ArrayRef<uint8_t> Contents = unwrapOrError(
57405766
this->FileName,
57415767
Obj->getSectionContents(this->dumper()->getDotAddrsigSec()));
5742-
const uint8_t *Cur = Contents.begin();
5743-
const uint8_t *End = Contents.end();
5744-
while (Cur != End) {
5745-
unsigned Size;
5746-
const char *Err;
5747-
uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
5748-
if (Err)
5749-
reportError(createError(Err), this->FileName);
5768+
Expected<std::vector<uint64_t>> V = toULEB128Array(Contents);
5769+
if (!V) {
5770+
reportWarning(V.takeError(), this->FileName);
5771+
return;
5772+
}
57505773

5751-
W.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex),
5752-
SymIndex);
5753-
Cur += Size;
5774+
for (uint64_t Sym : *V) {
5775+
Expected<std::string> NameOrErr = this->dumper()->getStaticSymbolName(Sym);
5776+
if (NameOrErr) {
5777+
W.printNumber("Sym", *NameOrErr, Sym);
5778+
continue;
5779+
}
5780+
reportWarning(NameOrErr.takeError(), this->FileName);
5781+
W.printNumber("Sym", "<?>", Sym);
57545782
}
57555783
}
57565784

llvm/tools/llvm-readobj/llvm-readobj.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,10 @@ int main(int argc, const char *argv[]) {
691691
opts::UnwindInfo = true;
692692
opts::SectionGroups = true;
693693
opts::HashHistogram = true;
694-
if (opts::Output == opts::LLVM)
694+
if (opts::Output == opts::LLVM) {
695+
opts::Addrsig = true;
695696
opts::PrintStackSizes = true;
697+
}
696698
}
697699

698700
if (opts::Headers) {

0 commit comments

Comments
 (0)