Skip to content

Commit 26db845

Browse files
[XCOFF] Support the subtype flag in DWARF section headers (#81667)
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.
1 parent a1a6860 commit 26db845

File tree

10 files changed

+246
-67
lines changed

10 files changed

+246
-67
lines changed

llvm/include/llvm/Object/XCOFFObjectFile.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,19 @@ struct XCOFFAuxiliaryHeader64 : XCOFFAuxiliaryHeader<XCOFFAuxiliaryHeader64> {
153153
};
154154

155155
template <typename T> struct XCOFFSectionHeader {
156-
// Least significant 3 bits are reserved.
156+
// The section flags definitions are the same in both 32- and 64-bit objects.
157+
// Least significant 3 bits are reserved.
157158
static constexpr unsigned SectionFlagsReservedMask = 0x7;
158159

159160
// The low order 16 bits of section flags denotes the section type.
161+
// The high order 16 bits of section flags denotes the section subtype.
162+
// For now, this is only used for DWARF sections.
160163
static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
161164

162165
public:
163166
StringRef getName() const;
164167
uint16_t getSectionType() const;
168+
uint32_t getSectionSubtype() const;
165169
bool isReservedSectionType() const;
166170
};
167171

llvm/include/llvm/ObjectYAML/XCOFFYAML.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct Section {
7979
llvm::yaml::Hex16 NumberOfRelocations;
8080
llvm::yaml::Hex16 NumberOfLineNumbers; // Line number counts. Not supported yet.
8181
uint32_t Flags;
82+
std::optional<XCOFF::DwarfSectionSubtypeFlags> SectionSubtype;
8283
yaml::BinaryRef SectionData;
8384
std::vector<Relocation> Relocations;
8485
};
@@ -232,6 +233,10 @@ template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> {
232233
static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value);
233234
};
234235

236+
template <> struct ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags> {
237+
static void enumeration(IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value);
238+
};
239+
235240
template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
236241
static void enumeration(IO &IO, XCOFF::StorageClass &Value);
237242
};

llvm/lib/Object/XCOFFObjectFile.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ template <typename T> uint16_t XCOFFSectionHeader<T>::getSectionType() const {
6464
return DerivedXCOFFSectionHeader.Flags & SectionFlagsTypeMask;
6565
}
6666

67+
template <typename T>
68+
uint32_t XCOFFSectionHeader<T>::getSectionSubtype() const {
69+
const T &DerivedXCOFFSectionHeader = static_cast<const T &>(*this);
70+
return DerivedXCOFFSectionHeader.Flags & ~SectionFlagsTypeMask;
71+
}
72+
6773
template <typename T>
6874
bool XCOFFSectionHeader<T>::isReservedSectionType() const {
6975
return getSectionType() & SectionFlagsReservedMask;

llvm/lib/ObjectYAML/XCOFFEmitter.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,21 @@ bool XCOFFWriter::initSectionHeaders(uint64_t &CurrentOffset) {
210210
return false;
211211
}
212212
}
213+
if (InitSections[I].SectionSubtype) {
214+
uint32_t DWARFSubtype =
215+
static_cast<uint32_t>(*InitSections[I].SectionSubtype);
216+
if (InitSections[I].Flags != XCOFF::STYP_DWARF) {
217+
ErrHandler("a DWARFSectionSubtype is only allowed for a DWARF section");
218+
return false;
219+
}
220+
unsigned Mask = Is64Bit ? XCOFFSectionHeader64::SectionFlagsTypeMask
221+
: XCOFFSectionHeader32::SectionFlagsTypeMask;
222+
if (DWARFSubtype & Mask) {
223+
ErrHandler("the low-order bits of DWARFSectionSubtype must be 0");
224+
return false;
225+
}
226+
InitSections[I].Flags |= DWARFSubtype;
227+
}
213228
}
214229
return initRelocations(CurrentOffset);
215230
}

llvm/lib/ObjectYAML/XCOFFYAML.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ void ScalarBitSetTraits<XCOFF::SectionTypeFlags>::bitset(
4444
#undef ECase
4545
}
4646

47+
void ScalarEnumerationTraits<XCOFF::DwarfSectionSubtypeFlags>::enumeration(
48+
IO &IO, XCOFF::DwarfSectionSubtypeFlags &Value) {
49+
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
50+
ECase(SSUBTYP_DWINFO);
51+
ECase(SSUBTYP_DWLINE);
52+
ECase(SSUBTYP_DWPBNMS);
53+
ECase(SSUBTYP_DWPBTYP);
54+
ECase(SSUBTYP_DWARNGE);
55+
ECase(SSUBTYP_DWABREV);
56+
ECase(SSUBTYP_DWSTR);
57+
ECase(SSUBTYP_DWRNGES);
58+
ECase(SSUBTYP_DWLOC);
59+
ECase(SSUBTYP_DWFRAME);
60+
ECase(SSUBTYP_DWMAC);
61+
#undef ECase
62+
IO.enumFallback<Hex32>(Value);
63+
}
64+
4765
void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
4866
IO &IO, XCOFF::StorageClass &Value) {
4967
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
@@ -232,6 +250,7 @@ void MappingTraits<XCOFFYAML::Section>::mapping(IO &IO,
232250
IO.mapOptional("NumberOfRelocations", Sec.NumberOfRelocations);
233251
IO.mapOptional("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
234252
IO.mapOptional("Flags", NC->Flags);
253+
IO.mapOptional("DWARFSectionSubtype", Sec.SectionSubtype);
235254
IO.mapOptional("SectionData", Sec.SectionData);
236255
IO.mapOptional("Relocations", Sec.Relocations);
237256
}

llvm/test/CodeGen/PowerPC/aix-dwarf.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ entry:
8484
; SEC-NEXT: NumberOfRelocations: 0
8585
; SEC-NEXT: NumberOfLineNumbers: 0
8686
; SEC-NEXT: Type: STYP_DWARF (0x10)
87+
; SEC-NEXT: DWARFSubType: SSUBTYP_DWABREV (0x60000)
8788
; SEC-NEXT: }
8889
; SEC-NEXT: Section {
8990
; SEC-NEXT: Index: 4
@@ -100,6 +101,7 @@ entry:
100101
; SEC-NEXT: NumberOfRelocations: 4
101102
; SEC-NEXT: NumberOfLineNumbers: 0
102103
; SEC-NEXT: Type: STYP_DWARF (0x10)
104+
; SEC-NEXT: DWARFSubType: SSUBTYP_DWINFO (0x10000)
103105
; SEC-NEXT: }
104106
; SEC-NEXT: Section {
105107
; SEC-NEXT: Index: 5
@@ -116,6 +118,7 @@ entry:
116118
; SEC-NEXT: NumberOfRelocations: 1
117119
; SEC-NEXT: NumberOfLineNumbers: 0
118120
; SEC-NEXT: Type: STYP_DWARF (0x10)
121+
; SEC-NEXT: DWARFSubType: SSUBTYP_DWLINE (0x20000)
119122
; SEC-NEXT: }
120123
; SEC-NEXT: ]
121124

llvm/test/tools/llvm-readobj/XCOFF/sections.test

Lines changed: 63 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,61 @@
22

33
# RUN: yaml2obj %s -o %t1
44
# RUN: llvm-readobj --section-headers %t1 | \
5-
# RUN: FileCheck --strict-whitespace --match-full-lines --check-prefix=SEC32 %s
5+
# RUN: FileCheck --strict-whitespace --match-full-lines --check-prefixes=SEC,SEC32 %s
6+
7+
# RUN: yaml2obj -DMAGIC=0x01F7 %s -o %t2
8+
# RUN: llvm-readobj --section-headers %t2 | \
9+
# RUN: FileCheck --strict-whitespace --match-full-lines --check-prefixes=SEC,SEC64 %s
610

711
# SEC32:Format: aixcoff-rs6000
12+
# SEC64:Format: aix5coff64-rs6000
813
# SEC32-NEXT:Arch: powerpc
14+
# SEC64-NEXT:Arch: powerpc64
915
# SEC32-NEXT:AddressSize: 32bit
10-
# SEC32-NEXT:Sections [
11-
# SEC32-NEXT: Section {
12-
# SEC32-NEXT: Index: 1
13-
# SEC32-NEXT: Name: .text
14-
# SEC32-NEXT: PhysicalAddress: 0x0
15-
# SEC32-NEXT: VirtualAddress: 0x0
16-
# SEC32-NEXT: Size: 0x2
17-
# SEC32-NEXT: RawDataOffset: 0x64
18-
# SEC32-NEXT: RelocationPointer: 0x0
19-
# SEC32-NEXT: LineNumberPointer: 0x0
20-
# SEC32-NEXT: NumberOfRelocations: 0
21-
# SEC32-NEXT: NumberOfLineNumbers: 0
22-
# SEC32-NEXT: Type: STYP_TEXT (0x20)
23-
# SEC32-NEXT: }
24-
# SEC32-NEXT: Section {
25-
# SEC32-NEXT: Index: 2
26-
# SEC32-NEXT: Name: .data
27-
# SEC32-NEXT: PhysicalAddress: 0x0
28-
# SEC32-NEXT: VirtualAddress: 0x0
29-
# SEC32-NEXT: Size: 0x2
30-
# SEC32-NEXT: RawDataOffset: 0x68
31-
# SEC32-NEXT: RelocationPointer: 0x6A
32-
# SEC32-NEXT: LineNumberPointer: 0x0
33-
# SEC32-NEXT: NumberOfRelocations: 1
34-
# SEC32-NEXT: NumberOfLineNumbers: 0
35-
# SEC32-NEXT: Type: STYP_DATA (0x40)
36-
# SEC32-NEXT: }
37-
# SEC32-NEXT:]
16+
# SEC64-NEXT:AddressSize: 64bit
17+
# SEC-NEXT:Sections [
18+
# SEC-NEXT: Section {
19+
# SEC-NEXT: Index: 1
20+
# SEC-NEXT: Name: .text
21+
# SEC-NEXT: PhysicalAddress: 0x0
22+
# SEC-NEXT: VirtualAddress: 0x0
23+
# SEC-NEXT: Size: 0x2
24+
# SEC32-NEXT: RawDataOffset: 0xB4
25+
# SEC64-NEXT: RawDataOffset: 0x138
26+
# SEC-NEXT: RelocationPointer: 0x0
27+
# SEC-NEXT: LineNumberPointer: 0x0
28+
# SEC-NEXT: NumberOfRelocations: 0
29+
# SEC-NEXT: NumberOfLineNumbers: 0
30+
# SEC-NEXT: Type: STYP_TEXT (0x20)
31+
# SEC-NEXT: }
32+
# SEC-NEXT: Section {
33+
# SEC-NEXT: Index: 2
34+
# SEC-NEXT: Name: .data
35+
# SEC-NEXT: PhysicalAddress: 0x0
36+
# SEC-NEXT: VirtualAddress: 0x0
37+
# SEC-NEXT: Size: 0x2
38+
# SEC32-NEXT: RawDataOffset: 0xB8
39+
# SEC64-NEXT: RawDataOffset: 0x13C
40+
# SEC32-NEXT: RelocationPointer: 0xC4
41+
# SEC64-NEXT: RelocationPointer: 0x148
42+
# SEC-NEXT: LineNumberPointer: 0x0
43+
# SEC-NEXT: NumberOfRelocations: 1
44+
# SEC-NEXT: NumberOfLineNumbers: 0
45+
# SEC-NEXT: Type: STYP_DATA (0x40)
46+
# SEC-NEXT: }
47+
# SEC-NEXT: Section {
48+
# SEC-NEXT: Index: 3
49+
# SEC-NEXT: Name: .dwabrev
50+
# SEC: Type: STYP_DWARF (0x10)
51+
# SEC-NEXT: DWARFSubType: SSUBTYP_DWABREV (0x60000)
52+
# SEC-NEXT: }
53+
# SEC-NEXT: Section {
54+
# SEC-NEXT: Index: 4
55+
# SEC-NEXT: Name: .dwinfo
56+
# SEC: Type: STYP_DWARF (0x10)
57+
# SEC-NEXT: DWARFSubType: SSUBTYP_DWINFO (0x10000)
58+
# SEC-NEXT: }
59+
# SEC-NEXT:]
3860

3961
--- !XCOFF
4062
FileHeader:
@@ -51,39 +73,15 @@ Sections:
5173
Symbol: 0x21
5274
Info: 0x1F
5375
Type: 0x0
54-
55-
# RUN: yaml2obj -DMAGIC=0x01F7 %s -o %t2
56-
# RUN: llvm-readobj --section-headers %t2 | \
57-
# RUN: FileCheck --strict-whitespace --match-full-lines --check-prefix=SEC64 %s
58-
59-
# SEC64:Format: aix5coff64-rs6000
60-
# SEC64-NEXT:Arch: powerpc64
61-
# SEC64-NEXT:AddressSize: 64bit
62-
# SEC64-NEXT:Sections [
63-
# SEC64-NEXT: Section {
64-
# SEC64-NEXT: Index: 1
65-
# SEC64-NEXT: Name: .text
66-
# SEC64-NEXT: PhysicalAddress: 0x0
67-
# SEC64-NEXT: VirtualAddress: 0x0
68-
# SEC64-NEXT: Size: 0x2
69-
# SEC64-NEXT: RawDataOffset: 0xA8
70-
# SEC64-NEXT: RelocationPointer: 0x0
71-
# SEC64-NEXT: LineNumberPointer: 0x0
72-
# SEC64-NEXT: NumberOfRelocations: 0
73-
# SEC64-NEXT: NumberOfLineNumbers: 0
74-
# SEC64-NEXT: Type: STYP_TEXT (0x20)
75-
# SEC64-NEXT: }
76-
# SEC64-NEXT: Section {
77-
# SEC64-NEXT: Index: 2
78-
# SEC64-NEXT: Name: .data
79-
# SEC64-NEXT: PhysicalAddress: 0x0
80-
# SEC64-NEXT: VirtualAddress: 0x0
81-
# SEC64-NEXT: Size: 0x2
82-
# SEC64-NEXT: RawDataOffset: 0xAC
83-
# SEC64-NEXT: RelocationPointer: 0xAE
84-
# SEC64-NEXT: LineNumberPointer: 0x0
85-
# SEC64-NEXT: NumberOfRelocations: 1
86-
# SEC64-NEXT: NumberOfLineNumbers: 0
87-
# SEC64-NEXT: Type: STYP_DATA (0x40)
88-
# SEC64-NEXT: }
89-
# SEC64-NEXT:]
76+
- Name: .dwabrev
77+
Address: 0x0
78+
Size: 0x4
79+
Flags: [ STYP_DWARF ]
80+
DWARFSectionSubtype: SSUBTYP_DWABREV
81+
SectionData: 01110125
82+
- Name: .dwinfo
83+
Address: 0x0
84+
Size: 0x4
85+
Flags: [ STYP_DWARF ]
86+
DWARFSectionSubtype: SSUBTYP_DWINFO
87+
SectionData: 00000080
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
## Test that we can generate and read DWARF section headers.
2+
3+
# RUN: yaml2obj --docnum=1 %s -o %t32
4+
# RUN: obj2yaml %t32 | FileCheck --check-prefix=YAML %s
5+
6+
# RUN: yaml2obj --docnum=1 -DMAGIC=0x01F7 %s -o %t64
7+
# RUN: obj2yaml %t64 | FileCheck --check-prefix=YAML %s
8+
9+
# YAML: - Name: .dwabrev
10+
# YAML: Flags: [ STYP_DWARF ]
11+
# YAML-NEXT: DWARFSectionSubtype: SSUBTYP_DWABREV
12+
# YAML: - Name: .dwinfo
13+
# YAML: Flags: [ STYP_DWARF ]
14+
# YAML-NEXT: DWARFSectionSubtype: SSUBTYP_DWINFO
15+
# YAML: - Name: .dwline
16+
# YAML: Flags: [ STYP_DWARF ]
17+
# YAML-NEXT: DWARFSectionSubtype: SSUBTYP_DWLINE
18+
19+
--- !XCOFF
20+
FileHeader:
21+
MagicNumber: [[MAGIC=0x01DF]]
22+
NumberOfSections: 4
23+
CreationTime: 0
24+
AuxiliaryHeaderSize: 0
25+
Flags: 0x0
26+
Sections:
27+
- Name: .data
28+
Address: 0x0
29+
Size: 0x4
30+
Flags: [ STYP_DATA ]
31+
SectionData: '00000001'
32+
- Name: .dwabrev
33+
Address: 0x0
34+
Size: 0x4
35+
Flags: [ STYP_DWARF ]
36+
DWARFSectionSubtype: SSUBTYP_DWABREV
37+
SectionData: 01110125
38+
- Name: .dwinfo
39+
Address: 0x0
40+
Size: 0x4
41+
Flags: [ STYP_DWARF ]
42+
DWARFSectionSubtype: SSUBTYP_DWINFO
43+
SectionData: 00000080
44+
- Name: .dwline
45+
Address: 0x0
46+
Size: 0x4
47+
Flags: [ STYP_DWARF ]
48+
DWARFSectionSubtype: SSUBTYP_DWLINE
49+
SectionData: 00000021
50+
StringTable: {}
51+
...
52+
53+
## Test that an invalid DWARF section subtype is diagnosed.
54+
# RUN: not yaml2obj --docnum=2 %s -o %t 2>&1 | FileCheck --check-prefix=ERR1 %s
55+
56+
# ERR1: the low-order bits of DWARFSectionSubtype must be 0
57+
58+
--- !XCOFF
59+
FileHeader:
60+
MagicNumber: 0x01DF
61+
NumberOfSections: 2
62+
CreationTime: 0
63+
AuxiliaryHeaderSize: 0
64+
Flags: 0x0
65+
Sections:
66+
- Name: .data
67+
Address: 0x0
68+
Size: 0x4
69+
Flags: [ STYP_DATA ]
70+
SectionData: '00000001'
71+
- Name: .dwabrev
72+
Address: 0x0
73+
Size: 0x4
74+
Flags: [ STYP_DWARF ]
75+
DWARFSectionSubtype: 0x12345
76+
SectionData: 01110125
77+
StringTable: {}
78+
...
79+
80+
## Test that a DWARF section subtype on a non-DWARF section is diagnosed.
81+
# RUN: not yaml2obj --docnum=3 %s -o %t 2>&1 | FileCheck --check-prefix=ERR2 %s
82+
83+
# ERR2: a DWARFSectionSubtype is only allowed for a DWARF section
84+
85+
--- !XCOFF
86+
FileHeader:
87+
MagicNumber: 0x01DF
88+
NumberOfSections: 2
89+
CreationTime: 0
90+
AuxiliaryHeaderSize: 0
91+
Flags: 0x0
92+
Sections:
93+
- Name: .data
94+
Address: 0x0
95+
Size: 0x4
96+
Flags: [ STYP_DATA ]
97+
DWARFSectionSubtype: SSUBTYP_DWABREV
98+
SectionData: '00000001'
99+
- Name: .dwabrev
100+
Address: 0x0
101+
Size: 0x4
102+
Flags: [ STYP_DWARF ]
103+
SectionData: 01110125
104+
StringTable: {}
105+
...

0 commit comments

Comments
 (0)