]> granicus.if.org Git - llvm/commitdiff
[yaml2obj]Re-allow dynamic sections to have raw content
authorJames Henderson <jh7370@my.bristol.ac.uk>
Mon, 25 Feb 2019 11:02:24 +0000 (11:02 +0000)
committerJames Henderson <jh7370@my.bristol.ac.uk>
Mon, 25 Feb 2019 11:02:24 +0000 (11:02 +0000)
Recently, support was added to yaml2obj to allow dynamic sections to
have a list of entries, to make it easier to write tests with dynamic
sections. However, this change also removed the ability to provide
custom contents to the dynamic section, making it hard to test
malformed contents (e.g. because the section is not a valid size to
contain an array of entries). This change reinstates this. An error is
emitted if raw content and dynamic entries are both specified.

Reviewed by: grimar, ruiu

Differential Review: https://reviews.llvm.org/D58543

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

include/llvm/ObjectYAML/ELFYAML.h
lib/ObjectYAML/ELFYAML.cpp
test/tools/yaml2obj/dynamic-section-raw-content.yaml [new file with mode: 0644]
tools/yaml2obj/yaml2elf.cpp

index c7f517a4b650446329dfff149f33dd252002308b..91c37ece0d8a5fc805f0f4bfcb721a8547d76611 100644 (file)
@@ -141,6 +141,7 @@ struct Section {
 
 struct DynamicSection : Section {
   std::vector<DynamicEntry> Entries;
+  Optional<yaml::BinaryRef> Content;
 
   DynamicSection() : Section(SectionKind::Dynamic) {}
 
index e51454cb759f71f3479bc4ff7143967092a210de..b2b69d5c30e31d86abc0d16d2055f0c9b41a6064 100644 (file)
@@ -855,6 +855,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
 static void sectionMapping(IO &IO, ELFYAML::DynamicSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapOptional("Entries", Section.Entries);
+  IO.mapOptional("Content", Section.Content);
 }
 
 static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
diff --git a/test/tools/yaml2obj/dynamic-section-raw-content.yaml b/test/tools/yaml2obj/dynamic-section-raw-content.yaml
new file mode 100644 (file)
index 0000000..37af067
--- /dev/null
@@ -0,0 +1,44 @@
+# Show that yaml2obj can handle a dynamic section with raw content instead of
+# entries. Also show that it rejects raw content when entries are also provided.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj -x .dynamic --sections %t1 | FileCheck %s --check-prefix=RAW
+
+# RAW:      Name: .dynamic
+# RAW-NEXT: Type: SHT_DYNAMIC
+# RAW-NEXT: Flags [
+# RAW-NEXT: ]
+# RAW-NEXT: Address:
+# RAW-NEXT: Offset:
+# RAW-NEXT: Size: 5
+
+# RAW:      Hex dump of section '.dynamic':
+# RAW-NEXT: 0x00000000 01234567 89 {{.*}}
+
+# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=ERR
+# ERR: Cannot specify both raw content and explicit entries for dynamic section '.dynamic'.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+    Content: "0123456789"
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_X86_64
+Sections:
+  - Name:    .dynamic
+    Type:    SHT_DYNAMIC
+    Content: "0123456789"
+    Entries:
+      - Tag:   DT_STRSZ
+        Value: 0
index 351b734765377dc4d5e32ef46912170dd6dfe843..d651c92dd658e78226e17bc332a1c2724df69540 100644 (file)
@@ -169,7 +169,7 @@ class ELFState {
   bool writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::MipsABIFlags &Section,
                            ContiguousBlobAccumulator &CBA);
-  void writeSectionContent(Elf_Shdr &SHeader,
+  bool writeSectionContent(Elf_Shdr &SHeader,
                            const ELFYAML::DynamicSection &Section,
                            ContiguousBlobAccumulator &CBA);
   bool hasDynamicSymbols() const;
@@ -309,7 +309,8 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
       // so just to setup the section offset.
       CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
     } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec.get())) {
-      writeSectionContent(SHeader, *S, CBA);
+      if (!writeSectionContent(SHeader, *S, CBA))
+        return false;
     } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec.get())) {
       writeSectionContent(SHeader, *S, CBA);
     } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec.get())) {
@@ -713,7 +714,7 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
 }
 
 template <class ELFT>
-void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
                                          const ELFYAML::DynamicSection &Section,
                                          ContiguousBlobAccumulator &CBA) {
   typedef typename ELFT::uint uintX_t;
@@ -721,7 +722,18 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
   assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
          "Section type is not SHT_DYNAMIC");
 
-  SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
+  if (!Section.Entries.empty() && Section.Content) {
+    WithColor::error()
+        << "Cannot specify both raw content and explicit entries "
+           "for dynamic section '"
+        << Section.Name << "'.\n";
+    return false;
+  }
+
+  if (Section.Content)
+    SHeader.sh_size = Section.Content->binary_size();
+  else
+    SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size();
   if (Section.EntSize)
     SHeader.sh_entsize = *Section.EntSize;
   else
@@ -732,6 +744,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
     support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness);
     support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness);
   }
+  if (Section.Content)
+    Section.Content->writeAsBinary(OS);
+
+  return true;
 }
 
 template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {