[llvm-branch-commits] [llvm] ee9ffc7 - [obj2yaml] - Dump the `EShNum` key in some cases.
Georgii Rymar via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 27 05:07:25 PST 2020
Author: Georgii Rymar
Date: 2020-11-27T15:56:10+03:00
New Revision: ee9ffc73452a0b500db18d422562918d389b1d14
URL: https://github.com/llvm/llvm-project/commit/ee9ffc73452a0b500db18d422562918d389b1d14
DIFF: https://github.com/llvm/llvm-project/commit/ee9ffc73452a0b500db18d422562918d389b1d14.diff
LOG: [obj2yaml] - Dump the `EShNum` key in some cases.
This patch starts emitting the `EShNum` key, when the `e_shnum = 0`
and the section header table exists.
`e_shnum` might be 0, when the the number of entries in the section header
table is larger than or equal to SHN_LORESERVE (0xff00).
In this case the real number of entries
in the section header table is held in the `sh_size`
member of the initial entry in section header table.
Currently, obj2yaml crashes when an object has `e_shoff != 0` and the `sh_size`
member of the initial entry in section header table is `0`.
This patch fixes it.
Differential revision: https://reviews.llvm.org/D92098
Added:
llvm/test/tools/obj2yaml/ELF/eshnum.yaml
Modified:
llvm/tools/obj2yaml/elf2yaml.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/obj2yaml/ELF/eshnum.yaml b/llvm/test/tools/obj2yaml/ELF/eshnum.yaml
new file mode 100644
index 000000000000..35c7cfddf58c
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/eshnum.yaml
@@ -0,0 +1,67 @@
+## Test cases related to the value of the e_shnum field of the ELF header live here.
+
+## Normally an object that does not have sections has e_shnum == 0.
+## Also, e_shnum might be 0, when the the number of entries in the section
+## header table is larger than or equal to SHN_LORESERVE (0xff00). In this case
+## the real number of entries in the section header table is held in the sh_size
+## member of the initial entry in the section header table.
+
+## In the test case below we have an object that has e_shnum = 0 and the real
+## number of sections is written to the sh_size member of the initial entry in
+## the section header table. Check that we emit the `EShNum` key properly.
+
+# RUN: yaml2obj %s -o %t1
+# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=PRESERVE
+
+# PRESERVE: --- !ELF
+# PRESERVE-NEXT: FileHeader:
+# PRESERVE-NEXT: Class: ELFCLASS64
+# PRESERVE-NEXT: Data: ELFDATA2LSB
+# PRESERVE-NEXT: Type: ET_REL
+# PRESERVE-NEXT: EShNum: 0x0
+# PRESERVE-NEXT: Sections:
+# PRESERVE-NEXT: - Type: SHT_NULL
+# PRESERVE-NEXT: Size: 0x3
+# PRESERVE-NEXT: ...
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ EShNum: 0x0
+ EShOff: [[ESHOFF=<none>]]
+Sections:
+ - Type: SHT_NULL
+## 3 sections total: SHT_NULL + 2 implicit sections: .strtab and .shstrtab.
+ Size: [[SIZE=0x3]]
+
+## In the test case below we have an object with a non-zero section header table
+## file offset and an initial entry in the section header table with sh_size of 0.
+## Here we check that we are able to dump such objects properly.
+
+# RUN: yaml2obj %s -DSIZE=0x0 -o %t2
+# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=NO-SECTIONS
+
+# NO-SECTIONS: --- !ELF
+# NO-SECTIONS-NEXT: FileHeader:
+# NO-SECTIONS-NEXT: Class: ELFCLASS64
+# NO-SECTIONS-NEXT: Data: ELFDATA2LSB
+# NO-SECTIONS-NEXT: Type: ET_REL
+# NO-SECTIONS-NEXT: EShNum: 0x0
+## Note: yaml2obj will create the SHT_NULL section with sh_size = 0 implicitly.
+# NO-SECTIONS-NEXT: ...
+
+## In the test case below we have an object without a section header table and e_shnum == 0.
+## Document how we dump it.
+## FIXME: we should emit the `SectionHeaderTable` key with `NoHeaders=true` for this case.
+
+# RUN: yaml2obj %s -DESHOFF=0x0 -o %t3
+# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=NO-HEADERS
+
+# NO-HEADERS: --- !ELF
+# NO-HEADERS-NEXT: FileHeader:
+# NO-HEADERS-NEXT: Class: ELFCLASS64
+# NO-HEADERS-NEXT: Data: ELFDATA2LSB
+# NO-HEADERS-NEXT: Type: ET_REL
+# NO-HEADERS-NEXT: ...
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 4d8d471817ac..ea2f2911712b 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -237,6 +237,9 @@ static void dumpSectionOffsets(const typename ELFT::Ehdr &Header,
ArrayRef<ELFYAML::ProgramHeader> Phdrs,
std::vector<std::unique_ptr<ELFYAML::Chunk>> &V,
ArrayRef<typename ELFT::Shdr> S) {
+ if (V.empty())
+ return;
+
uint64_t ExpectedOffset;
if (Header.e_phoff > 0)
ExpectedOffset = Header.e_phoff + Header.e_phentsize * Header.e_phnum;
@@ -289,6 +292,14 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
Sections = *SectionsOrErr;
SectionNames.resize(Sections.size());
+ // Normally an object that does not have sections has e_shnum == 0.
+ // Also, e_shnum might be 0, when the the number of entries in the section
+ // header table is larger than or equal to SHN_LORESERVE (0xff00). In this
+ // case the real number of entries is held in the sh_size member of the
+ // initial entry. We have a section header table when `e_shoff` is not 0.
+ if (Obj.getHeader().e_shoff != 0 && Obj.getHeader().e_shnum == 0)
+ Y->Header.EShNum = 0;
+
// Dump symbols. We need to do this early because other sections might want
// to access the deduplicated symbol names that we also create here.
const Elf_Shdr *SymTab = nullptr;
More information about the llvm-branch-commits
mailing list