]> granicus.if.org Git - llvm/commitdiff
[yaml2obj] - Add a Size field for StackSizesSection.
authorGeorge Rimar <grimar@accesssoftek.com>
Wed, 25 Sep 2019 11:40:11 +0000 (11:40 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Wed, 25 Sep 2019 11:40:11 +0000 (11:40 +0000)
It is a follow-up requested in the review comment
for D67757. Allows to use Content + Size or just Size
when describing .stack_sizes sections in YAML document

Differential revision: https://reviews.llvm.org/D67958

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372845 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ObjectYAML/ELFYAML.h
lib/ObjectYAML/ELFEmitter.cpp
lib/ObjectYAML/ELFYAML.cpp
test/tools/yaml2obj/elf-stack-sizes.yaml

index 15016dccdb624bb4b0e590c0284e9a73955db46c..37bbe72a56130f0c9c6c7aa0f1e72dd0c4a6854c 100644 (file)
@@ -171,6 +171,7 @@ struct Section {
 
 struct StackSizesSection : Section {
   Optional<yaml::BinaryRef> Content;
+  Optional<llvm::yaml::Hex64> Size;
   Optional<std::vector<StackSizeEntry>> Entries;
 
   StackSizesSection() : Section(SectionKind::StackSizes) {}
index c394763459d7650843e5dad14b57527833798168..0139c2d1144cb2e8f8dcd0f3a12e154533b5ec67 100644 (file)
@@ -440,19 +440,20 @@ static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
   return Symbols.size();
 }
 
-static uint64_t writeRawSectionData(raw_ostream &OS,
-                                    const ELFYAML::RawContentSection &RawSec) {
+static uint64_t writeContent(raw_ostream &OS,
+                             const Optional<yaml::BinaryRef> &Content,
+                             const Optional<llvm::yaml::Hex64> &Size) {
   size_t ContentSize = 0;
-  if (RawSec.Content) {
-    RawSec.Content->writeAsBinary(OS);
-    ContentSize = RawSec.Content->binary_size();
+  if (Content) {
+    Content->writeAsBinary(OS);
+    ContentSize = Content->binary_size();
   }
 
-  if (!RawSec.Size)
+  if (!Size)
     return ContentSize;
 
-  OS.write_zeros(*RawSec.Size - ContentSize);
-  return *RawSec.Size;
+  OS.write_zeros(*Size - ContentSize);
+  return *Size;
 }
 
 template <class ELFT>
@@ -554,7 +555,7 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
   auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
   if (RawSec && (RawSec->Content || RawSec->Size)) {
     assert(Symbols.empty());
-    SHeader.sh_size = writeRawSectionData(OS, *RawSec);
+    SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size);
     return;
   }
 
@@ -579,7 +580,7 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
 
   auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
   if (RawSec && (RawSec->Content || RawSec->Size)) {
-    SHeader.sh_size = writeRawSectionData(OS, *RawSec);
+    SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size);
   } else {
     STB.write(OS);
     SHeader.sh_size = STB.getSize();
@@ -675,7 +676,7 @@ void ELFState<ELFT>::writeSectionContent(
     ContiguousBlobAccumulator &CBA) {
   raw_ostream &OS =
       CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
-  SHeader.sh_size = writeRawSectionData(OS, Section);
+  SHeader.sh_size = writeContent(OS, Section.Content, Section.Size);
 
   if (Section.EntSize)
     SHeader.sh_entsize = *Section.EntSize;
@@ -795,9 +796,8 @@ void ELFState<ELFT>::writeSectionContent(
   raw_ostream &OS =
       CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
 
-  if (Section.Content) {
-    Section.Content->writeAsBinary(OS);
-    SHeader.sh_size = Section.Content->binary_size();
+  if (Section.Content || Section.Size) {
+    SHeader.sh_size = writeContent(OS, Section.Content, Section.Size);
     return;
   }
 
index af795f9732cdae8e867bb3f5cc33033cc7fd919e..d369f14be4bb7d4926f9a90acf0061b4a32e379f 100644 (file)
@@ -1020,6 +1020,7 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
 static void sectionMapping(IO &IO, ELFYAML::StackSizesSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapOptional("Content", Section.Content);
+  IO.mapOptional("Size", Section.Size);
   IO.mapOptional("Entries", Section.Entries);
 }
 
@@ -1176,10 +1177,22 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
   }
 
   if (const auto *SS = dyn_cast<ELFYAML::StackSizesSection>(Section.get())) {
-    if (SS->Content && SS->Entries)
+    if (!SS->Entries && !SS->Content && !SS->Size)
+      return ".stack_sizes: one of Content, Entries and Size must be specified";
+
+    if (SS->Size && SS->Content &&
+        (uint64_t)(*SS->Size) < SS->Content->binary_size())
+      return ".stack_sizes: Size must be greater than or equal to the content "
+             "size";
+
+    // We accept Content, Size or both together when there are no Entries.
+    if (!SS->Entries)
+      return {};
+
+    if (SS->Size)
+      return ".stack_sizes: Size and Entries cannot be used together";
+    if (SS->Content)
       return ".stack_sizes: Content and Entries cannot be used together";
-    if (!SS->Content && !SS->Entries)
-      return ".stack_sizes: either Content or Entries tag must be specified";
     return {};
   }
   return {};
index f050477b2e2fc8dcac330331ebe23750ba56fb2a..c94c2c3b862f3f2626e229addbd27a31ed2d2815 100644 (file)
@@ -212,11 +212,11 @@ Sections:
       - Address: 0x10
         Size:    0x20
 
-## Check we must specify either "Content" or "Entries" tag when describing .stack_sizes.
+## Check we must specify either "Content", "Entries" or "Size" tag when describing .stack_sizes.
 
 # RUN: not yaml2obj --docnum=9 %s 2>&1 | FileCheck %s --check-prefix=NO-TAGS
 
-# NO-TAGS: error: .stack_sizes: either Content or Entries tag must be specified
+# NO-TAGS: .stack_sizes: one of Content, Entries and Size must be specified
 
 --- !ELF
 FileHeader:
@@ -227,3 +227,87 @@ FileHeader:
 Sections:
   - Name: .stack_sizes
     Type: SHT_PROGBITS
+
+## Check we can't use both "Size" and "Entries" tags at the same time.
+
+# RUN: not yaml2obj --docnum=10 %s 2>&1 | FileCheck %s --check-prefix=ENTRIES-AND-SIZE
+
+# ENTRIES-AND-SIZE: .stack_sizes: Size and Entries cannot be used together
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .stack_sizes
+    Type: SHT_PROGBITS
+    Size: 0x1
+    Entries:
+      - Address: 0x10
+        Size:    0x20
+
+## Check we can use only "Size" to create .stack_sizes section.
+
+# RUN: yaml2obj --docnum=11 %s -o %t11
+# RUN: llvm-readobj --sections --section-data %t11 | FileCheck %s --check-prefix=SIZE
+
+# SIZE:      Name: .stack_sizes
+# SIZE:      Size:
+# SIZE-SAME: 17
+# SIZE:      SectionData (
+# SIZE-NEXT:  0000: 00000000 00000000 00000000 00000000  |
+# SIZE-NEXT:  0010: 00                                   |
+# SIZE-NEXT: )
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .stack_sizes
+    Type: SHT_PROGBITS
+    Size: 0x11
+
+## Check we can use "Size" and "Content" together to create .stack_sizes section.
+
+# RUN: yaml2obj --docnum=12 %s -o %t12
+# RUN: llvm-readobj --sections --section-data %t12 | FileCheck %s --check-prefix=SIZE-CONTENT
+
+# SIZE-CONTENT:      Name: .stack_sizes
+# SIZE-CONTENT:      Size:
+# SIZE-CONTENT-SAME: 5
+# SIZE-CONTENT:      SectionData (
+# SIZE-CONTENT-NEXT:  0000: 11223300 00 |
+# SIZE-CONTENT-NEXT: )
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .stack_sizes
+    Type: SHT_PROGBITS
+    Size: 0x5
+    Content: "112233"
+
+# RUN: not yaml2obj --docnum=13 %s 2>&1 | FileCheck %s --check-prefix=SIZE-CONTENT-ERR
+
+# SIZE-CONTENT-ERR: error: .stack_sizes: Size must be greater than or equal to the content size
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .stack_sizes
+    Type: SHT_PROGBITS
+    Size: 0x1
+    Content: "1122"