@@ -32,6 +32,7 @@ using namespace llvm::support;
32
32
33
33
namespace {
34
34
class XCOFFDumper : public objdump ::Dumper {
35
+ enum PrintStyle { Hex, Number };
35
36
const XCOFFObjectFile &Obj;
36
37
unsigned Width;
37
38
@@ -41,14 +42,32 @@ class XCOFFDumper : public objdump::Dumper {
41
42
private:
42
43
void printPrivateHeaders () override ;
43
44
void printFileHeader ();
44
- FormattedString formatName (StringRef Name);
45
+ void printAuxiliaryHeader ();
46
+ void printAuxiliaryHeader (const XCOFFAuxiliaryHeader32 *AuxHeader);
47
+ void printAuxiliaryHeader (const XCOFFAuxiliaryHeader64 *AuxHeader);
48
+ template <typename AuxHeaderMemberType, typename XCOFFAuxiliaryHeader>
49
+ void printAuxMemberHelper (PrintStyle Style, const char *MemberName,
50
+ const AuxHeaderMemberType &Member,
51
+ const XCOFFAuxiliaryHeader *AuxHeader,
52
+ uint16_t AuxSize, uint16_t &PartialFieldOffset,
53
+ const char *&PartialFieldName);
54
+ template <typename XCOFFAuxiliaryHeader>
55
+ void checkAndPrintAuxHeaderParseError (const char *PartialFieldName,
56
+ uint16_t PartialFieldOffset,
57
+ uint16_t AuxSize,
58
+ XCOFFAuxiliaryHeader &AuxHeader);
59
+
60
+ void printBinary (StringRef Name, ArrayRef<uint8_t > Data);
45
61
void printHex (StringRef Name, uint64_t Value);
46
62
void printNumber (StringRef Name, uint64_t Value);
63
+ FormattedString formatName (StringRef Name);
47
64
void printStrHex (StringRef Name, StringRef Str, uint64_t Value);
48
- void setWidth (unsigned W) { Width = W; };
49
65
};
50
66
51
- void XCOFFDumper::printPrivateHeaders () { printFileHeader (); }
67
+ void XCOFFDumper::printPrivateHeaders () {
68
+ printFileHeader ();
69
+ printAuxiliaryHeader ();
70
+ }
52
71
53
72
FormattedString XCOFFDumper::formatName (StringRef Name) {
54
73
return FormattedString (Name, Width, FormattedString::JustifyLeft);
@@ -67,8 +86,185 @@ void XCOFFDumper::printStrHex(StringRef Name, StringRef Str, uint64_t Value) {
67
86
<< " )\n " ;
68
87
}
69
88
89
+ void XCOFFDumper::printBinary (StringRef Name, ArrayRef<uint8_t > Data) {
90
+ unsigned OrgWidth = Width;
91
+ Width = 0 ;
92
+ outs () << formatName (Name) << " (" << format_bytes (Data) << " )\n " ;
93
+ Width = OrgWidth;
94
+ }
95
+
96
+ void XCOFFDumper::printAuxiliaryHeader () {
97
+ Width = 36 ;
98
+ if (Obj.is64Bit ())
99
+ printAuxiliaryHeader (Obj.auxiliaryHeader64 ());
100
+ else
101
+ printAuxiliaryHeader (Obj.auxiliaryHeader32 ());
102
+ }
103
+
104
+ template <typename AuxHeaderMemberType, typename XCOFFAuxiliaryHeader>
105
+ void XCOFFDumper::printAuxMemberHelper (PrintStyle Style, const char *MemberName,
106
+ const AuxHeaderMemberType &Member,
107
+ const XCOFFAuxiliaryHeader *AuxHeader,
108
+ uint16_t AuxSize,
109
+ uint16_t &PartialFieldOffset,
110
+ const char *&PartialFieldName) {
111
+ ptrdiff_t Offset = reinterpret_cast <const char *>(&Member) -
112
+ reinterpret_cast <const char *>(AuxHeader);
113
+ if (Offset + sizeof (Member) <= AuxSize) {
114
+ if (Style == Hex)
115
+ printHex (MemberName, Member);
116
+ else
117
+ printNumber (MemberName, Member);
118
+ } else if (Offset < AuxSize) {
119
+ PartialFieldOffset = Offset;
120
+ PartialFieldName = MemberName;
121
+ }
122
+ }
123
+
124
+ template <typename XCOFFAuxiliaryHeader>
125
+ void XCOFFDumper::checkAndPrintAuxHeaderParseError (
126
+ const char *PartialFieldName, uint16_t PartialFieldOffset, uint16_t AuxSize,
127
+ XCOFFAuxiliaryHeader &AuxHeader) {
128
+ if (PartialFieldOffset < AuxSize) {
129
+ std::string Buf;
130
+ raw_string_ostream OS (Buf);
131
+ OS.flush ();
132
+ OS << FormattedString (" Raw data" , 0 , FormattedString::JustifyLeft) << " ("
133
+ << format_bytes (
134
+ ArrayRef<uint8_t >(reinterpret_cast <const uint8_t *>(&AuxHeader) +
135
+ PartialFieldOffset,
136
+ AuxSize - PartialFieldOffset))
137
+ << " )\n " ;
138
+ reportUniqueWarning (Twine (" only partial field for " ) + PartialFieldName +
139
+ " at offset (" + Twine (PartialFieldOffset) + " )\n " +
140
+ OS.str ());
141
+ } else if (sizeof (AuxHeader) < AuxSize) {
142
+ printBinary (
143
+ " Extra raw data" ,
144
+ ArrayRef<uint8_t >(reinterpret_cast <const uint8_t *>(&AuxHeader) +
145
+ sizeof (AuxHeader),
146
+ AuxSize - sizeof (AuxHeader)));
147
+ }
148
+ }
149
+
150
+ void XCOFFDumper::printAuxiliaryHeader (
151
+ const XCOFFAuxiliaryHeader32 *AuxHeader) {
152
+ if (AuxHeader == nullptr )
153
+ return ;
154
+ outs () << " \n ---Auxiliary Header:\n " ;
155
+ uint16_t AuxSize = Obj.getOptionalHeaderSize ();
156
+ uint16_t PartialFieldOffset = AuxSize;
157
+ const char *PartialFieldName = nullptr ;
158
+
159
+ auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
160
+ auto &Member) {
161
+ printAuxMemberHelper (Style, MemberName, Member, AuxHeader, AuxSize,
162
+ PartialFieldOffset, PartialFieldName);
163
+ };
164
+
165
+ PrintAuxMember (Hex, " Magic:" , AuxHeader->AuxMagic );
166
+ PrintAuxMember (Hex, " Version:" , AuxHeader->Version );
167
+ PrintAuxMember (Hex, " Size of .text section:" , AuxHeader->TextSize );
168
+ PrintAuxMember (Hex, " Size of .data section:" , AuxHeader->InitDataSize );
169
+ PrintAuxMember (Hex, " Size of .bss section:" , AuxHeader->BssDataSize );
170
+ PrintAuxMember (Hex, " Entry point address:" , AuxHeader->EntryPointAddr );
171
+ PrintAuxMember (Hex, " .text section start address:" , AuxHeader->TextStartAddr );
172
+ PrintAuxMember (Hex, " .data section start address:" , AuxHeader->DataStartAddr );
173
+ PrintAuxMember (Hex, " TOC anchor address:" , AuxHeader->TOCAnchorAddr );
174
+ PrintAuxMember (
175
+ Number, " Section number of entryPoint:" , AuxHeader->SecNumOfEntryPoint );
176
+ PrintAuxMember (Number, " Section number of .text:" , AuxHeader->SecNumOfText );
177
+ PrintAuxMember (Number, " Section number of .data:" , AuxHeader->SecNumOfData );
178
+ PrintAuxMember (Number, " Section number of TOC:" , AuxHeader->SecNumOfTOC );
179
+ PrintAuxMember (Number,
180
+ " Section number of loader data:" , AuxHeader->SecNumOfLoader );
181
+ PrintAuxMember (Number, " Section number of .bss:" , AuxHeader->SecNumOfBSS );
182
+ PrintAuxMember (Hex, " Maxium alignment of .text:" , AuxHeader->MaxAlignOfText );
183
+ PrintAuxMember (Hex, " Maxium alignment of .data:" , AuxHeader->MaxAlignOfData );
184
+ PrintAuxMember (Hex, " Module type:" , AuxHeader->ModuleType );
185
+ PrintAuxMember (Hex, " CPU type of objects:" , AuxHeader->CpuFlag );
186
+ PrintAuxMember (Hex, " Maximum stack size:" , AuxHeader->MaxStackSize );
187
+ PrintAuxMember (Hex, " Maximum data size:" , AuxHeader->MaxDataSize );
188
+ PrintAuxMember (Hex, " Reserved for debugger:" , AuxHeader->ReservedForDebugger );
189
+ PrintAuxMember (Hex, " Text page size:" , AuxHeader->TextPageSize );
190
+ PrintAuxMember (Hex, " Data page size:" , AuxHeader->DataPageSize );
191
+ PrintAuxMember (Hex, " Stack page size:" , AuxHeader->StackPageSize );
192
+ if (offsetof (XCOFFAuxiliaryHeader32, FlagAndTDataAlignment) +
193
+ sizeof (XCOFFAuxiliaryHeader32::FlagAndTDataAlignment) <=
194
+ AuxSize) {
195
+ printHex (" Flag:" , AuxHeader->getFlag ());
196
+ printHex (" Alignment of thread-local storage:" ,
197
+ AuxHeader->getTDataAlignment ());
198
+ }
199
+
200
+ PrintAuxMember (Number,
201
+ " Section number for .tdata:" , AuxHeader->SecNumOfTData );
202
+ PrintAuxMember (Number, " Section number for .tbss:" , AuxHeader->SecNumOfTBSS );
203
+
204
+ checkAndPrintAuxHeaderParseError (PartialFieldName, PartialFieldOffset,
205
+ AuxSize, *AuxHeader);
206
+ }
207
+
208
+ void XCOFFDumper::printAuxiliaryHeader (
209
+ const XCOFFAuxiliaryHeader64 *AuxHeader) {
210
+ if (AuxHeader == nullptr )
211
+ return ;
212
+ uint16_t AuxSize = Obj.getOptionalHeaderSize ();
213
+ outs () << " \n ---Auxiliary Header:\n " ;
214
+ uint16_t PartialFieldOffset = AuxSize;
215
+ const char *PartialFieldName = nullptr ;
216
+
217
+ auto PrintAuxMember = [&](PrintStyle Style, const char *MemberName,
218
+ auto &Member) {
219
+ printAuxMemberHelper (Style, MemberName, Member, AuxHeader, AuxSize,
220
+ PartialFieldOffset, PartialFieldName);
221
+ };
222
+
223
+ PrintAuxMember (Hex, " Magic:" , AuxHeader->AuxMagic );
224
+ PrintAuxMember (Hex, " Version:" , AuxHeader->Version );
225
+ PrintAuxMember (Hex, " Reserved for debugger:" , AuxHeader->ReservedForDebugger );
226
+ PrintAuxMember (Hex, " .text section start address:" , AuxHeader->TextStartAddr );
227
+ PrintAuxMember (Hex, " .data section start address:" , AuxHeader->DataStartAddr );
228
+ PrintAuxMember (Hex, " TOC anchor address:" , AuxHeader->TOCAnchorAddr );
229
+ PrintAuxMember (
230
+ Number, " Section number of entryPoint:" , AuxHeader->SecNumOfEntryPoint );
231
+ PrintAuxMember (Number, " Section number of .text:" , AuxHeader->SecNumOfText );
232
+ PrintAuxMember (Number, " Section number of .data:" , AuxHeader->SecNumOfData );
233
+ PrintAuxMember (Number, " Section number of TOC:" , AuxHeader->SecNumOfTOC );
234
+ PrintAuxMember (Number,
235
+ " Section number of loader data:" , AuxHeader->SecNumOfLoader );
236
+ PrintAuxMember (Number, " Section number of .bss:" , AuxHeader->SecNumOfBSS );
237
+ PrintAuxMember (Hex, " Maxium alignment of .text:" , AuxHeader->MaxAlignOfText );
238
+ PrintAuxMember (Hex, " Maxium alignment of .data:" , AuxHeader->MaxAlignOfData );
239
+ PrintAuxMember (Hex, " Module type:" , AuxHeader->ModuleType );
240
+ PrintAuxMember (Hex, " CPU type of objects:" , AuxHeader->CpuFlag );
241
+ PrintAuxMember (Hex, " Text page size:" , AuxHeader->TextPageSize );
242
+ PrintAuxMember (Hex, " Data page size:" , AuxHeader->DataPageSize );
243
+ PrintAuxMember (Hex, " Stack page size:" , AuxHeader->StackPageSize );
244
+ if (offsetof (XCOFFAuxiliaryHeader64, FlagAndTDataAlignment) +
245
+ sizeof (XCOFFAuxiliaryHeader64::FlagAndTDataAlignment) <=
246
+ AuxSize) {
247
+ printHex (" Flag:" , AuxHeader->getFlag ());
248
+ printHex (" Alignment of thread-local storage:" ,
249
+ AuxHeader->getTDataAlignment ());
250
+ }
251
+ PrintAuxMember (Hex, " Size of .text section:" , AuxHeader->TextSize );
252
+ PrintAuxMember (Hex, " Size of .data section:" , AuxHeader->InitDataSize );
253
+ PrintAuxMember (Hex, " Size of .bss section:" , AuxHeader->BssDataSize );
254
+ PrintAuxMember (Hex, " Entry point address:" , AuxHeader->EntryPointAddr );
255
+ PrintAuxMember (Hex, " Maximum stack size:" , AuxHeader->MaxStackSize );
256
+ PrintAuxMember (Hex, " Maximum data size:" , AuxHeader->MaxDataSize );
257
+ PrintAuxMember (Number,
258
+ " Section number for .tdata:" , AuxHeader->SecNumOfTData );
259
+ PrintAuxMember (Number, " Section number for .tbss:" , AuxHeader->SecNumOfTBSS );
260
+ PrintAuxMember (Hex, " Additional flags 64-bit XCOFF:" , AuxHeader->XCOFF64Flag );
261
+
262
+ checkAndPrintAuxHeaderParseError (PartialFieldName, PartialFieldOffset,
263
+ AuxSize, *AuxHeader);
264
+ }
265
+
70
266
void XCOFFDumper::printFileHeader () {
71
- setWidth ( 20 ) ;
267
+ Width = 20 ;
72
268
outs () << " \n ---File Header:\n " ;
73
269
printHex (" Magic:" , Obj.getMagic ());
74
270
printNumber (" NumberOfSections:" , Obj.getNumberOfSections ());
0 commit comments