[llvm] 2dad496 - [yaml2obj] Add support for structured COFF section data.

Jacek Caban via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 5 04:07:53 PDT 2023


Author: Jacek Caban
Date: 2023-07-05T13:06:37+02:00
New Revision: 2dad496be35332f2c076a06b13d2dab3a37026cf

URL: https://github.com/llvm/llvm-project/commit/2dad496be35332f2c076a06b13d2dab3a37026cf
DIFF: https://github.com/llvm/llvm-project/commit/2dad496be35332f2c076a06b13d2dab3a37026cf.diff

LOG: [yaml2obj] Add support for structured COFF section data.

Reviewed By: jhenderson
Differential Revision: https://reviews.llvm.org/D149439

Added: 
    llvm/test/tools/yaml2obj/COFF/invalid-raw-data.yaml
    llvm/test/tools/yaml2obj/COFF/mixed-data.yaml
    llvm/test/tools/yaml2obj/COFF/structured-data.yaml

Modified: 
    llvm/docs/yaml2obj.rst
    llvm/include/llvm/ObjectYAML/COFFYAML.h
    llvm/lib/ObjectYAML/COFFEmitter.cpp
    llvm/lib/ObjectYAML/COFFYAML.cpp
    llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml

Removed: 
    


################################################################################
diff  --git a/llvm/docs/yaml2obj.rst b/llvm/docs/yaml2obj.rst
index d18ce02a336c59..a0bca068d36420 100644
--- a/llvm/docs/yaml2obj.rst
+++ b/llvm/docs/yaml2obj.rst
@@ -29,6 +29,11 @@ Here's a sample COFF file.
                        ] # 0x60500020
       SectionData:
         "\x83\xEC\x0C\xC7\x44\x24\x08\x00\x00\x00\x00\xC7\x04\x24\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x8B\x44\x24\x08\x83\xC4\x0C\xC3" # |....D$.......$...............D$.....|
+    - Name: .rdata
+      Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+      StructuredData:
+        - Binary: {type: str}
+        - UInt32: {type: int}
 
   symbols:
     - Name: .text

diff  --git a/llvm/include/llvm/ObjectYAML/COFFYAML.h b/llvm/include/llvm/ObjectYAML/COFFYAML.h
index fbd8298919bd21..1d941ae7b1a3e3 100644
--- a/llvm/include/llvm/ObjectYAML/COFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/COFFYAML.h
@@ -66,6 +66,14 @@ struct Relocation {
   std::optional<uint32_t> SymbolTableIndex;
 };
 
+struct SectionDataEntry {
+  std::optional<uint32_t> UInt32;
+  yaml::BinaryRef Binary;
+
+  size_t size() const;
+  void writeAsBinary(raw_ostream &OS) const;
+};
+
 struct Section {
   COFF::section Header;
   unsigned Alignment = 0;
@@ -74,6 +82,7 @@ struct Section {
   std::vector<CodeViewYAML::LeafRecord> DebugT;
   std::vector<CodeViewYAML::LeafRecord> DebugP;
   std::optional<CodeViewYAML::DebugHSection> DebugH;
+  std::vector<SectionDataEntry> StructuredData;
   std::vector<Relocation> Relocations;
   StringRef Name;
 
@@ -117,6 +126,7 @@ struct Object {
 LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section)
 LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol)
 LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation)
+LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::SectionDataEntry)
 
 namespace llvm {
 namespace yaml {
@@ -241,6 +251,10 @@ struct MappingTraits<COFFYAML::Symbol> {
   static void mapping(IO &IO, COFFYAML::Symbol &S);
 };
 
+template <> struct MappingTraits<COFFYAML::SectionDataEntry> {
+  static void mapping(IO &IO, COFFYAML::SectionDataEntry &Sec);
+};
+
 template <>
 struct MappingTraits<COFFYAML::Section> {
   static void mapping(IO &IO, COFFYAML::Section &Sec);

diff  --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp
index f8a285d36f9c03..b4ce90ddc87b85 100644
--- a/llvm/lib/ObjectYAML/COFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp
@@ -242,10 +242,13 @@ static bool layoutCOFF(COFFParser &CP) {
         S.SectionData = CodeViewYAML::toDebugH(*S.DebugH, CP.Allocator);
     }
 
-    if (S.SectionData.binary_size() > 0) {
+    size_t DataSize = S.SectionData.binary_size();
+    for (auto E : S.StructuredData)
+      DataSize += E.size();
+    if (DataSize > 0) {
       CurrentSectionDataOffset = alignTo(CurrentSectionDataOffset,
                                          CP.isPE() ? CP.getFileAlignment() : 4);
-      S.Header.SizeOfRawData = S.SectionData.binary_size();
+      S.Header.SizeOfRawData = DataSize;
       if (CP.isPE())
         S.Header.SizeOfRawData =
             alignTo(S.Header.SizeOfRawData, CP.getFileAlignment());
@@ -496,9 +499,12 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
       continue;
     assert(S.Header.PointerToRawData >= OS.tell());
     OS.write_zeros(S.Header.PointerToRawData - OS.tell());
+    for (auto E : S.StructuredData)
+      E.writeAsBinary(OS);
     S.SectionData.writeAsBinary(OS);
     assert(S.Header.SizeOfRawData >= S.SectionData.binary_size());
-    OS.write_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size());
+    OS.write_zeros(S.Header.PointerToRawData + S.Header.SizeOfRawData -
+                   OS.tell());
     if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL)
       OS << binary_le<uint32_t>(/*VirtualAddress=*/ S.Relocations.size() + 1)
          << binary_le<uint32_t>(/*SymbolTableIndex=*/ 0)
@@ -588,6 +594,19 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
   return true;
 }
 
+size_t COFFYAML::SectionDataEntry::size() const {
+  size_t Size = Binary.binary_size();
+  if (UInt32)
+    Size += sizeof(*UInt32);
+  return Size;
+}
+
+void COFFYAML::SectionDataEntry::writeAsBinary(raw_ostream &OS) const {
+  if (UInt32)
+    OS << binary_le(*UInt32);
+  Binary.writeAsBinary(OS);
+}
+
 namespace llvm {
 namespace yaml {
 

diff  --git a/llvm/lib/ObjectYAML/COFFYAML.cpp b/llvm/lib/ObjectYAML/COFFYAML.cpp
index fe9a9f89313810..5ef634cbf1ed52 100644
--- a/llvm/lib/ObjectYAML/COFFYAML.cpp
+++ b/llvm/lib/ObjectYAML/COFFYAML.cpp
@@ -547,6 +547,12 @@ void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
   IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
 }
 
+void MappingTraits<COFFYAML::SectionDataEntry>::mapping(
+    IO &IO, COFFYAML::SectionDataEntry &E) {
+  IO.mapOptional("UInt32", E.UInt32);
+  IO.mapOptional("Binary", E.Binary);
+}
+
 void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
   MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
 
@@ -586,9 +592,16 @@ void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
   else if (Sec.Name == ".debug$H")
     IO.mapOptional("GlobalHashes", Sec.DebugH);
 
+  IO.mapOptional("StructuredData", Sec.StructuredData);
+
+  if (!Sec.StructuredData.empty() && Sec.SectionData.binary_size()) {
+    IO.setError("StructuredData and SectionData can't be used together");
+    return;
+  }
+
   // Uninitialized sections, such as .bss, typically have no data, but the size
   // is carried in SizeOfRawData, even though PointerToRawData is zero.
-  if (Sec.SectionData.binary_size() == 0 &&
+  if (Sec.SectionData.binary_size() == 0 && Sec.StructuredData.empty() &&
       NC->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
     IO.mapOptional("SizeOfRawData", Sec.Header.SizeOfRawData);
 

diff  --git a/llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml b/llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml
index 629fe027b64e33..e3758da799bd36 100644
--- a/llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml
+++ b/llvm/test/tools/llvm-readobj/arm64ec-chpe.yaml
@@ -44,6 +44,42 @@ sections:
     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
     VirtualAddress:  0x5000
     VirtualSize:     144
-    SectionData:     '010000005050000003000000685000008050000000000000000000000000000000000000000000000000000000000000020000000200000000000000000000000000000000000000000000000000000001100000300000000020000040000000023000005000000000100000201000000010000020100000401000000020000000100000002000002010000030200000'
+    StructuredData:
+      - UInt32: 1       # Version
+      - UInt32: 0x5050  # CodeMap
+      - UInt32: 3       # CodeMapCount
+      - UInt32: 0x5068  # CodeRangesToEntryPoints
+      - UInt32: 0x5080  # RedirectionMetadata
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 2       # CodeRangesToEntryPointsCount
+      - UInt32: 2       # RedirectionMetadataCount
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0
+      - UInt32: 0x1001  # CodeMap[0]
+      - UInt32: 0x30
+      - UInt32: 0x2000  # CodeMap[1]
+      - UInt32: 0x40
+      - UInt32: 0x3002  # CodeMap[2]
+      - UInt32: 0x50
+      - UInt32: 0x1000  # CodeRangesToEntryPoints[0]
+      - UInt32: 0x1020
+      - UInt32: 0x1000
+      - UInt32: 0x1020  # CodeRangesToEntryPoints[1]
+      - UInt32: 0x1040
+      - UInt32: 0x2000
+      - UInt32: 0x1000  # RedirectionMetadata[0]
+      - UInt32: 0x2000
+      - UInt32: 0x1020  # RedirectionMetadata[1]
+      - UInt32: 0x2030
 symbols:         []
 ...

diff  --git a/llvm/test/tools/yaml2obj/COFF/invalid-raw-data.yaml b/llvm/test/tools/yaml2obj/COFF/invalid-raw-data.yaml
new file mode 100644
index 00000000000000..62445fa1858b86
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/COFF/invalid-raw-data.yaml
@@ -0,0 +1,22 @@
+# RUN: not yaml2obj %s -o %t 2>&1 | FileCheck %s
+# CHECK: YAML:18:5: error: unknown key 'SizeOfRawData'
+
+--- !COFF
+OptionalHeader:
+  ImageBase:        0x180000000
+  SectionAlignment: 4096
+  FileAlignment:    512
+  DLLCharacteristics: [ ]
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ]
+sections:
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  0x1000
+    VirtualSize:     20
+    SizeOfRawData:   4
+    StructuredData:
+        - UInt32: 1
+symbols: []
+...

diff  --git a/llvm/test/tools/yaml2obj/COFF/mixed-data.yaml b/llvm/test/tools/yaml2obj/COFF/mixed-data.yaml
new file mode 100644
index 00000000000000..7f23f4de3dff65
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/COFF/mixed-data.yaml
@@ -0,0 +1,22 @@
+# RUN: not yaml2obj %s -o %t 2>&1 | FileCheck %s
+# CHECK: error: StructuredData and SectionData can't be used together
+
+--- !COFF
+OptionalHeader:
+  ImageBase:        0x180000000
+  SectionAlignment: 4096
+  FileAlignment:    512
+  DLLCharacteristics: [ ]
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ]
+sections:
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  0x1000
+    VirtualSize:     20
+    SectionData:     55
+    StructuredData:
+        - UInt32: 1
+symbols: []
+...

diff  --git a/llvm/test/tools/yaml2obj/COFF/structured-data.yaml b/llvm/test/tools/yaml2obj/COFF/structured-data.yaml
new file mode 100644
index 00000000000000..687c43de2a796d
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/COFF/structured-data.yaml
@@ -0,0 +1,25 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj --hex-dump=.rdata %t | FileCheck %s
+# CHECK:  0x180001000 01000000 02000000 11223344 ffffffff
+
+--- !COFF
+OptionalHeader:
+  ImageBase:        0x180000000
+  SectionAlignment: 4096
+  FileAlignment:    512
+  DLLCharacteristics: [ ]
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ]
+sections:
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  0x1000
+    VirtualSize:     20
+    StructuredData:
+        - UInt32: 1
+        - UInt32: 2
+        - Binary: 11223344
+        - UInt32: 0xffffffff
+symbols: []
+...


        


More information about the llvm-commits mailing list