[InstCombine] Signed saturation patterns
[llvm-complete.git] / tools / llvm-readobj / XCOFFDumper.cpp
blobfe95b6d1b494d74e6a477fc81b274e6b20610a9a
1 //===-- XCOFFDumper.cpp - XCOFF dumping utility -----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements an XCOFF specific dumper for llvm-readobj.
11 //===----------------------------------------------------------------------===//
13 #include "Error.h"
14 #include "ObjDumper.h"
15 #include "llvm-readobj.h"
16 #include "llvm/Object/XCOFFObjectFile.h"
17 #include "llvm/Support/ScopedPrinter.h"
19 using namespace llvm;
20 using namespace object;
22 namespace {
24 class XCOFFDumper : public ObjDumper {
25 enum {
26 SymbolTypeMask = 0x07,
27 SymbolAlignmentMask = 0xF8,
28 SymbolAlignmentBitOffset = 3
31 public:
32 XCOFFDumper(const XCOFFObjectFile &Obj, ScopedPrinter &Writer)
33 : ObjDumper(Writer), Obj(Obj) {}
35 void printFileHeaders() override;
36 void printSectionHeaders() override;
37 void printRelocations() override;
38 void printSymbols() override;
39 void printDynamicSymbols() override;
40 void printUnwindInfo() override;
41 void printStackMap() const override;
42 void printNeededLibraries() override;
44 private:
45 template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
46 template <typename T> void printGenericSectionHeader(T &Sec) const;
47 template <typename T> void printOverflowSectionHeader(T &Sec) const;
48 void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
49 void printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr);
50 void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
51 void printSymbol(const SymbolRef &);
53 // Least significant 3 bits are reserved.
54 static constexpr unsigned SectionFlagsReservedMask = 0x7;
56 // The low order 16 bits of section flags denotes the section type.
57 static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
59 void printRelocations(ArrayRef<XCOFFSectionHeader32> Sections);
60 const XCOFFObjectFile &Obj;
62 } // anonymous namespace
64 void XCOFFDumper::printFileHeaders() {
65 DictScope DS(W, "FileHeader");
66 W.printHex("Magic", Obj.getMagic());
67 W.printNumber("NumberOfSections", Obj.getNumberOfSections());
69 // Negative timestamp values are reserved for future use.
70 int32_t TimeStamp = Obj.getTimeStamp();
71 if (TimeStamp > 0) {
72 // This handling of the time stamp assumes that the host system's time_t is
73 // compatible with AIX time_t. If a platform is not compatible, the lit
74 // tests will let us know.
75 time_t TimeDate = TimeStamp;
77 char FormattedTime[21] = {};
78 size_t BytesWritten =
79 strftime(FormattedTime, 21, "%Y-%m-%dT%H:%M:%SZ", gmtime(&TimeDate));
80 if (BytesWritten)
81 W.printHex("TimeStamp", FormattedTime, TimeStamp);
82 else
83 W.printHex("Timestamp", TimeStamp);
84 } else {
85 W.printHex("TimeStamp", TimeStamp == 0 ? "None" : "Reserved Value",
86 TimeStamp);
89 // The number of symbol table entries is an unsigned value in 64-bit objects
90 // and a signed value (with negative values being 'reserved') in 32-bit
91 // objects.
92 if (Obj.is64Bit()) {
93 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset64());
94 W.printNumber("SymbolTableEntries", Obj.getNumberOfSymbolTableEntries64());
95 } else {
96 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset32());
97 int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries32();
98 if (SymTabEntries >= 0)
99 W.printNumber("SymbolTableEntries", SymTabEntries);
100 else
101 W.printHex("SymbolTableEntries", "Reserved Value", SymTabEntries);
104 W.printHex("OptionalHeaderSize", Obj.getOptionalHeaderSize());
105 W.printHex("Flags", Obj.getFlags());
107 // TODO FIXME Add support for the auxiliary header (if any) once
108 // XCOFFObjectFile has the necessary support.
111 void XCOFFDumper::printSectionHeaders() {
112 if (Obj.is64Bit())
113 printSectionHeaders(Obj.sections64());
114 else
115 printSectionHeaders(Obj.sections32());
118 void XCOFFDumper::printRelocations() {
119 if (Obj.is64Bit())
120 llvm_unreachable("64-bit relocation output not implemented!");
121 else
122 printRelocations(Obj.sections32());
125 static const EnumEntry<XCOFF::RelocationType> RelocationTypeNameclass[] = {
126 #define ECase(X) \
127 { #X, XCOFF::X }
128 ECase(R_POS), ECase(R_RL), ECase(R_RLA), ECase(R_NEG),
129 ECase(R_REL), ECase(R_TOC), ECase(R_TRL), ECase(R_TRLA),
130 ECase(R_GL), ECase(R_TCL), ECase(R_REF), ECase(R_BA),
131 ECase(R_BR), ECase(R_RBA), ECase(R_RBR), ECase(R_TLS),
132 ECase(R_TLS_IE), ECase(R_TLS_LD), ECase(R_TLS_LE), ECase(R_TLSM),
133 ECase(R_TLSML), ECase(R_TOCU), ECase(R_TOCL)
134 #undef ECase
137 void XCOFFDumper::printRelocations(ArrayRef<XCOFFSectionHeader32> Sections) {
138 if (!opts::ExpandRelocs)
139 report_fatal_error("Unexpanded relocation output not implemented.");
141 ListScope LS(W, "Relocations");
142 uint16_t Index = 0;
143 for (const auto &Sec : Sections) {
144 ++Index;
145 // Only the .text, .data, .tdata, and STYP_DWARF sections have relocation.
146 if (Sec.Flags != XCOFF::STYP_TEXT && Sec.Flags != XCOFF::STYP_DATA &&
147 Sec.Flags != XCOFF::STYP_TDATA && Sec.Flags != XCOFF::STYP_DWARF)
148 continue;
149 auto Relocations = unwrapOrError(Obj.getFileName(), Obj.relocations(Sec));
150 if (Relocations.empty())
151 continue;
153 W.startLine() << "Section (index: " << Index << ") " << Sec.getName()
154 << " {\n";
155 for (auto Reloc : Relocations) {
156 StringRef SymbolName = unwrapOrError(
157 Obj.getFileName(), Obj.getSymbolNameByIndex(Reloc.SymbolIndex));
159 DictScope RelocScope(W, "Relocation");
160 W.printHex("Virtual Address", Reloc.VirtualAddress);
161 W.printNumber("Symbol", SymbolName, Reloc.SymbolIndex);
162 W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No");
163 W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0);
164 W.printNumber("Length", Reloc.getRelocatedLength());
165 W.printEnum("Type", (uint8_t)Reloc.Type,
166 makeArrayRef(RelocationTypeNameclass));
168 W.unindent();
169 W.startLine() << "}\n";
173 static const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
174 #define ECase(X) \
175 { #X, XCOFF::X }
176 ECase(XFT_FN), ECase(XFT_CT), ECase(XFT_CV), ECase(XFT_CD)
177 #undef ECase
180 void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
181 if (Obj.is64Bit())
182 report_fatal_error(
183 "Printing for File Auxiliary Entry in 64-bit is unimplemented.");
184 StringRef FileName =
185 unwrapOrError(Obj.getFileName(), Obj.getCFileName(AuxEntPtr));
186 DictScope SymDs(W, "File Auxiliary Entry");
187 W.printNumber("Index",
188 Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
189 W.printString("Name", FileName);
190 W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type),
191 makeArrayRef(FileStringType));
194 static const EnumEntry<XCOFF::StorageMappingClass> CsectStorageMappingClass[] =
196 #define ECase(X) \
197 { #X, XCOFF::X }
198 ECase(XMC_PR), ECase(XMC_RO), ECase(XMC_DB),
199 ECase(XMC_GL), ECase(XMC_XO), ECase(XMC_SV),
200 ECase(XMC_SV64), ECase(XMC_SV3264), ECase(XMC_TI),
201 ECase(XMC_TB), ECase(XMC_RW), ECase(XMC_TC0),
202 ECase(XMC_TC), ECase(XMC_TD), ECase(XMC_DS),
203 ECase(XMC_UA), ECase(XMC_BS), ECase(XMC_UC),
204 ECase(XMC_TL), ECase(XMC_TE)
205 #undef ECase
208 static const EnumEntry<XCOFF::SymbolType> CsectSymbolTypeClass[] = {
209 #define ECase(X) \
210 { #X, XCOFF::X }
211 ECase(XTY_ER), ECase(XTY_SD), ECase(XTY_LD), ECase(XTY_CM)
212 #undef ECase
215 void XCOFFDumper::printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr) {
216 assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
218 DictScope SymDs(W, "CSECT Auxiliary Entry");
219 W.printNumber("Index",
220 Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
221 if ((AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask) == XCOFF::XTY_LD)
222 W.printNumber("ContainingCsectSymbolIndex", AuxEntPtr->SectionOrLength);
223 else
224 W.printNumber("SectionLen", AuxEntPtr->SectionOrLength);
225 W.printHex("ParameterHashIndex", AuxEntPtr->ParameterHashIndex);
226 W.printHex("TypeChkSectNum", AuxEntPtr->TypeChkSectNum);
227 // Print out symbol alignment and type.
228 W.printNumber("SymbolAlignmentLog2",
229 (AuxEntPtr->SymbolAlignmentAndType & SymbolAlignmentMask) >>
230 SymbolAlignmentBitOffset);
231 W.printEnum("SymbolType", AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask,
232 makeArrayRef(CsectSymbolTypeClass));
233 W.printEnum("StorageMappingClass",
234 static_cast<uint8_t>(AuxEntPtr->StorageMappingClass),
235 makeArrayRef(CsectStorageMappingClass));
236 W.printHex("StabInfoIndex", AuxEntPtr->StabInfoIndex);
237 W.printHex("StabSectNum", AuxEntPtr->StabSectNum);
240 void XCOFFDumper::printSectAuxEntForStat(
241 const XCOFFSectAuxEntForStat *AuxEntPtr) {
242 assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
244 DictScope SymDs(W, "Sect Auxiliary Entry For Stat");
245 W.printNumber("Index",
246 Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
247 W.printNumber("SectionLength", AuxEntPtr->SectionLength);
249 // Unlike the corresponding fields in the section header, NumberOfRelocEnt
250 // and NumberOfLineNum do not handle values greater than 65535.
251 W.printNumber("NumberOfRelocEnt", AuxEntPtr->NumberOfRelocEnt);
252 W.printNumber("NumberOfLineNum", AuxEntPtr->NumberOfLineNum);
255 static const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = {
256 #define ECase(X) \
257 { #X, XCOFF::X }
258 ECase(C_NULL), ECase(C_AUTO), ECase(C_EXT), ECase(C_STAT),
259 ECase(C_REG), ECase(C_EXTDEF), ECase(C_LABEL), ECase(C_ULABEL),
260 ECase(C_MOS), ECase(C_ARG), ECase(C_STRTAG), ECase(C_MOU),
261 ECase(C_UNTAG), ECase(C_TPDEF), ECase(C_USTATIC), ECase(C_ENTAG),
262 ECase(C_MOE), ECase(C_REGPARM), ECase(C_FIELD), ECase(C_BLOCK),
263 ECase(C_FCN), ECase(C_EOS), ECase(C_FILE), ECase(C_LINE),
264 ECase(C_ALIAS), ECase(C_HIDDEN), ECase(C_HIDEXT), ECase(C_BINCL),
265 ECase(C_EINCL), ECase(C_INFO), ECase(C_WEAKEXT), ECase(C_DWARF),
266 ECase(C_GSYM), ECase(C_LSYM), ECase(C_PSYM), ECase(C_RSYM),
267 ECase(C_RPSYM), ECase(C_STSYM), ECase(C_TCSYM), ECase(C_BCOMM),
268 ECase(C_ECOML), ECase(C_ECOMM), ECase(C_DECL), ECase(C_ENTRY),
269 ECase(C_FUN), ECase(C_BSTAT), ECase(C_ESTAT), ECase(C_GTLS),
270 ECase(C_STTLS), ECase(C_EFCN)
271 #undef ECase
274 static StringRef GetSymbolValueName(XCOFF::StorageClass SC) {
275 switch (SC) {
276 case XCOFF::C_EXT:
277 case XCOFF::C_WEAKEXT:
278 case XCOFF::C_HIDEXT:
279 case XCOFF::C_STAT:
280 return "Value (RelocatableAddress)";
281 case XCOFF::C_FILE:
282 return "Value (SymbolTableIndex)";
283 case XCOFF::C_FCN:
284 case XCOFF::C_BLOCK:
285 case XCOFF::C_FUN:
286 case XCOFF::C_STSYM:
287 case XCOFF::C_BINCL:
288 case XCOFF::C_EINCL:
289 case XCOFF::C_INFO:
290 case XCOFF::C_BSTAT:
291 case XCOFF::C_LSYM:
292 case XCOFF::C_PSYM:
293 case XCOFF::C_RPSYM:
294 case XCOFF::C_RSYM:
295 case XCOFF::C_ECOML:
296 case XCOFF::C_DWARF:
297 assert(false && "This StorageClass for the symbol is not yet implemented.");
298 return "";
299 default:
300 return "Value";
304 static const EnumEntry<XCOFF::CFileLangId> CFileLangIdClass[] = {
305 #define ECase(X) \
306 { #X, XCOFF::X }
307 ECase(TB_C), ECase(TB_CPLUSPLUS)
308 #undef ECase
311 static const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
312 #define ECase(X) \
313 { #X, XCOFF::X }
314 ECase(TCPU_PPC64), ECase(TCPU_COM), ECase(TCPU_970)
315 #undef ECase
318 void XCOFFDumper::printSymbol(const SymbolRef &S) {
319 if (Obj.is64Bit())
320 report_fatal_error("64-bit support is unimplemented.");
322 DataRefImpl SymbolDRI = S.getRawDataRefImpl();
323 const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
325 XCOFFSymbolRef XCOFFSymRef(SymbolDRI, &Obj);
326 uint8_t NumberOfAuxEntries = XCOFFSymRef.getNumberOfAuxEntries();
328 DictScope SymDs(W, "Symbol");
330 StringRef SymbolName =
331 unwrapOrError(Obj.getFileName(), Obj.getSymbolName(SymbolDRI));
333 W.printNumber("Index",
334 Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(SymbolEntPtr)));
335 W.printString("Name", SymbolName);
336 W.printHex(GetSymbolValueName(SymbolEntPtr->StorageClass),
337 SymbolEntPtr->Value);
339 StringRef SectionName =
340 unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntPtr));
342 W.printString("Section", SectionName);
343 if (XCOFFSymRef.getStorageClass() == XCOFF::C_FILE) {
344 W.printEnum("Source Language ID",
345 SymbolEntPtr->CFileLanguageIdAndTypeId.LanguageId,
346 makeArrayRef(CFileLangIdClass));
347 W.printEnum("CPU Version ID",
348 SymbolEntPtr->CFileLanguageIdAndTypeId.CpuTypeId,
349 makeArrayRef(CFileCpuIdClass));
350 } else
351 W.printHex("Type", SymbolEntPtr->SymbolType);
353 W.printEnum("StorageClass", static_cast<uint8_t>(SymbolEntPtr->StorageClass),
354 makeArrayRef(SymStorageClass));
355 W.printNumber("NumberOfAuxEntries", SymbolEntPtr->NumberOfAuxEntries);
357 if (NumberOfAuxEntries == 0)
358 return;
360 switch (XCOFFSymRef.getStorageClass()) {
361 case XCOFF::C_FILE:
362 // If the symbol is C_FILE and has auxiliary entries...
363 for (int i = 1; i <= NumberOfAuxEntries; i++) {
364 const XCOFFFileAuxEnt *FileAuxEntPtr =
365 reinterpret_cast<const XCOFFFileAuxEnt *>(SymbolEntPtr + i);
366 #ifndef NDEBUG
367 Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
368 #endif
369 printFileAuxEnt(FileAuxEntPtr);
371 break;
372 case XCOFF::C_EXT:
373 case XCOFF::C_WEAKEXT:
374 case XCOFF::C_HIDEXT:
375 // If the symbol is for a function, and it has more than 1 auxiliary entry,
376 // then one of them must be function auxiliary entry which we do not
377 // support yet.
378 if (XCOFFSymRef.isFunction() && NumberOfAuxEntries >= 2)
379 report_fatal_error("Function auxiliary entry printing is unimplemented.");
381 // If there is more than 1 auxiliary entry, instead of printing out
382 // error information, print out the raw Auxiliary entry from 1st till
383 // the last - 1. The last one must be a CSECT Auxiliary Entry.
384 for (int i = 1; i < NumberOfAuxEntries; i++) {
385 W.startLine() << "!Unexpected raw auxiliary entry data:\n";
386 W.startLine() << format_bytes(
387 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
388 XCOFF::SymbolTableEntrySize));
391 // The symbol's last auxiliary entry is a CSECT Auxiliary Entry.
392 printCsectAuxEnt32(XCOFFSymRef.getXCOFFCsectAuxEnt32());
393 break;
394 case XCOFF::C_STAT:
395 if (NumberOfAuxEntries > 1)
396 report_fatal_error(
397 "C_STAT symbol should not have more than 1 auxiliary entry.");
399 const XCOFFSectAuxEntForStat *StatAuxEntPtr;
400 StatAuxEntPtr =
401 reinterpret_cast<const XCOFFSectAuxEntForStat *>(SymbolEntPtr + 1);
402 #ifndef NDEBUG
403 Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
404 #endif
405 printSectAuxEntForStat(StatAuxEntPtr);
406 break;
407 case XCOFF::C_DWARF:
408 case XCOFF::C_BLOCK:
409 case XCOFF::C_FCN:
410 report_fatal_error("Symbol table entry printing for this storage class "
411 "type is unimplemented.");
412 break;
413 default:
414 for (int i = 1; i <= NumberOfAuxEntries; i++) {
415 W.startLine() << "!Unexpected raw auxiliary entry data:\n";
416 W.startLine() << format_bytes(
417 ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
418 XCOFF::SymbolTableEntrySize));
420 break;
424 void XCOFFDumper::printSymbols() {
425 ListScope Group(W, "Symbols");
426 for (const SymbolRef &S : Obj.symbols())
427 printSymbol(S);
430 void XCOFFDumper::printDynamicSymbols() {
431 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
434 void XCOFFDumper::printUnwindInfo() {
435 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
438 void XCOFFDumper::printStackMap() const {
439 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
442 void XCOFFDumper::printNeededLibraries() {
443 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
446 static const EnumEntry<XCOFF::SectionTypeFlags> SectionTypeFlagsNames[] = {
447 #define ECase(X) \
448 { #X, XCOFF::X }
449 ECase(STYP_PAD), ECase(STYP_DWARF), ECase(STYP_TEXT),
450 ECase(STYP_DATA), ECase(STYP_BSS), ECase(STYP_EXCEPT),
451 ECase(STYP_INFO), ECase(STYP_TDATA), ECase(STYP_TBSS),
452 ECase(STYP_LOADER), ECase(STYP_DEBUG), ECase(STYP_TYPCHK),
453 ECase(STYP_OVRFLO)
454 #undef ECase
457 template <typename T>
458 void XCOFFDumper::printOverflowSectionHeader(T &Sec) const {
459 if (Obj.is64Bit()) {
460 reportWarning(make_error<StringError>("An 64-bit XCOFF object file may not "
461 "contain an overflow section header.",
462 object_error::parse_failed),
463 Obj.getFileName());
466 W.printString("Name", Sec.getName());
467 W.printNumber("NumberOfRelocations", Sec.PhysicalAddress);
468 W.printNumber("NumberOfLineNumbers", Sec.VirtualAddress);
469 W.printHex("Size", Sec.SectionSize);
470 W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
471 W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
472 W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
473 W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfRelocations);
474 W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfLineNumbers);
477 template <typename T>
478 void XCOFFDumper::printGenericSectionHeader(T &Sec) const {
479 W.printString("Name", Sec.getName());
480 W.printHex("PhysicalAddress", Sec.PhysicalAddress);
481 W.printHex("VirtualAddress", Sec.VirtualAddress);
482 W.printHex("Size", Sec.SectionSize);
483 W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
484 W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
485 W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
486 W.printNumber("NumberOfRelocations", Sec.NumberOfRelocations);
487 W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
490 template <typename T>
491 void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
492 ListScope Group(W, "Sections");
494 uint16_t Index = 1;
495 for (const T &Sec : Sections) {
496 DictScope SecDS(W, "Section");
498 W.printNumber("Index", Index++);
500 uint16_t SectionType = Sec.Flags & SectionFlagsTypeMask;
501 switch (SectionType) {
502 case XCOFF::STYP_OVRFLO:
503 printOverflowSectionHeader(Sec);
504 break;
505 case XCOFF::STYP_LOADER:
506 case XCOFF::STYP_EXCEPT:
507 case XCOFF::STYP_TYPCHK:
508 // TODO The interpretation of loader, exception and type check section
509 // headers are different from that of generic section headers. We will
510 // implement them later. We interpret them as generic section headers for
511 // now.
512 default:
513 printGenericSectionHeader(Sec);
514 break;
516 // For now we just dump the section type portion of the flags.
517 if (SectionType & SectionFlagsReservedMask)
518 W.printHex("Flags", "Reserved", SectionType);
519 else
520 W.printEnum("Type", SectionType, makeArrayRef(SectionTypeFlagsNames));
523 if (opts::SectionRelocations)
524 report_fatal_error("Dumping section relocations is unimplemented");
526 if (opts::SectionSymbols)
527 report_fatal_error("Dumping symbols is unimplemented");
529 if (opts::SectionData)
530 report_fatal_error("Dumping section data is unimplemented");
533 namespace llvm {
534 std::error_code createXCOFFDumper(const object::ObjectFile *Obj,
535 ScopedPrinter &Writer,
536 std::unique_ptr<ObjDumper> &Result) {
537 const XCOFFObjectFile *XObj = dyn_cast<XCOFFObjectFile>(Obj);
538 if (!XObj)
539 return readobj_error::unsupported_obj_file_format;
541 Result.reset(new XCOFFDumper(*XObj, Writer));
542 return readobj_error::success;
544 } // namespace llvm