diff --git a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test --- a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test +++ b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test @@ -390,29 +390,42 @@ Binding: STB_GLOBAL ## Check that we report a warning when a relocation symbol does not belong to a -## valid section. We expect a stack size entry with an unknown symbol in the -## output. +## valid section or when it has an invalid index. We expect a stack size entry +## with an unknown symbol in the output. # RUN: yaml2obj --docnum=7 %s -o %t07 -# RUN: llvm-readelf --stack-sizes %t07 2> %t07-gnu.err | FileCheck %s --check-prefix=BADSECTION-OUT-GNU -# RUN: FileCheck %s < %t07-gnu.err --check-prefix=BADSECTION-ERR -DFILE=%t07 -# RUN: llvm-readobj --stack-sizes %t07 2> %t07-llvm.err | FileCheck %s --check-prefix=BADSECTION-OUT-LLVM -# RUN: FileCheck %s < %t07-llvm.err --check-prefix=BADSECTION-ERR -DFILE=%t07 - -# RUN: llvm-readelf --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07 -# RUN: llvm-readobj --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07 - -# BADSECTION-OUT-GNU: Size Function -# BADSECTION-OUT-GNU: 8 ? +# RUN: llvm-readelf --stack-sizes %t07 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t07 --check-prefix=BADSECTION-OUT-GNU --implicit-check-not=warning: +# RUN: llvm-readobj --stack-sizes %t07 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t07 --check-prefix=BADSECTION-OUT-LLVM --implicit-check-not=warning: + +# BADSECTION-OUT-GNU: Stack Sizes: +# BADSECTION-OUT-GNU-NEXT: Size Function +# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10 +# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry +# BADSECTION-OUT-GNU-NEXT: 8 ? +# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x1880: offset goes past the end of file +# BADSECTION-OUT-GNU-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry +# BADSECTION-OUT-GNU-NEXT: 22 ? # BADSECTION-OUT-LLVM: StackSizes [ +# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof': invalid section index: 10 +# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry # BADSECTION-OUT-LLVM-NEXT: Entry { # BADSECTION-OUT-LLVM-NEXT: Function: ? # BADSECTION-OUT-LLVM-NEXT: Size: 0x8 # BADSECTION-OUT-LLVM-NEXT: } +# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': unable to get the target of relocation with index 2 in SHT_RELA section with index 3: unable to access section [index 4] data at 0x1880: offset goes past the end of file +# BADSECTION-OUT-LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for stack size entry +# BADSECTION-OUT-LLVM-NEXT: Entry { +# BADSECTION-OUT-LLVM-NEXT: Function: ? +# BADSECTION-OUT-LLVM-NEXT: Size: 0x16 +# BADSECTION-OUT-LLVM-NEXT: } # BADSECTION-OUT-LLVM-NEXT: ] -# BADSECTION-ERR: warning: '[[FILE]]': cannot identify the section for relocation symbol '_Z3foof' +# RUN: llvm-readelf --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07 +# RUN: llvm-readobj --stack-sizes --demangle %t07 2>&1 | FileCheck %s --check-prefix=BADSECTION-DEMANGLE-ERR -DFILE=%t07 + # BADSECTION-DEMANGLE-ERR: warning: '[[FILE]]': cannot identify the section for relocation symbol 'foo(float)' --- !ELF @@ -424,12 +437,13 @@ Sections: - Name: .text Type: SHT_PROGBITS - Size: 8 + Size: 16 - Name: .stack_sizes Type: SHT_PROGBITS Link: .text Entries: - Size: 0x8 + - Size: 0x16 - Name: .rela.stack_sizes Type: SHT_RELA Info: .stack_sizes @@ -437,6 +451,10 @@ - Offset: 0 Symbol: _Z3foof Type: R_X86_64_64 + - Offset: 9 +## An invalid symbol index. + Symbol: 0xff + Type: R_X86_64_64 Symbols: - Name: _Z3foof ## An invalid section index. 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 @@ -794,8 +794,9 @@ Optional FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset); - void printStackSize(RelocationRef Rel, const Elf_Shdr *FunctionSec, - const Elf_Shdr &StackSizeSec, + void printStackSize(const Relocation &R, const Elf_Shdr &RelocSec, + unsigned Ndx, const Elf_Shdr *SymTab, + const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec, const RelocationResolver &Resolver, DataExtractor Data); virtual void printStackSizeEntry(uint64_t Size, StringRef FuncName) = 0; virtual void printMipsGOT(const MipsGOTParser &Parser) = 0; @@ -5877,44 +5878,47 @@ } template -void DumpStyle::printStackSize(RelocationRef Reloc, +void DumpStyle::printStackSize(const Relocation &R, + const Elf_Shdr &RelocSec, unsigned Ndx, + const Elf_Shdr *SymTab, const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec, const RelocationResolver &Resolver, DataExtractor Data) { // This function ignores potentially erroneous input, unless it is directly // related to stack size reporting. - object::symbol_iterator RelocSym = Reloc.getSymbol(); + const Elf_Sym *Sym = nullptr; + Expected> TargetOrErr = + this->dumper().getRelocationTarget(R, SymTab); + if (!TargetOrErr) + reportUniqueWarning( + createError("unable to get the target of relocation with index " + + Twine(Ndx) + " in " + describe(Obj, RelocSec) + ": " + + toString(TargetOrErr.takeError()))); + else + Sym = TargetOrErr->Sym; + uint64_t RelocSymValue = 0; - if (RelocSym != ElfObj.symbol_end()) { - // Ensure that the relocation symbol is in the function section, i.e. the - // section where the functions whose stack sizes we are reporting are - // located. - auto SectionOrErr = RelocSym->getSection(); + if (Sym) { + Expected SectionOrErr = + this->Obj.getSection(*Sym, SymTab, this->dumper().getShndxTable()); if (!SectionOrErr) { - reportWarning( - createError("cannot identify the section for relocation symbol '" + - getSymbolName(*RelocSym) + "'"), - FileName); - consumeError(SectionOrErr.takeError()); - } else if (*SectionOrErr != ElfObj.toSectionRef(FunctionSec)) { - reportWarning(createError("relocation symbol '" + - getSymbolName(*RelocSym) + - "' is not in the expected section"), - FileName); + reportUniqueWarning(createError( + "cannot identify the section for relocation symbol '" + + (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError()))); + } else if (*SectionOrErr != FunctionSec) { + reportUniqueWarning(createError("relocation symbol '" + + (*TargetOrErr).Name + + "' is not in the expected section")); // Pretend that the symbol is in the correct section and report its // stack size anyway. - FunctionSec = ElfObj.getSection((*SectionOrErr)->getRawDataRefImpl()); + FunctionSec = *SectionOrErr; } - Expected RelocSymValueOrErr = RelocSym->getValue(); - if (RelocSymValueOrErr) - RelocSymValue = *RelocSymValueOrErr; - else - consumeError(RelocSymValueOrErr.takeError()); + RelocSymValue = Sym->st_value; } - uint64_t Offset = Reloc.getOffset(); + uint64_t Offset = R.Offset; if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { reportUniqueWarning(createStringError( object_error::parse_failed, @@ -5924,8 +5928,9 @@ return; } - uint64_t Addend = Data.getAddress(&Offset); - uint64_t SymValue = resolveRelocation(Resolver, Reloc, RelocSymValue, Addend); + uint64_t SymValue = + Resolver(R.Type, Offset, RelocSymValue, Data.getAddress(&Offset), + R.Addend.getValueOr(0)); this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data, &Offset); } @@ -6031,21 +6036,26 @@ unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec)); DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr)); - size_t I = 0; - for (const RelocationRef &Reloc : - ElfObj.toSectionRef(RelocSec).relocations()) { - ++I; - if (!IsSupportedFn || !IsSupportedFn(Reloc.getType())) { - reportUniqueWarning(createStringError( - object_error::parse_failed, - describe(Obj, *RelocSec) + - " contains an unsupported relocation with index " + Twine(I) + - ": " + Obj.getRelocationTypeName(Reloc.getType()))); - continue; - } - this->printStackSize(Reloc, FunctionSec, *StackSizesELFSec, Resolver, - Data); - } + forEachRelocationDo( + *RelocSec, /*RawRelr=*/false, + [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, + const Elf_Shdr *SymTab) { + if (!IsSupportedFn || !IsSupportedFn(R.Type)) { + reportUniqueWarning(createStringError( + object_error::parse_failed, + describe(Obj, *RelocSec) + + " contains an unsupported relocation with index " + + Twine(Ndx) + ": " + Obj.getRelocationTypeName(R.Type))); + return; + } + + this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec, + *StackSizesELFSec, Resolver, Data); + }, + [](const Elf_Relr &) { + llvm_unreachable("can't get here, because we only support " + "SHT_REL/SHT_RELA sections"); + }); } }