[llvm] r369348 - [yaml2obj/obj2yaml][MachO] Allow setting custom section data

Seiya Nuta via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 20 01:49:07 PDT 2019


Author: seiya
Date: Tue Aug 20 01:49:07 2019
New Revision: 369348

URL: http://llvm.org/viewvc/llvm-project?rev=369348&view=rev
Log:
[yaml2obj/obj2yaml][MachO] Allow setting custom section data

Reviewers: alexshap, jhenderson, rupprecht

Reviewed By: alexshap, jhenderson

Subscribers: abrachet, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65799

Added:
    llvm/trunk/test/ObjectYAML/MachO/section_data.yaml
Modified:
    llvm/trunk/include/llvm/BinaryFormat/MachO.h
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/lib/ObjectYAML/MachOEmitter.cpp
    llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
    llvm/trunk/test/ObjectYAML/MachO/virtual_section.yaml
    llvm/trunk/tools/obj2yaml/macho2yaml.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/MachO.h?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/MachO.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/MachO.h Tue Aug 20 01:49:07 2019
@@ -581,6 +581,11 @@ struct section_64 {
   uint32_t reserved3;
 };
 
+inline bool isVirtualSection(uint8_t type) {
+  return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL ||
+          type == MachO::S_THREAD_LOCAL_ZEROFILL);
+}
+
 struct fvmlib {
   uint32_t name;
   uint32_t minor_version;

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Tue Aug 20 01:49:07 2019
@@ -297,6 +297,7 @@ public:
   uint64_t getSectionAddress(DataRefImpl Sec) const override;
   uint64_t getSectionIndex(DataRefImpl Sec) const override;
   uint64_t getSectionSize(DataRefImpl Sec) const override;
+  ArrayRef<uint8_t> getSectionContents(uint32_t Offset, uint64_t Size) const;
   Expected<ArrayRef<uint8_t>>
   getSectionContents(DataRefImpl Sec) const override;
   uint64_t getSectionAlignment(DataRefImpl Sec) const override;

Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Tue Aug 20 01:49:07 2019
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/ObjectYAML/DWARFYAML.h"
+#include "llvm/ObjectYAML/YAML.h"
 #include "llvm/Support/YAMLTraits.h"
 #include <cstdint>
 #include <string>
@@ -39,6 +40,7 @@ struct Section {
   llvm::yaml::Hex32 reserved1;
   llvm::yaml::Hex32 reserved2;
   llvm::yaml::Hex32 reserved3;
+  Optional<llvm::yaml::BinaryRef> content;
 };
 
 struct FileHeader {
@@ -198,6 +200,7 @@ template <> struct MappingTraits<MachOYA
 
 template <> struct MappingTraits<MachOYAML::Section> {
   static void mapping(IO &IO, MachOYAML::Section &Section);
+  static StringRef validate(IO &io, MachOYAML::Section &Section);
 };
 
 template <> struct MappingTraits<MachOYAML::NListEntry> {

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Tue Aug 20 01:49:07 2019
@@ -1945,6 +1945,11 @@ uint64_t MachOObjectFile::getSectionSize
   return SectSize;
 }
 
+ArrayRef<uint8_t> MachOObjectFile::getSectionContents(uint32_t Offset,
+                                                      uint64_t Size) const {
+  return arrayRefFromStringRef(getData().substr(Offset, Size));
+}
+
 Expected<ArrayRef<uint8_t>>
 MachOObjectFile::getSectionContents(DataRefImpl Sec) const {
   uint32_t Offset;
@@ -1960,7 +1965,7 @@ MachOObjectFile::getSectionContents(Data
     Size = Sect.size;
   }
 
-  return arrayRefFromStringRef(getData().substr(Offset, Size));
+  return getSectionContents(Offset, Size);
 }
 
 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {

Modified: llvm/trunk/lib/ObjectYAML/MachOEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MachOEmitter.cpp?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MachOEmitter.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MachOEmitter.cpp Tue Aug 20 01:49:07 2019
@@ -262,11 +262,6 @@ Error MachOWriter::writeLoadCommands(raw
   return Error::success();
 }
 
-static bool isVirtualSection(uint8_t type) {
-  return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL ||
-          type == MachO::S_THREAD_LOCAL_ZEROFILL);
-}
-
 Error MachOWriter::writeSectionData(raw_ostream &OS) {
   bool FoundLinkEditSeg = false;
   for (auto &LC : Obj.LoadCommands) {
@@ -311,11 +306,17 @@ Error MachOWriter::writeSectionData(raw_
         }
 
         // Skip if it's a virtual section.
-        if (isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
+        if (MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
           continue;
 
-        // Fill section data with 0xDEADBEEF
-        Fill(OS, Sec.size, 0xDEADBEEFu);
+        if (Sec.content) {
+          yaml::BinaryRef Content = *Sec.content;
+          Content.writeAsBinary(OS);
+          ZeroFillBytes(OS, Sec.size - Content.binary_size());
+        } else {
+          // Fill section data with 0xDEADBEEF.
+          Fill(OS, Sec.size, 0xDEADBEEFu);
+        }
       }
       uint64_t segSize = is64Bit ? LC.Data.segment_command_64_data.filesize
                                  : LC.Data.segment_command_data.filesize;

Modified: llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MachOYAML.cpp?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MachOYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MachOYAML.cpp Tue Aug 20 01:49:07 2019
@@ -287,6 +287,15 @@ void MappingTraits<MachOYAML::Section>::
   IO.mapRequired("reserved1", Section.reserved1);
   IO.mapRequired("reserved2", Section.reserved2);
   IO.mapOptional("reserved3", Section.reserved3);
+  IO.mapOptional("content", Section.content);
+}
+
+StringRef
+MappingTraits<MachOYAML::Section>::validate(IO &IO,
+                                            MachOYAML::Section &Section) {
+  if (Section.content && Section.size < Section.content->binary_size())
+    return "Section size must be greater than or equal to the content size";
+  return {};
 }
 
 void MappingTraits<MachO::build_tool_version>::mapping(

Added: llvm/trunk/test/ObjectYAML/MachO/section_data.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/section_data.yaml?rev=369348&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/section_data.yaml (added)
+++ llvm/trunk/test/ObjectYAML/MachO/section_data.yaml Tue Aug 20 01:49:07 2019
@@ -0,0 +1,161 @@
+## Show that yaml2obj supports custom section data for Mach-O YAML inputs.
+
+## Case 1: The size of content is greater than the section size.
+# RUN: not yaml2obj --docnum=1 %s -o %t1 2>&1 | FileCheck %s --check-prefix=CASE1
+# CASE1: error: Section size must be greater than or equal to the content size
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           1
+  sizeofcmds:      232
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          4
+    fileoff:         392
+    filesize:        4
+    maxprot:         7
+    initprot:        7
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x0000000000000000
+        size:            0
+        offset:          0x00000188
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         CDAB3412
+
+## Case 2: The content size equals the section size.
+# RUN: yaml2obj --docnum=2 %s > %t2
+# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefix=CASE2
+# CASE2:       Index: 0
+# CASE2-NEXT:  Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+# CASE2-NEXT:  Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+# CASE2-NEXT:  Address: 0x0
+# CASE2-NEXT:  Size: 0x4
+# CASE2-NEXT:  Offset: 392
+# CASE2-NEXT:  Alignment: 2
+# CASE2-NEXT:  RelocationOffset: 0x0
+# CASE2-NEXT:  RelocationCount: 0
+# CASE2-NEXT:  Type: Regular (0x0)
+# CASE2-NEXT:  Attributes [ (0x0)
+# CASE2-NEXT:  ]
+# CASE2-NEXT:  Reserved1: 0x0
+# CASE2-NEXT:  Reserved2: 0x0
+# CASE2-NEXT:  Reserved3: 0x0
+# CASE2-NEXT:  SectionData (
+# CASE2-NEXT:    0000: CDAB3412                             |..4.|
+# CASE2-NEXT:  )
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           1
+  sizeofcmds:      232
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          4
+    fileoff:         392
+    filesize:        4
+    maxprot:         7
+    initprot:        7
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x0000000000000000
+        size:            4
+        offset:          0x00000188
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         CDAB3412
+
+## Case 3: The content size is less than the section size. In this case, the area
+## after the custom content is filled with zeroes.
+# RUN: yaml2obj --docnum=3 %s > %t3
+# RUN: llvm-readobj --sections --section-data %t3 | FileCheck %s --check-prefix=CASE3
+# CASE3:       Index: 0
+# CASE3-NEXT:  Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT:  Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+# CASE3-NEXT:  Address: 0x0
+# CASE3-NEXT:  Size: 0x4
+# CASE3-NEXT:  Offset: 392
+# CASE3-NEXT:  Alignment: 2
+# CASE3-NEXT:  RelocationOffset: 0x0
+# CASE3-NEXT:  RelocationCount: 0
+# CASE3-NEXT:  Type: Regular (0x0)
+# CASE3-NEXT:  Attributes [ (0x0)
+# CASE3-NEXT:  ]
+# CASE3-NEXT:  Reserved1: 0x0
+# CASE3-NEXT:  Reserved2: 0x0
+# CASE3-NEXT:  Reserved3: 0x0
+# CASE3-NEXT:  SectionData (
+# CASE3-NEXT:    0000: AA000000                             |....|
+# CASE3-NEXT:  )
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           1
+  sizeofcmds:      232
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          4
+    fileoff:         392
+    filesize:        4
+    maxprot:         7
+    initprot:        7
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x0000000000000000
+        size:            4
+        offset:          0x00000188
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         AA

Modified: llvm/trunk/test/ObjectYAML/MachO/virtual_section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/virtual_section.yaml?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/virtual_section.yaml (original)
+++ llvm/trunk/test/ObjectYAML/MachO/virtual_section.yaml Tue Aug 20 01:49:07 2019
@@ -163,8 +163,7 @@ LinkEditData:
     - ''
 ...
 
-# CHECK:         Sections:
-# CHECK-NEXT:      - sectname:        __text
+# CHECK:           - sectname:        __text
 # CHECK-NEXT:        segname:         __TEXT
 # CHECK-NEXT:        addr:            0x0000000000000000
 # CHECK-NEXT:        size:            72
@@ -176,6 +175,7 @@ LinkEditData:
 # CHECK-NEXT:        reserved1:       0x00000000
 # CHECK-NEXT:        reserved2:       0x00000000
 # CHECK-NEXT:        reserved3:       0x00000000
+# CHECK-NEXT:        content:         {{(EFBEADDE){18}$}}
 # CHECK-NEXT:      - sectname:        __data
 # CHECK-NEXT:        segname:         __DATA
 # CHECK-NEXT:        addr:            0x0000000000000048
@@ -188,6 +188,7 @@ LinkEditData:
 # CHECK-NEXT:        reserved1:       0x00000000
 # CHECK-NEXT:        reserved2:       0x00000000
 # CHECK-NEXT:        reserved3:       0x00000000
+# CHECK-NEXT:        content:         EFBEADDE{{$}}
 # CHECK-NEXT:      - sectname:        __bss
 # CHECK-NEXT:        segname:         __DATA
 # CHECK-NEXT:        addr:            0x00000000000000A0
@@ -224,3 +225,4 @@ LinkEditData:
 # CHECK-NEXT:        reserved1:       0x00000000
 # CHECK-NEXT:        reserved2:       0x00000000
 # CHECK-NEXT:        reserved3:       0x00000000
+# CHECK-NEXT:        content:         {{.*}}

Modified: llvm/trunk/tools/obj2yaml/macho2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/macho2yaml.cpp?rev=369348&r1=369347&r2=369348&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/macho2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/macho2yaml.cpp Tue Aug 20 01:49:07 2019
@@ -39,6 +39,15 @@ class MachODumper {
   void dumpDebugStrings(DWARFContext &DCtx,
                         std::unique_ptr<MachOYAML::Object> &Y);
 
+  template <typename SectionType>
+  MachOYAML::Section constructSectionCommon(SectionType Sec);
+  template <typename SectionType>
+  MachOYAML::Section constructSection(SectionType Sec);
+  template <typename SectionType, typename SegmentType>
+  const char *
+  extractSections(const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
+                  std::vector<MachOYAML::Section> &Sections);
+
 public:
   MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
   Expected<std::unique_ptr<MachOYAML::Object>> dump();
@@ -46,7 +55,7 @@ public:
 
 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct)                         \
   case MachO::LCName:                                                          \
-    memcpy((void *) & (LC.Data.LCStruct##_data), LoadCmd.Ptr,                  \
+    memcpy((void *)&(LC.Data.LCStruct##_data), LoadCmd.Ptr,                    \
            sizeof(MachO::LCStruct));                                           \
     if (Obj.isLittleEndian() != sys::IsLittleEndianHost)                       \
       MachO::swapStruct(LC.Data.LCStruct##_data);                              \
@@ -54,7 +63,7 @@ public:
     break;
 
 template <typename SectionType>
-MachOYAML::Section constructSectionCommon(SectionType Sec) {
+MachOYAML::Section MachODumper::constructSectionCommon(SectionType Sec) {
   MachOYAML::Section TempSec;
   memcpy(reinterpret_cast<void *>(&TempSec.sectname[0]), &Sec.sectname[0], 16);
   memcpy(reinterpret_cast<void *>(&TempSec.segname[0]), &Sec.segname[0], 16);
@@ -68,34 +77,35 @@ MachOYAML::Section constructSectionCommo
   TempSec.reserved1 = Sec.reserved1;
   TempSec.reserved2 = Sec.reserved2;
   TempSec.reserved3 = 0;
+  if (!MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
+    TempSec.content =
+        yaml::BinaryRef(Obj.getSectionContents(Sec.offset, Sec.size));
   return TempSec;
 }
 
-template <typename SectionType>
-MachOYAML::Section constructSection(SectionType Sec);
-
-template <> MachOYAML::Section constructSection(MachO::section Sec) {
+template <>
+MachOYAML::Section MachODumper::constructSection(MachO::section Sec) {
   MachOYAML::Section TempSec = constructSectionCommon(Sec);
   TempSec.reserved3 = 0;
   return TempSec;
 }
 
-template <> MachOYAML::Section constructSection(MachO::section_64 Sec) {
+template <>
+MachOYAML::Section MachODumper::constructSection(MachO::section_64 Sec) {
   MachOYAML::Section TempSec = constructSectionCommon(Sec);
   TempSec.reserved3 = Sec.reserved3;
   return TempSec;
 }
 
 template <typename SectionType, typename SegmentType>
-const char *
-extractSections(const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
-                std::vector<MachOYAML::Section> &Sections,
-                bool IsLittleEndian) {
+const char *MachODumper::extractSections(
+    const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
+    std::vector<MachOYAML::Section> &Sections) {
   auto End = LoadCmd.Ptr + LoadCmd.C.cmdsize;
   const SectionType *Curr =
       reinterpret_cast<const SectionType *>(LoadCmd.Ptr + sizeof(SegmentType));
   for (; reinterpret_cast<const void *>(Curr) < End; Curr++) {
-    if (IsLittleEndian != sys::IsLittleEndianHost) {
+    if (Obj.isLittleEndian() != sys::IsLittleEndianHost) {
       SectionType Sec;
       memcpy((void *)&Sec, Curr, sizeof(SectionType));
       MachO::swapStruct(Sec);
@@ -118,8 +128,8 @@ template <>
 const char *MachODumper::processLoadCommandData<MachO::segment_command>(
     MachOYAML::LoadCommand &LC,
     const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd) {
-  return extractSections<MachO::section, MachO::segment_command>(
-      LoadCmd, LC.Sections, Obj.isLittleEndian());
+  return extractSections<MachO::section, MachO::segment_command>(LoadCmd,
+                                                                 LC.Sections);
 }
 
 template <>
@@ -127,7 +137,7 @@ const char *MachODumper::processLoadComm
     MachOYAML::LoadCommand &LC,
     const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd) {
   return extractSections<MachO::section_64, MachO::segment_command_64>(
-      LoadCmd, LC.Sections, Obj.isLittleEndian());
+      LoadCmd, LC.Sections);
 }
 
 template <typename StructType>




More information about the llvm-commits mailing list