@@ -32,6 +32,7 @@ using namespace llvm::support;
3232
3333namespace {
3434class XCOFFDumper : public objdump ::Dumper {
35+ enum PrintStyle { Hex, Number };
3536 const XCOFFObjectFile &Obj;
3637 unsigned Width;
3738
@@ -41,14 +42,32 @@ class XCOFFDumper : public objdump::Dumper {
4142private:
4243 void printPrivateHeaders () override ;
4344 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);
4561 void printHex (StringRef Name, uint64_t Value);
4662 void printNumber (StringRef Name, uint64_t Value);
63+ FormattedString formatName (StringRef Name);
4764 void printStrHex (StringRef Name, StringRef Str, uint64_t Value);
48- void setWidth (unsigned W) { Width = W; };
4965};
5066
51- void XCOFFDumper::printPrivateHeaders () { printFileHeader (); }
67+ void XCOFFDumper::printPrivateHeaders () {
68+ printFileHeader ();
69+ printAuxiliaryHeader ();
70+ }
5271
5372FormattedString XCOFFDumper::formatName (StringRef Name) {
5473 return FormattedString (Name, Width, FormattedString::JustifyLeft);
@@ -67,8 +86,185 @@ void XCOFFDumper::printStrHex(StringRef Name, StringRef Str, uint64_t Value) {
6786 << " )\n " ;
6887}
6988
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+
70266void XCOFFDumper::printFileHeader () {
71- setWidth ( 20 ) ;
267+ Width = 20 ;
72268 outs () << " \n ---File Header:\n " ;
73269 printHex (" Magic:" , Obj.getMagic ());
74270 printNumber (" NumberOfSections:" , Obj.getNumberOfSections ());
0 commit comments