[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