[llvm] 86b093d - [llvm-readobj] Allow syms from all sections to match stack size entries
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 20 03:56:21 PDT 2020
Author: James Henderson
Date: 2020-03-20T10:54:18Z
New Revision: 86b093d1a18c1d4ccd3578e70e738a0f249ab19e
URL: https://github.com/llvm/llvm-project/commit/86b093d1a18c1d4ccd3578e70e738a0f249ab19e
DIFF: https://github.com/llvm/llvm-project/commit/86b093d1a18c1d4ccd3578e70e738a0f249ab19e.diff
LOG: [llvm-readobj] Allow syms from all sections to match stack size entries
Prior to this change, for non-relocatable objects llvm-readobj would
assume that all symbols that corresponded to a stack size section's
entries were in the section specified by the section's sh_link field.
In the presence of an output section description combining
SHF_LINK_ORDER sections linking different output sections, this cannot
be respected, since linker script section patterns are "by name" by
nature. Consequently, the sh_link value would not be correct for all
section entries.
This patch changes llvm-readobj to ignore the section of symbols in a
non-relocatable object.
Fixes https://bugs.llvm.org/show_bug.cgi?id=45228.
Reviewed by: grimar, MaskRay
Differential Revision: https://reviews.llvm.org/D76425
Added:
Modified:
llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
llvm/tools/llvm-readobj/ELFDumper.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
index d1f6dabdbf08..c315749ba425 100644
--- a/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
+++ b/llvm/test/tools/llvm-readobj/ELF/stack-sizes.test
@@ -92,27 +92,35 @@ Symbols:
Binding: STB_GLOBAL
## Check that we correctly report the stack sizes in an executable (non-relocatable)
-## object file.
+## object file. This also shows that the sh_link field is ignored in this situation
+## without warning.
# RUN: yaml2obj --docnum=2 %s -o %t02
-# RUN: llvm-readelf --stack-sizes %t02 \
-# RUN: | FileCheck %s --check-prefix=EXEC-GNU --strict-whitespace --match-full-lines
-# RUN: llvm-readobj --stack-sizes %t02 | FileCheck %s --check-prefix=EXEC-LLVM
+# RUN: llvm-readelf --stack-sizes %t02 2>&1 \
+# RUN: | FileCheck %s --check-prefix=EXEC-GNU --strict-whitespace \
+# RUN: --match-full-lines --implicit-check-not=warning:
+# RUN: llvm-readobj --stack-sizes %t02 2>&1 \
+# RUN: | FileCheck %s --check-prefix=EXEC-LLVM --implicit-check-not=warning:
# EXEC-GNU: Size Function
-# EXEC-GNU-NEXT: 16 foo
-# EXEC-GNU-NEXT: 32 bar
+# EXEC-GNU-NEXT: 16 other
+# EXEC-GNU-NEXT: 32 other_end
+# EXEC-GNU-NEXT: 48 bar
# EXEC-GNU-NOT:{{.}}
# EXEC-LLVM: StackSizes [
# EXEC-LLVM-NEXT: Entry {
-# EXEC-LLVM-NEXT: Function: foo
+# EXEC-LLVM-NEXT: Function: other
# EXEC-LLVM-NEXT: Size: 0x10
# EXEC-LLVM-NEXT: }
# EXEC-LLVM-NEXT: Entry {
-# EXEC-LLVM-NEXT: Function: bar
+# EXEC-LLVM-NEXT: Function: other_end
# EXEC-LLVM-NEXT: Size: 0x20
# EXEC-LLVM-NEXT: }
+# EXEC-LLVM-NEXT: Entry {
+# EXEC-LLVM-NEXT: Function: bar
+# EXEC-LLVM-NEXT: Size: 0x30
+# EXEC-LLVM-NEXT: }
# EXEC-LLVM-NEXT: ]
--- !ELF
@@ -126,22 +134,45 @@ Sections:
Type: SHT_PROGBITS
Flags: [SHF_ALLOC]
Size: 16
+ - Name: .text2
+ Type: SHT_PROGBITS
+ Flags: [SHF_ALLOC]
+ Size: 16
- Name: .stack_sizes
Type: SHT_PROGBITS
Entries:
- - Address: 0x10
+ - Address: 0x0
Size: 0x10
- - Address: 0x20
+ - Address: 0x10
Size: 0x20
- Link: .text
+ - Address: 0x20
+ Size: 0x30
+ Link: .text2
Symbols:
- - Name: foo
+ ## Undefined symbols are ignored.
+ - Name: undefined
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ ## sh_link of .stack_sizes is ignored for non-reloctable objects.
+ - Name: other
+ Section: .text
+ Value: 0
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
+ ## If two symbols have the same value, the first is picked, regardless of
+ ## the sh_link value of the .stack_sizes section.
+ - Name: other_end
Section: .text
Value: 0x10
Type: STT_FUNC
Binding: STB_GLOBAL
+ - Name: foo
+ Section: .text2
+ Value: 0x10
+ Type: STT_FUNC
+ Binding: STB_GLOBAL
- Name: bar
- Section: .text
+ Section: .text2
Value: 0x20
Type: STT_FUNC
Binding: STB_GLOBAL
@@ -184,7 +215,8 @@ Symbols:
Binding: STB_GLOBAL
## Check that we warn about a function symbol that is not in the section
-## that is referenced by the stack sizes section's sh_link.
+## that is referenced by the stack sizes section's sh_link, for relocatable
+## output.
# RUN: yaml2obj --docnum=4 %s -o %t04
# RUN: llvm-readelf --stack-sizes %t04 2> %t04-gnu.err | FileCheck %s --check-prefix=WRONGSECTION-GNU
@@ -437,18 +469,23 @@ Sections:
# MULTIPLE-GNU-EMPTY:
# MULTIPLE-GNU-NEXT:Stack Sizes:
# MULTIPLE-GNU-NEXT: Size Function
-# MULTIPLE-GNU-NEXT: 16 foo
-# MULTIPLE-GNU-NEXT: 32 bar
+# MULTIPLE-GNU-NEXT: 16 other
+# MULTIPLE-GNU-NEXT: 32 other_end
+# MULTIPLE-GNU-NEXT: 48 bar
# MULTIPLE-LLVM: StackSizes [
# MULTIPLE-LLVM-NEXT: Entry {
-# MULTIPLE-LLVM-NEXT: Function: foo
+# MULTIPLE-LLVM-NEXT: Function: other
# MULTIPLE-LLVM-NEXT: Size: 0x10
# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: Entry {
-# MULTIPLE-LLVM-NEXT: Function: bar
+# MULTIPLE-LLVM-NEXT: Function: other_end
# MULTIPLE-LLVM-NEXT: Size: 0x20
# MULTIPLE-LLVM-NEXT: }
+# MULTIPLE-LLVM-NEXT: Entry {
+# MULTIPLE-LLVM-NEXT: Function: bar
+# MULTIPLE-LLVM-NEXT: Size: 0x30
+# MULTIPLE-LLVM-NEXT: }
# MULTIPLE-LLVM-NEXT: ]
## Check that we do not consider symbols that are not function symbols, even though
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 283f1b24020d..fe7ee7fa6048 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -752,7 +752,7 @@ template <typename ELFT> class DumpStyle {
void printRelocatableStackSizes(const ELFObjectFile<ELFT> *Obj,
std::function<void()> PrintHeader);
void printFunctionStackSize(const ELFObjectFile<ELFT> *Obj, uint64_t SymValue,
- SectionRef FunctionSec,
+ Optional<SectionRef> FunctionSec,
const StringRef SectionName, DataExtractor Data,
uint64_t *Offset);
void printStackSize(const ELFObjectFile<ELFT> *Obj, RelocationRef Rel,
@@ -5174,9 +5174,12 @@ static std::string getSymbolName(const ELFSymbolRef &Sym) {
}
template <class ELFT>
-void DumpStyle<ELFT>::printFunctionStackSize(
- const ELFObjectFile<ELFT> *Obj, uint64_t SymValue, SectionRef FunctionSec,
- const StringRef SectionName, DataExtractor Data, uint64_t *Offset) {
+void DumpStyle<ELFT>::printFunctionStackSize(const ELFObjectFile<ELFT> *Obj,
+ uint64_t SymValue,
+ Optional<SectionRef> FunctionSec,
+ const StringRef SectionName,
+ DataExtractor Data,
+ uint64_t *Offset) {
// This function ignores potentially erroneous input, unless it is directly
// related to stack size reporting.
SymbolRef FuncSym;
@@ -5186,9 +5189,15 @@ void DumpStyle<ELFT>::printFunctionStackSize(
consumeError(SymAddrOrErr.takeError());
continue;
}
+ if (Expected<uint32_t> SymFlags = Symbol.getFlags()) {
+ if (*SymFlags & SymbolRef::SF_Undefined)
+ continue;
+ } else
+ consumeError(SymFlags.takeError());
if (Symbol.getELFType() == ELF::STT_FUNC && *SymAddrOrErr == SymValue) {
- // Check if the symbol is in the right section.
- if (FunctionSec.containsSymbol(Symbol)) {
+ // Check if the symbol is in the right section. FunctionSec == None means
+ // "any section".
+ if (!FunctionSec || FunctionSec->containsSymbol(Symbol)) {
FuncSym = Symbol;
break;
}
@@ -5299,11 +5308,6 @@ void DumpStyle<ELFT>::printNonRelocatableStackSizes(
ArrayRef<uint8_t> Contents =
unwrapOrError(this->FileName, EF->getSectionContents(ElfSec));
DataExtractor Data(Contents, Obj->isLittleEndian(), sizeof(Elf_Addr));
- // A .stack_sizes section header's sh_link field is supposed to point
- // to the section that contains the functions whose stack sizes are
- // described in it.
- const Elf_Shdr *FunctionELFSec =
- unwrapOrError(this->FileName, EF->getSection(ElfSec->sh_link));
uint64_t Offset = 0;
while (Offset < Contents.size()) {
// The function address is followed by a ULEB representing the stack
@@ -5317,8 +5321,8 @@ void DumpStyle<ELFT>::printNonRelocatableStackSizes(
FileStr);
}
uint64_t SymValue = Data.getAddress(&Offset);
- printFunctionStackSize(Obj, SymValue, Obj->toSectionRef(FunctionELFSec),
- SectionName, Data, &Offset);
+ printFunctionStackSize(Obj, SymValue, /*FunctionSec=*/None, SectionName,
+ Data, &Offset);
}
}
}
More information about the llvm-commits
mailing list