[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