[llvm] [XCOFF] Peckham/yamldwarf (PR #81667)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 13 13:34:24 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-objectyaml
Author: None (stephenpeckham)
<details>
<summary>Changes</summary>
The section headers for XCOFF files have a subtype flag for Dwarf sections. This PR updates obj2yaml, yaml2obj, and llvm-readobj so that they recognize the subtype.
---
Full diff: https://github.com/llvm/llvm-project/pull/81667.diff
10 Files Affected:
- (modified) llvm/include/llvm/Object/XCOFFObjectFile.h (+7-1)
- (modified) llvm/include/llvm/ObjectYAML/XCOFFYAML.h (+5)
- (modified) llvm/lib/Object/XCOFFObjectFile.cpp (+7-2)
- (modified) llvm/lib/ObjectYAML/XCOFFEmitter.cpp (+17)
- (modified) llvm/lib/ObjectYAML/XCOFFYAML.cpp (+19)
- (modified) llvm/test/CodeGen/PowerPC/aix-dwarf.ll (+3)
- (added) llvm/test/tools/yaml2obj/XCOFF/dwarf.yaml (+108)
- (added) llvm/test/tools/yaml2obj/XCOFF/dwarf2.yaml (+104)
- (modified) llvm/tools/llvm-readobj/XCOFFDumper.cpp (+19-1)
- (modified) llvm/tools/obj2yaml/xcoff2yaml.cpp (+7)
``````````diff
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 47926ab3ae401a..7a6542ac6723b7 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -153,15 +153,21 @@ struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader64> {
};
template <typename T> struct XCOFFSectionHeader {
- // Least significant 3 bits are reserved.
+ // The section flags definitions are the same in both 32- and 64-bit objects.
+ // Least significant 3 bits are reserved.
static constexpr unsigned SectionFlagsReservedMask = 0x7;
// The low order 16 bits of section flags denotes the section type.
static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
+ // The high order 16 bits of section flags denotes the section subtype.
+ // For now, this is only used for dwarf sections.
+ static constexpr unsigned SectionFlagsSubtypeMask = 0xffff0000u;
+
public:
StringRef getName() const;
uint16_t getSectionType() const;
+ int32_t getSectionSubtype() const;
bool isReservedSectionType() const;
};
diff --git a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
index dd359ac8e53dd3..2874c998d6903c 100644
--- a/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/XCOFFYAML.h
@@ -79,6 +79,7 @@ struct Section {
llvm::yaml::Hex16 NumberOfRelocations;
llvm::yaml::Hex16 NumberOfLineNumbers; // Line number counts. Not supported yet.
uint32_t Flags;
+ std::optional<XCOFF::DwarfSectionSubtypeFlags> SectionSubtype;
yaml::BinaryRef SectionData;
std::vector<Relocation> Relocations;
};
@@ -232,6 +233,10 @@ template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> {
static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value);
};
+template <> struct ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags> {
+ static void enumeration(IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value);
+};
+
template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
static void enumeration(IO &IO, XCOFF::StorageClass &Value);
};
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 3fbd51887831e7..3138860c7e7cac 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -64,6 +64,11 @@ template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
}
+template <typename T> int32_t XCOFFSectionHeader<T>::getSectionSubtype() const {
+ const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
+ return DerivedXCOFFSectionHeader.Flags & SectionFlagsSubtypeMask;
+}
+
template <typename T>
bool XCOFFSectionHeader<T>::isReservedSectionType() const {
return getSectionType() & SectionFlagsReservedMask;
@@ -757,8 +762,8 @@ size_t XCOFFObjectFile::getFileHeaderSize() const {
}
size_t XCOFFObjectFile::getSectionHeaderSize() const {
- return is64Bit() ? sizeof(XCOFFSectionHeader64) :
- sizeof(XCOFFSectionHeader32);
+ return is64Bit() ? sizeof(XCOFFSectionHeader64)
+ : sizeof(XCOFFSectionHeader32);
}
bool XCOFFObjectFile::is64Bit() const {
diff --git a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
index f68c571da9fa0f..284e8a3b1b359d 100644
--- a/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFEmitter.cpp
@@ -210,7 +210,23 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
return false;
}
}
+ if (InitSections[I].SectionSubtype) {
+ uint32_t DwarfSubtype =
+ static_cast<uint32_t>(*InitSections[I].SectionSubtype);
+ if (InitSections[I].Flags != XCOFF::STYP_DWARF) {
+ ErrHandler("a DwarfSectionSubtype is only allowed for a dwarf section");
+ return false;
+ }
+ unsigned mask = Is64Bit ? XCOFFSectionHeader64::SectionFlagsSubtypeMask
+ : XCOFFSectionHeader32::SectionFlagsSubtypeMask;
+ if (DwarfSubtype & ~mask) {
+ ErrHandler("the low-order bits of DwarfSectionSubtype must be 0");
+ return false;
+ }
+ InitSections[I].Flags |= DwarfSubtype;
+ }
}
+
return initRelocations(CurrentOffset);
}
@@ -513,6 +529,7 @@ void XCOFFWriter::writeSectionHeaders() {
for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
XCOFFYAML::Section DerivedSec = InitSections[I];
writeName(DerivedSec.SectionName, W);
+
if (Is64Bit) {
// Virtual address is the same as physical address.
W.write<uint64_t>(DerivedSec.Address); // Physical address
diff --git a/llvm/lib/ObjectYAML/XCOFFYAML.cpp b/llvm/lib/ObjectYAML/XCOFFYAML.cpp
index 83bf61301387f0..97cb46eeb1674b 100644
--- a/llvm/lib/ObjectYAML/XCOFFYAML.cpp
+++ b/llvm/lib/ObjectYAML/XCOFFYAML.cpp
@@ -44,6 +44,24 @@ void ScalarBitSetTraits<XCOFF::SectionTypeFlags>::bitset(
#undef ECase
}
+void ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags>::enumeration(
+ IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+ ECase(SSUBTYP_DWINFO);
+ ECase(SSUBTYP_DWLINE);
+ ECase(SSUBTYP_DWPBNMS);
+ ECase(SSUBTYP_DWPBTYP);
+ ECase(SSUBTYP_DWARNGE);
+ ECase(SSUBTYP_DWABREV);
+ ECase(SSUBTYP_DWSTR);
+ ECase(SSUBTYP_DWRNGES);
+ ECase(SSUBTYP_DWLOC);
+ ECase(SSUBTYP_DWFRAME);
+ ECase(SSUBTYP_DWMAC);
+#undef ECase
+ IO.enumFallback<Hex32>(Value);
+}
+
void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
IO &IO, XCOFF::StorageClass &Value) {
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
@@ -232,6 +250,7 @@ void MappingTraits<XCOFFYAML::Section>::mapping(IO &IO,
IO.mapOptional("NumberOfRelocations", Sec.NumberOfRelocations);
IO.mapOptional("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
IO.mapOptional("Flags", NC->Flags);
+ IO.mapOptional("DwarfSectionSubtype", Sec.SectionSubtype);
IO.mapOptional("SectionData", Sec.SectionData);
IO.mapOptional("Relocations", Sec.Relocations);
}
diff --git a/llvm/test/CodeGen/PowerPC/aix-dwarf.ll b/llvm/test/CodeGen/PowerPC/aix-dwarf.ll
index eaa7c493ee6aef..5b176e30ab1ed4 100644
--- a/llvm/test/CodeGen/PowerPC/aix-dwarf.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-dwarf.ll
@@ -84,6 +84,7 @@ entry:
; SEC-NEXT: NumberOfRelocations: 0
; SEC-NEXT: NumberOfLineNumbers: 0
; SEC-NEXT: Type: STYP_DWARF (0x10)
+; SEC-NEXT: DwarfSubType: SSUBTYP_DWABREV (0x60000)
; SEC-NEXT: }
; SEC-NEXT: Section {
; SEC-NEXT: Index: 4
@@ -100,6 +101,7 @@ entry:
; SEC-NEXT: NumberOfRelocations: 4
; SEC-NEXT: NumberOfLineNumbers: 0
; SEC-NEXT: Type: STYP_DWARF (0x10)
+; SEC-NEXT: DwarfSubType: SSUBTYP_DWINFO (0x10000)
; SEC-NEXT: }
; SEC-NEXT: Section {
; SEC-NEXT: Index: 5
@@ -116,6 +118,7 @@ entry:
; SEC-NEXT: NumberOfRelocations: 1
; SEC-NEXT: NumberOfLineNumbers: 0
; SEC-NEXT: Type: STYP_DWARF (0x10)
+; SEC-NEXT: DwarfSubType: SSUBTYP_DWLINE (0x20000)
; SEC-NEXT: }
; SEC-NEXT: ]
diff --git a/llvm/test/tools/yaml2obj/XCOFF/dwarf.yaml b/llvm/test/tools/yaml2obj/XCOFF/dwarf.yaml
new file mode 100644
index 00000000000000..7896aa9e9fa87e
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/XCOFF/dwarf.yaml
@@ -0,0 +1,108 @@
+## Test that we can generate and read DWARF section headers
+# RUN: yaml2obj %s -o %t32
+# RUN: llvm-readobj --section-headers %t32 | \
+# RUN FileCheck -check-prefixes=HDRS,HDRS32 %s
+# RUN: obj2yaml %t32 | FileCheck -check-prefix=YAML %s
+
+# RUN: yaml2obj -DMAGIC=0x01F7 -DSectionOrLength=SectionOrLengthLo %s -o %t64
+# RUN: llvm-readobj --section-headers %t64 | \
+# RUN FileCheck -check-prefixes=HDRS,HDRS64 %s
+# RUN: obj2yaml %t64 | FileCheck -check-prefix=YAML %s
+
+# YAML: - Name: .dwabrev
+# YAML: Flags: [ STYP_DWARF ]
+# YAML-NEXT: DwarfSectionSubtype: SSUBTYP_DWABREV
+# YAML: - Name: .dwinfo
+# YAML: Flags: [ STYP_DWARF ]
+# YAML-NEXT: DwarfSectionSubtype: SSUBTYP_DWINFO
+# YAML: - Name: .dwline
+# YAML: Flags: [ STYP_DWARF ]
+# YAML-NEXT: DwarfSectionSubtype: SSUBTYP_DWLINE
+
+# HDRS32: Format: aixcoff-rs6000
+# HDRS64: Format: aix5coff64-rs6000
+# HDRS: Arch: powerpc
+# HDRS-NEXT: AddressSize: 32bit
+# HDRS-NEXT: Sections [
+# HDRS-NEXT: Section {
+# HDRS: Index: 1
+# HDRS-NEXT: Name: .data
+# HDRS: Type: STYP_DATA (0x40)
+# HDRS-NEXT: }
+# HDRS-NEXT: Section {
+# HDRS-NEXT: Index: 2
+# HDRS-NEXT: Name: .dwabrev
+# HDRS: Type: STYP_DWARF (0x10)
+# HDRS-NEXT: DwarfSubType: SSUBTYP_DWABREV (0x60000)
+# HDRS-NEXT: }
+# HDRS-NEXT: Section {
+# HDRS-NEXT: Index: 3
+# HDRS-NEXT: Name: .dwinfo
+# HDRS: Type: STYP_DWARF (0x10)
+# HDRS-NEXT: DwarfSubType: SSUBTYP_DWINFO (0x10000)
+# HDRS-NEXT: }
+# HDRS-NEXT: Section {
+# HDRS-NEXT: Index: 4
+# HDRS-NEXT: Name: .dwline
+# HDRS: Type: STYP_DWARF (0x10)
+# HDRS-NEXT: DwarfSubType: SSUBTYP_DWLINE (0x20000)
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: [[MAGIC=0x01DF]]
+ NumberOfSections: 4
+ CreationTime: 0
+ AuxiliaryHeaderSize: 0
+ Flags: 0x0
+Sections:
+ - Name: .data
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DATA ]
+ SectionData: '00000001'
+ - Name: .dwabrev
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DWARF ]
+ DwarfSectionSubtype: SSUBTYP_DWABREV
+ SectionData: 01110125
+ - Name: .dwinfo
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DWARF ]
+ DwarfSectionSubtype: SSUBTYP_DWINFO
+ SectionData: 00000080
+ - Name: .dwline
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DWARF ]
+ DwarfSectionSubtype: SSUBTYP_DWLINE
+ SectionData: 00000021
+Symbols:
+ - Name: .file
+ Value: 0x0
+ Section: N_DEBUG
+ Type: 0x3
+ StorageClass: C_FILE
+ NumberOfAuxEntries: 2
+ AuxEntries:
+ - Type: AUX_FILE
+ FileNameOrString: d2.c
+ FileStringType: XFT_FN
+ - Type: AUX_FILE
+ FileNameOrString: LLVM version 17.0.6
+ FileStringType: XFT_CV
+ - Name: foo
+ Value: 0x0
+ Section: .data
+ Type: 0x0
+ StorageClass: C_EXT
+ NumberOfAuxEntries: 1
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolType: XTY_SD
+ SymbolAlignment: 2
+ StorageMappingClass: XMC_RW
+ [[SectionOrLength=SectionOrLength]]: 4
+StringTable: {}
+...
diff --git a/llvm/test/tools/yaml2obj/XCOFF/dwarf2.yaml b/llvm/test/tools/yaml2obj/XCOFF/dwarf2.yaml
new file mode 100644
index 00000000000000..2ab95a95b3d6f6
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/XCOFF/dwarf2.yaml
@@ -0,0 +1,104 @@
+## Test that we can generate and read DWARF section headers
+# RUN: not yaml2obj --docnum=1 %s -o %t 2>&1 | FileCheck -check-prefix=ERR1 %s
+
+# ERR1: the low-order bits of DwarfSectionSubtype must be 0
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+ NumberOfSections: 2
+ CreationTime: 0
+ AuxiliaryHeaderSize: 0
+ Flags: 0x0
+Sections:
+ - Name: .data
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DATA ]
+ SectionData: '00000001'
+ - Name: .dwabrev
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DWARF ]
+ DwarfSectionSubtype: 0x12345
+ SectionData: 01110125
+Symbols:
+ - Name: .file
+ Value: 0x0
+ Section: N_DEBUG
+ Type: 0x3
+ StorageClass: C_FILE
+ NumberOfAuxEntries: 2
+ AuxEntries:
+ - Type: AUX_FILE
+ FileNameOrString: d2.c
+ FileStringType: XFT_FN
+ - Type: AUX_FILE
+ FileNameOrString: LLVM version 17
+ FileStringType: XFT_CV
+ - Name: foo
+ Value: 0x0
+ Section: .data
+ Type: 0x0
+ StorageClass: C_EXT
+ NumberOfAuxEntries: 1
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolType: XTY_SD
+ SymbolAlignment: 2
+ StorageMappingClass: XMC_RW
+ SectionOrLength: 4
+StringTable: {}
+...
+
+# RUN: not yaml2obj --docnum=2 %s -o %t 2>&1 | FileCheck -check-prefix=ERR2 %s
+
+# ERR2: a DwarfSectionSubtype is only allowed for a dwarf section
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01DF
+ NumberOfSections: 2
+ CreationTime: 0
+ AuxiliaryHeaderSize: 0
+ Flags: 0x0
+Sections:
+ - Name: .data
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DATA ]
+ DwarfSectionSubtype: SSUBTYP_DWABREV
+ SectionData: '00000001'
+ - Name: .dwabrev
+ Address: 0x0
+ Size: 0x4
+ Flags: [ STYP_DWARF ]
+ SectionData: 01110125
+Symbols:
+ - Name: .file
+ Value: 0x0
+ Section: N_DEBUG
+ Type: 0x3
+ StorageClass: C_FILE
+ NumberOfAuxEntries: 2
+ AuxEntries:
+ - Type: AUX_FILE
+ FileNameOrString: d2.c
+ FileStringType: XFT_FN
+ - Type: AUX_FILE
+ FileNameOrString: LLVM version 17
+ FileStringType: XFT_CV
+ - Name: foo
+ Value: 0x0
+ Section: .data
+ Type: 0x0
+ StorageClass: C_EXT
+ NumberOfAuxEntries: 1
+ AuxEntries:
+ - Type: AUX_CSECT
+ SymbolType: XTY_SD
+ SymbolAlignment: 2
+ StorageMappingClass: XMC_RW
+ SectionOrLength: 4
+StringTable: {}
+...
diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index 8ebd670d5d56af..edc844be68a161 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -111,6 +111,7 @@ void XCOFFDumper::printFileHeaders() {
TimeStamp);
}
+
// The number of symbol table entries is an unsigned value in 64-bit objects
// and a signed value (with negative values being 'reserved') in 32-bit
// objects.
@@ -983,6 +984,17 @@ const EnumEntry<XCOFF::SectionTypeFlags> SectionTypeFlagsNames[] = {
#undef ECase
};
+const EnumEntry<XCOFF::DwarfSectionSubtypeFlags>
+ DwarfSectionSubtypeFlagsNames[] = {
+#define ECase(X) \
+ { #X, XCOFF::X }
+ ECase(SSUBTYP_DWINFO), ECase(SSUBTYP_DWLINE), ECase(SSUBTYP_DWPBNMS),
+ ECase(SSUBTYP_DWPBTYP), ECase(SSUBTYP_DWARNGE), ECase(SSUBTYP_DWABREV),
+ ECase(SSUBTYP_DWSTR), ECase(SSUBTYP_DWRNGES), ECase(SSUBTYP_DWLOC),
+ ECase(SSUBTYP_DWFRAME), ECase(SSUBTYP_DWMAC)
+#undef ECase
+};
+
template <typename T>
void XCOFFDumper::printOverflowSectionHeader(T &Sec) const {
if (Obj.is64Bit()) {
@@ -1180,6 +1192,7 @@ void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
W.printNumber("Index", Index++);
uint16_t SectionType = Sec.getSectionType();
+ int32_t SectionSubtype = Sec.getSectionSubtype();
switch (SectionType) {
case XCOFF::STYP_OVRFLO:
printOverflowSectionHeader(Sec);
@@ -1197,8 +1210,13 @@ void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
}
if (Sec.isReservedSectionType())
W.printHex("Flags", "Reserved", SectionType);
- else
+ else {
W.printEnum("Type", SectionType, ArrayRef(SectionTypeFlagsNames));
+ if (SectionType == XCOFF::STYP_DWARF) {
+ W.printEnum("DwarfSubType", SectionSubtype,
+ ArrayRef(DwarfSectionSubtypeFlagsNames));
+ }
+ }
}
if (opts::SectionRelocations)
diff --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp
index e426b645cbeff6..1d04fc2902ea31 100644
--- a/llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -95,6 +95,13 @@ Error XCOFFDumper::dumpSections(ArrayRef<Shdr> Sections) {
YamlSec.FileOffsetToRelocations = S.FileOffsetToRelocationInfo;
YamlSec.FileOffsetToLineNumbers = S.FileOffsetToLineNumberInfo;
YamlSec.Flags = S.Flags;
+ if (YamlSec.Flags & XCOFF::STYP_DWARF) {
+ unsigned mask = Obj.is64Bit()
+ ? XCOFFSectionHeader64::SectionFlagsSubtypeMask
+ : XCOFFSectionHeader32::SectionFlagsSubtypeMask;
+ YamlSec.SectionSubtype =
+ static_cast<XCOFF::DwarfSectionSubtypeFlags>(S.Flags & mask);
+ }
// Dump section data.
if (S.FileOffsetToRawData) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/81667
More information about the llvm-commits
mailing list