File: | tools/llvm-readobj/COFFDumper.cpp |
Location: | line 1598, column 34 |
Description: | Function call argument is an uninitialized value |
1 | //===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | /// | |||
10 | /// \file | |||
11 | /// \brief This file implements the COFF-specific dumper for llvm-readobj. | |||
12 | /// | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "ARMWinEHPrinter.h" | |||
16 | #include "CodeView.h" | |||
17 | #include "Error.h" | |||
18 | #include "ObjDumper.h" | |||
19 | #include "StackMapPrinter.h" | |||
20 | #include "Win64EHDumper.h" | |||
21 | #include "llvm-readobj.h" | |||
22 | #include "llvm/ADT/DenseMap.h" | |||
23 | #include "llvm/ADT/SmallString.h" | |||
24 | #include "llvm/ADT/StringExtras.h" | |||
25 | #include "llvm/DebugInfo/CodeView/CodeView.h" | |||
26 | #include "llvm/DebugInfo/CodeView/Line.h" | |||
27 | #include "llvm/DebugInfo/CodeView/RecordSerialization.h" | |||
28 | #include "llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h" | |||
29 | #include "llvm/DebugInfo/CodeView/SymbolRecord.h" | |||
30 | #include "llvm/DebugInfo/CodeView/TypeDumper.h" | |||
31 | #include "llvm/DebugInfo/CodeView/TypeIndex.h" | |||
32 | #include "llvm/DebugInfo/CodeView/TypeRecord.h" | |||
33 | #include "llvm/DebugInfo/CodeView/TypeStream.h" | |||
34 | #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" | |||
35 | #include "llvm/Object/COFF.h" | |||
36 | #include "llvm/Object/ObjectFile.h" | |||
37 | #include "llvm/Support/COFF.h" | |||
38 | #include "llvm/Support/Casting.h" | |||
39 | #include "llvm/Support/Compiler.h" | |||
40 | #include "llvm/Support/DataExtractor.h" | |||
41 | #include "llvm/Support/Format.h" | |||
42 | #include "llvm/Support/ScopedPrinter.h" | |||
43 | #include "llvm/Support/SourceMgr.h" | |||
44 | #include "llvm/Support/Win64EH.h" | |||
45 | #include "llvm/Support/raw_ostream.h" | |||
46 | #include <algorithm> | |||
47 | #include <cstring> | |||
48 | #include <system_error> | |||
49 | #include <time.h> | |||
50 | ||||
51 | using namespace llvm; | |||
52 | using namespace llvm::object; | |||
53 | using namespace llvm::codeview; | |||
54 | using namespace llvm::support; | |||
55 | using namespace llvm::Win64EH; | |||
56 | ||||
57 | namespace { | |||
58 | ||||
59 | class COFFDumper : public ObjDumper { | |||
60 | public: | |||
61 | COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer) | |||
62 | : ObjDumper(Writer), Obj(Obj), | |||
63 | CVTD(Writer, opts::CodeViewSubsectionBytes) {} | |||
64 | ||||
65 | void printFileHeaders() override; | |||
66 | void printSections() override; | |||
67 | void printRelocations() override; | |||
68 | void printSymbols() override; | |||
69 | void printDynamicSymbols() override; | |||
70 | void printUnwindInfo() override; | |||
71 | void printCOFFImports() override; | |||
72 | void printCOFFExports() override; | |||
73 | void printCOFFDirectives() override; | |||
74 | void printCOFFBaseReloc() override; | |||
75 | void printCodeViewDebugInfo() override; | |||
76 | void | |||
77 | mergeCodeViewTypes(llvm::codeview::MemoryTypeTableBuilder &CVTypes) override; | |||
78 | void printStackMap() const override; | |||
79 | private: | |||
80 | void printSymbol(const SymbolRef &Sym); | |||
81 | void printRelocation(const SectionRef &Section, const RelocationRef &Reloc, | |||
82 | uint64_t Bias = 0); | |||
83 | void printDataDirectory(uint32_t Index, const std::string &FieldName); | |||
84 | ||||
85 | void printDOSHeader(const dos_header *DH); | |||
86 | template <class PEHeader> void printPEHeader(const PEHeader *Hdr); | |||
87 | void printBaseOfDataField(const pe32_header *Hdr); | |||
88 | void printBaseOfDataField(const pe32plus_header *Hdr); | |||
89 | ||||
90 | void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section); | |||
91 | void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section); | |||
92 | StringRef getTypeName(TypeIndex Ty); | |||
93 | StringRef getFileNameForFileOffset(uint32_t FileOffset); | |||
94 | void printFileNameForOffset(StringRef Label, uint32_t FileOffset); | |||
95 | void printTypeIndex(StringRef FieldName, TypeIndex TI) { | |||
96 | // Forward to CVTypeDumper for simplicity. | |||
97 | CVTD.printTypeIndex(FieldName, TI); | |||
98 | } | |||
99 | void printLocalVariableAddrRange(const LocalVariableAddrRange &Range, | |||
100 | const coff_section *Sec, | |||
101 | StringRef SectionContents); | |||
102 | void printLocalVariableAddrGap(StringRef &SymData); | |||
103 | ||||
104 | void printCodeViewSymbolsSubsection(StringRef Subsection, | |||
105 | const SectionRef &Section, | |||
106 | StringRef SectionContents); | |||
107 | ||||
108 | void printCodeViewFileChecksums(StringRef Subsection); | |||
109 | ||||
110 | void printCodeViewInlineeLines(StringRef Subsection); | |||
111 | ||||
112 | void printRelocatedField(StringRef Label, const coff_section *Sec, | |||
113 | StringRef SectionContents, const ulittle32_t *Field, | |||
114 | StringRef *RelocSym = nullptr); | |||
115 | ||||
116 | void printBinaryBlockWithRelocs(StringRef Label, const SectionRef &Sec, | |||
117 | StringRef SectionContents, StringRef Block); | |||
118 | ||||
119 | /// Given a .debug$S section, find the string table and file checksum table. | |||
120 | void initializeFileAndStringTables(StringRef Data); | |||
121 | ||||
122 | void cacheRelocations(); | |||
123 | ||||
124 | std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset, | |||
125 | SymbolRef &Sym); | |||
126 | std::error_code resolveSymbolName(const coff_section *Section, | |||
127 | uint64_t Offset, StringRef &Name); | |||
128 | std::error_code resolveSymbolName(const coff_section *Section, | |||
129 | StringRef SectionContents, | |||
130 | const void *RelocPtr, StringRef &Name); | |||
131 | void printImportedSymbols(iterator_range<imported_symbol_iterator> Range); | |||
132 | void printDelayImportedSymbols( | |||
133 | const DelayImportDirectoryEntryRef &I, | |||
134 | iterator_range<imported_symbol_iterator> Range); | |||
135 | ||||
136 | typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy; | |||
137 | ||||
138 | const llvm::object::COFFObjectFile *Obj; | |||
139 | bool RelocCached = false; | |||
140 | RelocMapTy RelocMap; | |||
141 | StringRef CVFileChecksumTable; | |||
142 | StringRef CVStringTable; | |||
143 | ||||
144 | CVTypeDumper CVTD; | |||
145 | }; | |||
146 | ||||
147 | } // end namespace | |||
148 | ||||
149 | namespace llvm { | |||
150 | ||||
151 | std::error_code createCOFFDumper(const object::ObjectFile *Obj, | |||
152 | ScopedPrinter &Writer, | |||
153 | std::unique_ptr<ObjDumper> &Result) { | |||
154 | const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(Obj); | |||
155 | if (!COFFObj) | |||
156 | return readobj_error::unsupported_obj_file_format; | |||
157 | ||||
158 | Result.reset(new COFFDumper(COFFObj, Writer)); | |||
159 | return readobj_error::success; | |||
160 | } | |||
161 | ||||
162 | } // namespace llvm | |||
163 | ||||
164 | // Given a a section and an offset into this section the function returns the | |||
165 | // symbol used for the relocation at the offset. | |||
166 | std::error_code COFFDumper::resolveSymbol(const coff_section *Section, | |||
167 | uint64_t Offset, SymbolRef &Sym) { | |||
168 | cacheRelocations(); | |||
169 | const auto &Relocations = RelocMap[Section]; | |||
170 | for (const auto &Relocation : Relocations) { | |||
171 | uint64_t RelocationOffset = Relocation.getOffset(); | |||
172 | ||||
173 | if (RelocationOffset == Offset) { | |||
174 | Sym = *Relocation.getSymbol(); | |||
175 | return readobj_error::success; | |||
176 | } | |||
177 | } | |||
178 | return readobj_error::unknown_symbol; | |||
179 | } | |||
180 | ||||
181 | // Given a section and an offset into this section the function returns the name | |||
182 | // of the symbol used for the relocation at the offset. | |||
183 | std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, | |||
184 | uint64_t Offset, | |||
185 | StringRef &Name) { | |||
186 | SymbolRef Symbol; | |||
187 | if (std::error_code EC = resolveSymbol(Section, Offset, Symbol)) | |||
188 | return EC; | |||
189 | Expected<StringRef> NameOrErr = Symbol.getName(); | |||
190 | if (!NameOrErr) | |||
191 | return errorToErrorCode(NameOrErr.takeError()); | |||
192 | Name = *NameOrErr; | |||
193 | return std::error_code(); | |||
194 | } | |||
195 | ||||
196 | // Helper for when you have a pointer to real data and you want to know about | |||
197 | // relocations against it. | |||
198 | std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, | |||
199 | StringRef SectionContents, | |||
200 | const void *RelocPtr, | |||
201 | StringRef &Name) { | |||
202 | assert(SectionContents.data() < RelocPtr &&((SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && "pointer to relocated object is not in section" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && \"pointer to relocated object is not in section\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 204, __PRETTY_FUNCTION__)) | |||
203 | RelocPtr < SectionContents.data() + SectionContents.size() &&((SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && "pointer to relocated object is not in section" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && \"pointer to relocated object is not in section\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 204, __PRETTY_FUNCTION__)) | |||
204 | "pointer to relocated object is not in section")((SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && "pointer to relocated object is not in section" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.data() < RelocPtr && RelocPtr < SectionContents.data() + SectionContents.size() && \"pointer to relocated object is not in section\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 204, __PRETTY_FUNCTION__)); | |||
205 | uint64_t Offset = ptrdiff_t(reinterpret_cast<const char *>(RelocPtr) - | |||
206 | SectionContents.data()); | |||
207 | return resolveSymbolName(Section, Offset, Name); | |||
208 | } | |||
209 | ||||
210 | void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec, | |||
211 | StringRef SectionContents, | |||
212 | const ulittle32_t *Field, | |||
213 | StringRef *RelocSym) { | |||
214 | StringRef SymStorage; | |||
215 | StringRef &Symbol = RelocSym ? *RelocSym : SymStorage; | |||
216 | if (!resolveSymbolName(Sec, SectionContents, Field, Symbol)) | |||
217 | W.printSymbolOffset(Label, Symbol, *Field); | |||
218 | else | |||
219 | W.printHex(Label, *Field); | |||
220 | } | |||
221 | ||||
222 | void COFFDumper::printBinaryBlockWithRelocs(StringRef Label, | |||
223 | const SectionRef &Sec, | |||
224 | StringRef SectionContents, | |||
225 | StringRef Block) { | |||
226 | W.printBinaryBlock(Label, Block); | |||
227 | ||||
228 | assert(SectionContents.begin() < Block.begin() &&((SectionContents.begin() < Block.begin() && SectionContents .end() >= Block.end() && "Block is not contained in SectionContents" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.begin() < Block.begin() && SectionContents.end() >= Block.end() && \"Block is not contained in SectionContents\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 230, __PRETTY_FUNCTION__)) | |||
229 | SectionContents.end() >= Block.end() &&((SectionContents.begin() < Block.begin() && SectionContents .end() >= Block.end() && "Block is not contained in SectionContents" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.begin() < Block.begin() && SectionContents.end() >= Block.end() && \"Block is not contained in SectionContents\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 230, __PRETTY_FUNCTION__)) | |||
230 | "Block is not contained in SectionContents")((SectionContents.begin() < Block.begin() && SectionContents .end() >= Block.end() && "Block is not contained in SectionContents" ) ? static_cast<void> (0) : __assert_fail ("SectionContents.begin() < Block.begin() && SectionContents.end() >= Block.end() && \"Block is not contained in SectionContents\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.9~svn270412/tools/llvm-readobj/COFFDumper.cpp" , 230, __PRETTY_FUNCTION__)); | |||
231 | uint64_t OffsetStart = Block.data() - SectionContents.data(); | |||
232 | uint64_t OffsetEnd = OffsetStart + Block.size(); | |||
233 | ||||
234 | cacheRelocations(); | |||
235 | ListScope D(W, "BlockRelocations"); | |||
236 | const coff_section *Section = Obj->getCOFFSection(Sec); | |||
237 | const auto &Relocations = RelocMap[Section]; | |||
238 | for (const auto &Relocation : Relocations) { | |||
239 | uint64_t RelocationOffset = Relocation.getOffset(); | |||
240 | if (OffsetStart <= RelocationOffset && RelocationOffset < OffsetEnd) | |||
241 | printRelocation(Sec, Relocation, OffsetStart); | |||
242 | } | |||
243 | } | |||
244 | ||||
245 | static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = { | |||
246 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ){ "IMAGE_FILE_MACHINE_UNKNOWN", COFF::IMAGE_FILE_MACHINE_UNKNOWN }, | |||
247 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ){ "IMAGE_FILE_MACHINE_AM33", COFF::IMAGE_FILE_MACHINE_AM33 }, | |||
248 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ){ "IMAGE_FILE_MACHINE_AMD64", COFF::IMAGE_FILE_MACHINE_AMD64 }, | |||
249 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ){ "IMAGE_FILE_MACHINE_ARM", COFF::IMAGE_FILE_MACHINE_ARM }, | |||
250 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ){ "IMAGE_FILE_MACHINE_ARMNT", COFF::IMAGE_FILE_MACHINE_ARMNT }, | |||
251 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ){ "IMAGE_FILE_MACHINE_EBC", COFF::IMAGE_FILE_MACHINE_EBC }, | |||
252 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ){ "IMAGE_FILE_MACHINE_I386", COFF::IMAGE_FILE_MACHINE_I386 }, | |||
253 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ){ "IMAGE_FILE_MACHINE_IA64", COFF::IMAGE_FILE_MACHINE_IA64 }, | |||
254 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R ){ "IMAGE_FILE_MACHINE_M32R", COFF::IMAGE_FILE_MACHINE_M32R }, | |||
255 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16 ){ "IMAGE_FILE_MACHINE_MIPS16", COFF::IMAGE_FILE_MACHINE_MIPS16 }, | |||
256 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU ){ "IMAGE_FILE_MACHINE_MIPSFPU", COFF::IMAGE_FILE_MACHINE_MIPSFPU }, | |||
257 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16){ "IMAGE_FILE_MACHINE_MIPSFPU16", COFF::IMAGE_FILE_MACHINE_MIPSFPU16 }, | |||
258 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC ){ "IMAGE_FILE_MACHINE_POWERPC", COFF::IMAGE_FILE_MACHINE_POWERPC }, | |||
259 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP){ "IMAGE_FILE_MACHINE_POWERPCFP", COFF::IMAGE_FILE_MACHINE_POWERPCFP }, | |||
260 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000 ){ "IMAGE_FILE_MACHINE_R4000", COFF::IMAGE_FILE_MACHINE_R4000 }, | |||
261 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3 ){ "IMAGE_FILE_MACHINE_SH3", COFF::IMAGE_FILE_MACHINE_SH3 }, | |||
262 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP ){ "IMAGE_FILE_MACHINE_SH3DSP", COFF::IMAGE_FILE_MACHINE_SH3DSP }, | |||
263 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4 ){ "IMAGE_FILE_MACHINE_SH4", COFF::IMAGE_FILE_MACHINE_SH4 }, | |||
264 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5 ){ "IMAGE_FILE_MACHINE_SH5", COFF::IMAGE_FILE_MACHINE_SH5 }, | |||
265 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB ){ "IMAGE_FILE_MACHINE_THUMB", COFF::IMAGE_FILE_MACHINE_THUMB }, | |||
266 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2){ "IMAGE_FILE_MACHINE_WCEMIPSV2", COFF::IMAGE_FILE_MACHINE_WCEMIPSV2 } | |||
267 | }; | |||
268 | ||||
269 | static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = { | |||
270 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED ){ "IMAGE_FILE_RELOCS_STRIPPED", COFF::IMAGE_FILE_RELOCS_STRIPPED }, | |||
271 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE ){ "IMAGE_FILE_EXECUTABLE_IMAGE", COFF::IMAGE_FILE_EXECUTABLE_IMAGE }, | |||
272 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED ){ "IMAGE_FILE_LINE_NUMS_STRIPPED", COFF::IMAGE_FILE_LINE_NUMS_STRIPPED }, | |||
273 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED ){ "IMAGE_FILE_LOCAL_SYMS_STRIPPED", COFF::IMAGE_FILE_LOCAL_SYMS_STRIPPED }, | |||
274 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM ){ "IMAGE_FILE_AGGRESSIVE_WS_TRIM", COFF::IMAGE_FILE_AGGRESSIVE_WS_TRIM }, | |||
275 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE ){ "IMAGE_FILE_LARGE_ADDRESS_AWARE", COFF::IMAGE_FILE_LARGE_ADDRESS_AWARE }, | |||
276 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO ){ "IMAGE_FILE_BYTES_REVERSED_LO", COFF::IMAGE_FILE_BYTES_REVERSED_LO }, | |||
277 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE ){ "IMAGE_FILE_32BIT_MACHINE", COFF::IMAGE_FILE_32BIT_MACHINE }, | |||
278 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED ){ "IMAGE_FILE_DEBUG_STRIPPED", COFF::IMAGE_FILE_DEBUG_STRIPPED }, | |||
279 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP){ "IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP", COFF::IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP }, | |||
280 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP ){ "IMAGE_FILE_NET_RUN_FROM_SWAP", COFF::IMAGE_FILE_NET_RUN_FROM_SWAP }, | |||
281 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM ){ "IMAGE_FILE_SYSTEM", COFF::IMAGE_FILE_SYSTEM }, | |||
282 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL ){ "IMAGE_FILE_DLL", COFF::IMAGE_FILE_DLL }, | |||
283 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY ){ "IMAGE_FILE_UP_SYSTEM_ONLY", COFF::IMAGE_FILE_UP_SYSTEM_ONLY }, | |||
284 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI ){ "IMAGE_FILE_BYTES_REVERSED_HI", COFF::IMAGE_FILE_BYTES_REVERSED_HI } | |||
285 | }; | |||
286 | ||||
287 | static const EnumEntry<COFF::WindowsSubsystem> PEWindowsSubsystem[] = { | |||
288 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_UNKNOWN ){ "IMAGE_SUBSYSTEM_UNKNOWN", COFF::IMAGE_SUBSYSTEM_UNKNOWN }, | |||
289 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_NATIVE ){ "IMAGE_SUBSYSTEM_NATIVE", COFF::IMAGE_SUBSYSTEM_NATIVE }, | |||
290 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_GUI ){ "IMAGE_SUBSYSTEM_WINDOWS_GUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI }, | |||
291 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CUI ){ "IMAGE_SUBSYSTEM_WINDOWS_CUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI }, | |||
292 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_POSIX_CUI ){ "IMAGE_SUBSYSTEM_POSIX_CUI", COFF::IMAGE_SUBSYSTEM_POSIX_CUI }, | |||
293 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI ){ "IMAGE_SUBSYSTEM_WINDOWS_CE_GUI", COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI }, | |||
294 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_APPLICATION ){ "IMAGE_SUBSYSTEM_EFI_APPLICATION", COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION }, | |||
295 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER){ "IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER", COFF::IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER }, | |||
296 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ){ "IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER", COFF::IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER }, | |||
297 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_EFI_ROM ){ "IMAGE_SUBSYSTEM_EFI_ROM", COFF::IMAGE_SUBSYSTEM_EFI_ROM }, | |||
298 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SUBSYSTEM_XBOX ){ "IMAGE_SUBSYSTEM_XBOX", COFF::IMAGE_SUBSYSTEM_XBOX }, | |||
299 | }; | |||
300 | ||||
301 | static const EnumEntry<COFF::DLLCharacteristics> PEDLLCharacteristics[] = { | |||
302 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA ){ "IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA", COFF::IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA }, | |||
303 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE ){ "IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE", COFF::IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE }, | |||
304 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY ){ "IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY", COFF::IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY }, | |||
305 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ){ "IMAGE_DLL_CHARACTERISTICS_NX_COMPAT", COFF::IMAGE_DLL_CHARACTERISTICS_NX_COMPAT }, | |||
306 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION ){ "IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION", COFF::IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION }, | |||
307 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_SEH ){ "IMAGE_DLL_CHARACTERISTICS_NO_SEH", COFF::IMAGE_DLL_CHARACTERISTICS_NO_SEH }, | |||
308 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_NO_BIND ){ "IMAGE_DLL_CHARACTERISTICS_NO_BIND", COFF::IMAGE_DLL_CHARACTERISTICS_NO_BIND }, | |||
309 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_APPCONTAINER ){ "IMAGE_DLL_CHARACTERISTICS_APPCONTAINER", COFF::IMAGE_DLL_CHARACTERISTICS_APPCONTAINER }, | |||
310 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER ){ "IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER", COFF::IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER }, | |||
311 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_GUARD_CF ){ "IMAGE_DLL_CHARACTERISTICS_GUARD_CF", COFF::IMAGE_DLL_CHARACTERISTICS_GUARD_CF }, | |||
312 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE){ "IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE", COFF::IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE }, | |||
313 | }; | |||
314 | ||||
315 | static const EnumEntry<COFF::SectionCharacteristics> | |||
316 | ImageSectionCharacteristics[] = { | |||
317 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD ){ "IMAGE_SCN_TYPE_NOLOAD", COFF::IMAGE_SCN_TYPE_NOLOAD }, | |||
318 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ){ "IMAGE_SCN_TYPE_NO_PAD", COFF::IMAGE_SCN_TYPE_NO_PAD }, | |||
319 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE ){ "IMAGE_SCN_CNT_CODE", COFF::IMAGE_SCN_CNT_CODE }, | |||
320 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA ){ "IMAGE_SCN_CNT_INITIALIZED_DATA", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA }, | |||
321 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA){ "IMAGE_SCN_CNT_UNINITIALIZED_DATA", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA }, | |||
322 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER ){ "IMAGE_SCN_LNK_OTHER", COFF::IMAGE_SCN_LNK_OTHER }, | |||
323 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO ){ "IMAGE_SCN_LNK_INFO", COFF::IMAGE_SCN_LNK_INFO }, | |||
324 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE ){ "IMAGE_SCN_LNK_REMOVE", COFF::IMAGE_SCN_LNK_REMOVE }, | |||
325 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT ){ "IMAGE_SCN_LNK_COMDAT", COFF::IMAGE_SCN_LNK_COMDAT }, | |||
326 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL ){ "IMAGE_SCN_GPREL", COFF::IMAGE_SCN_GPREL }, | |||
327 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE ){ "IMAGE_SCN_MEM_PURGEABLE", COFF::IMAGE_SCN_MEM_PURGEABLE }, | |||
328 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT ){ "IMAGE_SCN_MEM_16BIT", COFF::IMAGE_SCN_MEM_16BIT }, | |||
329 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED ){ "IMAGE_SCN_MEM_LOCKED", COFF::IMAGE_SCN_MEM_LOCKED }, | |||
330 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD ){ "IMAGE_SCN_MEM_PRELOAD", COFF::IMAGE_SCN_MEM_PRELOAD }, | |||
331 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES ){ "IMAGE_SCN_ALIGN_1BYTES", COFF::IMAGE_SCN_ALIGN_1BYTES }, | |||
332 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES ){ "IMAGE_SCN_ALIGN_2BYTES", COFF::IMAGE_SCN_ALIGN_2BYTES }, | |||
333 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES ){ "IMAGE_SCN_ALIGN_4BYTES", COFF::IMAGE_SCN_ALIGN_4BYTES }, | |||
334 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES ){ "IMAGE_SCN_ALIGN_8BYTES", COFF::IMAGE_SCN_ALIGN_8BYTES }, | |||
335 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES ){ "IMAGE_SCN_ALIGN_16BYTES", COFF::IMAGE_SCN_ALIGN_16BYTES }, | |||
336 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES ){ "IMAGE_SCN_ALIGN_32BYTES", COFF::IMAGE_SCN_ALIGN_32BYTES }, | |||
337 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES ){ "IMAGE_SCN_ALIGN_64BYTES", COFF::IMAGE_SCN_ALIGN_64BYTES }, | |||
338 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES ){ "IMAGE_SCN_ALIGN_128BYTES", COFF::IMAGE_SCN_ALIGN_128BYTES }, | |||
339 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES ){ "IMAGE_SCN_ALIGN_256BYTES", COFF::IMAGE_SCN_ALIGN_256BYTES }, | |||
340 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES ){ "IMAGE_SCN_ALIGN_512BYTES", COFF::IMAGE_SCN_ALIGN_512BYTES }, | |||
341 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES ){ "IMAGE_SCN_ALIGN_1024BYTES", COFF::IMAGE_SCN_ALIGN_1024BYTES }, | |||
342 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES ){ "IMAGE_SCN_ALIGN_2048BYTES", COFF::IMAGE_SCN_ALIGN_2048BYTES }, | |||
343 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES ){ "IMAGE_SCN_ALIGN_4096BYTES", COFF::IMAGE_SCN_ALIGN_4096BYTES }, | |||
344 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES ){ "IMAGE_SCN_ALIGN_8192BYTES", COFF::IMAGE_SCN_ALIGN_8192BYTES }, | |||
345 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL ){ "IMAGE_SCN_LNK_NRELOC_OVFL", COFF::IMAGE_SCN_LNK_NRELOC_OVFL }, | |||
346 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE ){ "IMAGE_SCN_MEM_DISCARDABLE", COFF::IMAGE_SCN_MEM_DISCARDABLE }, | |||
347 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED ){ "IMAGE_SCN_MEM_NOT_CACHED", COFF::IMAGE_SCN_MEM_NOT_CACHED }, | |||
348 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED ){ "IMAGE_SCN_MEM_NOT_PAGED", COFF::IMAGE_SCN_MEM_NOT_PAGED }, | |||
349 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED ){ "IMAGE_SCN_MEM_SHARED", COFF::IMAGE_SCN_MEM_SHARED }, | |||
350 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE ){ "IMAGE_SCN_MEM_EXECUTE", COFF::IMAGE_SCN_MEM_EXECUTE }, | |||
351 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ ){ "IMAGE_SCN_MEM_READ", COFF::IMAGE_SCN_MEM_READ }, | |||
352 | LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE ){ "IMAGE_SCN_MEM_WRITE", COFF::IMAGE_SCN_MEM_WRITE } | |||
353 | }; | |||
354 | ||||
355 | static const EnumEntry<COFF::SymbolBaseType> ImageSymType[] = { | |||
356 | { "Null" , COFF::IMAGE_SYM_TYPE_NULL }, | |||
357 | { "Void" , COFF::IMAGE_SYM_TYPE_VOID }, | |||
358 | { "Char" , COFF::IMAGE_SYM_TYPE_CHAR }, | |||
359 | { "Short" , COFF::IMAGE_SYM_TYPE_SHORT }, | |||
360 | { "Int" , COFF::IMAGE_SYM_TYPE_INT }, | |||
361 | { "Long" , COFF::IMAGE_SYM_TYPE_LONG }, | |||
362 | { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT }, | |||
363 | { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE }, | |||
364 | { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT }, | |||
365 | { "Union" , COFF::IMAGE_SYM_TYPE_UNION }, | |||
366 | { "Enum" , COFF::IMAGE_SYM_TYPE_ENUM }, | |||
367 | { "MOE" , COFF::IMAGE_SYM_TYPE_MOE }, | |||
368 | { "Byte" , COFF::IMAGE_SYM_TYPE_BYTE }, | |||
369 | { "Word" , COFF::IMAGE_SYM_TYPE_WORD }, | |||
370 | { "UInt" , COFF::IMAGE_SYM_TYPE_UINT }, | |||
371 | { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD } | |||
372 | }; | |||
373 | ||||
374 | static const EnumEntry<COFF::SymbolComplexType> ImageSymDType[] = { | |||
375 | { "Null" , COFF::IMAGE_SYM_DTYPE_NULL }, | |||
376 | { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER }, | |||
377 | { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION }, | |||
378 | { "Array" , COFF::IMAGE_SYM_DTYPE_ARRAY } | |||
379 | }; | |||
380 | ||||
381 | static const EnumEntry<COFF::SymbolStorageClass> ImageSymClass[] = { | |||
382 | { "EndOfFunction" , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION }, | |||
383 | { "Null" , COFF::IMAGE_SYM_CLASS_NULL }, | |||
384 | { "Automatic" , COFF::IMAGE_SYM_CLASS_AUTOMATIC }, | |||
385 | { "External" , COFF::IMAGE_SYM_CLASS_EXTERNAL }, | |||
386 | { "Static" , COFF::IMAGE_SYM_CLASS_STATIC }, | |||
387 | { "Register" , COFF::IMAGE_SYM_CLASS_REGISTER }, | |||
388 | { "ExternalDef" , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF }, | |||
389 | { "Label" , COFF::IMAGE_SYM_CLASS_LABEL }, | |||
390 | { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL }, | |||
391 | { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT }, | |||
392 | { "Argument" , COFF::IMAGE_SYM_CLASS_ARGUMENT }, | |||
393 | { "StructTag" , COFF::IMAGE_SYM_CLASS_STRUCT_TAG }, | |||
394 | { "MemberOfUnion" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION }, | |||
395 | { "UnionTag" , COFF::IMAGE_SYM_CLASS_UNION_TAG }, | |||
396 | { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION }, | |||
397 | { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC }, | |||
398 | { "EnumTag" , COFF::IMAGE_SYM_CLASS_ENUM_TAG }, | |||
399 | { "MemberOfEnum" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM }, | |||
400 | { "RegisterParam" , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM }, | |||
401 | { "BitField" , COFF::IMAGE_SYM_CLASS_BIT_FIELD }, | |||
402 | { "Block" , COFF::IMAGE_SYM_CLASS_BLOCK }, | |||
403 | { "Function" , COFF::IMAGE_SYM_CLASS_FUNCTION }, | |||
404 | { "EndOfStruct" , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT }, | |||
405 | { "File" , COFF::IMAGE_SYM_CLASS_FILE }, | |||
406 | { "Section" , COFF::IMAGE_SYM_CLASS_SECTION }, | |||
407 | { "WeakExternal" , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL }, | |||
408 | { "CLRToken" , COFF::IMAGE_SYM_CLASS_CLR_TOKEN } | |||
409 | }; | |||
410 | ||||
411 | static const EnumEntry<COFF::COMDATType> ImageCOMDATSelect[] = { | |||
412 | { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES }, | |||
413 | { "Any" , COFF::IMAGE_COMDAT_SELECT_ANY }, | |||
414 | { "SameSize" , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE }, | |||
415 | { "ExactMatch" , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH }, | |||
416 | { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE }, | |||
417 | { "Largest" , COFF::IMAGE_COMDAT_SELECT_LARGEST }, | |||
418 | { "Newest" , COFF::IMAGE_COMDAT_SELECT_NEWEST } | |||
419 | }; | |||
420 | ||||
421 | static const EnumEntry<COFF::WeakExternalCharacteristics> | |||
422 | WeakExternalCharacteristics[] = { | |||
423 | { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY }, | |||
424 | { "Library" , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY }, | |||
425 | { "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS } | |||
426 | }; | |||
427 | ||||
428 | static const EnumEntry<uint32_t> CompileSym3FlagNames[] = { | |||
429 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, EC){ "EC", std::underlying_type<CompileSym3Flags>::type(CompileSym3Flags ::EC) }, | |||
430 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo){ "NoDbgInfo", std::underlying_type<CompileSym3Flags>:: type(CompileSym3Flags::NoDbgInfo) }, | |||
431 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, LTCG){ "LTCG", std::underlying_type<CompileSym3Flags>::type( CompileSym3Flags::LTCG) }, | |||
432 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign){ "NoDataAlign", std::underlying_type<CompileSym3Flags> ::type(CompileSym3Flags::NoDataAlign) }, | |||
433 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent){ "ManagedPresent", std::underlying_type<CompileSym3Flags> ::type(CompileSym3Flags::ManagedPresent) }, | |||
434 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks){ "SecurityChecks", std::underlying_type<CompileSym3Flags> ::type(CompileSym3Flags::SecurityChecks) }, | |||
435 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch){ "HotPatch", std::underlying_type<CompileSym3Flags>::type (CompileSym3Flags::HotPatch) }, | |||
436 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL){ "CVTCIL", std::underlying_type<CompileSym3Flags>::type (CompileSym3Flags::CVTCIL) }, | |||
437 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule){ "MSILModule", std::underlying_type<CompileSym3Flags>:: type(CompileSym3Flags::MSILModule) }, | |||
438 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, Sdl){ "Sdl", std::underlying_type<CompileSym3Flags>::type(CompileSym3Flags ::Sdl) }, | |||
439 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, PGO){ "PGO", std::underlying_type<CompileSym3Flags>::type(CompileSym3Flags ::PGO) }, | |||
440 | LLVM_READOBJ_ENUM_CLASS_ENT(CompileSym3Flags, Exp){ "Exp", std::underlying_type<CompileSym3Flags>::type(CompileSym3Flags ::Exp) }, | |||
441 | }; | |||
442 | ||||
443 | static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = { | |||
444 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, C){ "C", SourceLanguage::C }, | |||
445 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cpp){ "Cpp", SourceLanguage::Cpp }, | |||
446 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Fortran){ "Fortran", SourceLanguage::Fortran }, | |||
447 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Masm){ "Masm", SourceLanguage::Masm }, | |||
448 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Pascal){ "Pascal", SourceLanguage::Pascal }, | |||
449 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Basic){ "Basic", SourceLanguage::Basic }, | |||
450 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cobol){ "Cobol", SourceLanguage::Cobol }, | |||
451 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Link){ "Link", SourceLanguage::Link }, | |||
452 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtres){ "Cvtres", SourceLanguage::Cvtres }, | |||
453 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtpgd){ "Cvtpgd", SourceLanguage::Cvtpgd }, | |||
454 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, CSharp){ "CSharp", SourceLanguage::CSharp }, | |||
455 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, VB){ "VB", SourceLanguage::VB }, | |||
456 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, ILAsm){ "ILAsm", SourceLanguage::ILAsm }, | |||
457 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, Java){ "Java", SourceLanguage::Java }, | |||
458 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, JScript){ "JScript", SourceLanguage::JScript }, | |||
459 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, MSIL){ "MSIL", SourceLanguage::MSIL }, | |||
460 | LLVM_READOBJ_ENUM_ENT(SourceLanguage, HLSL){ "HLSL", SourceLanguage::HLSL }, | |||
461 | }; | |||
462 | ||||
463 | static const EnumEntry<uint32_t> SubSectionTypes[] = { | |||
464 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols){ "Symbols", std::underlying_type<ModuleSubstreamKind>:: type(ModuleSubstreamKind::Symbols) }, | |||
465 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines){ "Lines", std::underlying_type<ModuleSubstreamKind>::type (ModuleSubstreamKind::Lines) }, | |||
466 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable){ "StringTable", std::underlying_type<ModuleSubstreamKind> ::type(ModuleSubstreamKind::StringTable) }, | |||
467 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums){ "FileChecksums", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::FileChecksums) }, | |||
468 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData){ "FrameData", std::underlying_type<ModuleSubstreamKind> ::type(ModuleSubstreamKind::FrameData) }, | |||
469 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines){ "InlineeLines", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::InlineeLines) }, | |||
470 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports){ "CrossScopeImports", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::CrossScopeImports) }, | |||
471 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports){ "CrossScopeExports", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::CrossScopeExports) }, | |||
472 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines){ "ILLines", std::underlying_type<ModuleSubstreamKind>:: type(ModuleSubstreamKind::ILLines) }, | |||
473 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap){ "FuncMDTokenMap", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::FuncMDTokenMap) }, | |||
474 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap){ "TypeMDTokenMap", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::TypeMDTokenMap) }, | |||
475 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput){ "MergedAssemblyInput", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::MergedAssemblyInput) }, | |||
476 | LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA){ "CoffSymbolRVA", std::underlying_type<ModuleSubstreamKind >::type(ModuleSubstreamKind::CoffSymbolRVA) }, | |||
477 | }; | |||
478 | ||||
479 | static const EnumEntry<unsigned> CPUTypeNames[] = { | |||
480 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8080){ "Intel8080", std::underlying_type<CPUType>::type(CPUType ::Intel8080) }, | |||
481 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8086){ "Intel8086", std::underlying_type<CPUType>::type(CPUType ::Intel8086) }, | |||
482 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80286){ "Intel80286", std::underlying_type<CPUType>::type(CPUType ::Intel80286) }, | |||
483 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80386){ "Intel80386", std::underlying_type<CPUType>::type(CPUType ::Intel80386) }, | |||
484 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80486){ "Intel80486", std::underlying_type<CPUType>::type(CPUType ::Intel80486) }, | |||
485 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium){ "Pentium", std::underlying_type<CPUType>::type(CPUType ::Pentium) }, | |||
486 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PentiumPro){ "PentiumPro", std::underlying_type<CPUType>::type(CPUType ::PentiumPro) }, | |||
487 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium3){ "Pentium3", std::underlying_type<CPUType>::type(CPUType ::Pentium3) }, | |||
488 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS){ "MIPS", std::underlying_type<CPUType>::type(CPUType:: MIPS) }, | |||
489 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS16){ "MIPS16", std::underlying_type<CPUType>::type(CPUType ::MIPS16) }, | |||
490 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS32){ "MIPS32", std::underlying_type<CPUType>::type(CPUType ::MIPS32) }, | |||
491 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS64){ "MIPS64", std::underlying_type<CPUType>::type(CPUType ::MIPS64) }, | |||
492 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSI){ "MIPSI", std::underlying_type<CPUType>::type(CPUType:: MIPSI) }, | |||
493 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSII){ "MIPSII", std::underlying_type<CPUType>::type(CPUType ::MIPSII) }, | |||
494 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIII){ "MIPSIII", std::underlying_type<CPUType>::type(CPUType ::MIPSIII) }, | |||
495 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIV){ "MIPSIV", std::underlying_type<CPUType>::type(CPUType ::MIPSIV) }, | |||
496 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSV){ "MIPSV", std::underlying_type<CPUType>::type(CPUType:: MIPSV) }, | |||
497 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68000){ "M68000", std::underlying_type<CPUType>::type(CPUType ::M68000) }, | |||
498 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68010){ "M68010", std::underlying_type<CPUType>::type(CPUType ::M68010) }, | |||
499 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68020){ "M68020", std::underlying_type<CPUType>::type(CPUType ::M68020) }, | |||
500 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68030){ "M68030", std::underlying_type<CPUType>::type(CPUType ::M68030) }, | |||
501 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68040){ "M68040", std::underlying_type<CPUType>::type(CPUType ::M68040) }, | |||
502 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha){ "Alpha", std::underlying_type<CPUType>::type(CPUType:: Alpha) }, | |||
503 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164){ "Alpha21164", std::underlying_type<CPUType>::type(CPUType ::Alpha21164) }, | |||
504 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164A){ "Alpha21164A", std::underlying_type<CPUType>::type(CPUType ::Alpha21164A) }, | |||
505 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21264){ "Alpha21264", std::underlying_type<CPUType>::type(CPUType ::Alpha21264) }, | |||
506 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21364){ "Alpha21364", std::underlying_type<CPUType>::type(CPUType ::Alpha21364) }, | |||
507 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC601){ "PPC601", std::underlying_type<CPUType>::type(CPUType ::PPC601) }, | |||
508 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC603){ "PPC603", std::underlying_type<CPUType>::type(CPUType ::PPC603) }, | |||
509 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC604){ "PPC604", std::underlying_type<CPUType>::type(CPUType ::PPC604) }, | |||
510 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC620){ "PPC620", std::underlying_type<CPUType>::type(CPUType ::PPC620) }, | |||
511 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCFP){ "PPCFP", std::underlying_type<CPUType>::type(CPUType:: PPCFP) }, | |||
512 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCBE){ "PPCBE", std::underlying_type<CPUType>::type(CPUType:: PPCBE) }, | |||
513 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3){ "SH3", std::underlying_type<CPUType>::type(CPUType::SH3 ) }, | |||
514 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3E){ "SH3E", std::underlying_type<CPUType>::type(CPUType:: SH3E) }, | |||
515 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3DSP){ "SH3DSP", std::underlying_type<CPUType>::type(CPUType ::SH3DSP) }, | |||
516 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH4){ "SH4", std::underlying_type<CPUType>::type(CPUType::SH4 ) }, | |||
517 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SHMedia){ "SHMedia", std::underlying_type<CPUType>::type(CPUType ::SHMedia) }, | |||
518 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM3){ "ARM3", std::underlying_type<CPUType>::type(CPUType:: ARM3) }, | |||
519 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4){ "ARM4", std::underlying_type<CPUType>::type(CPUType:: ARM4) }, | |||
520 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4T){ "ARM4T", std::underlying_type<CPUType>::type(CPUType:: ARM4T) }, | |||
521 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5){ "ARM5", std::underlying_type<CPUType>::type(CPUType:: ARM5) }, | |||
522 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5T){ "ARM5T", std::underlying_type<CPUType>::type(CPUType:: ARM5T) }, | |||
523 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM6){ "ARM6", std::underlying_type<CPUType>::type(CPUType:: ARM6) }, | |||
524 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_XMAC){ "ARM_XMAC", std::underlying_type<CPUType>::type(CPUType ::ARM_XMAC) }, | |||
525 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_WMMX){ "ARM_WMMX", std::underlying_type<CPUType>::type(CPUType ::ARM_WMMX) }, | |||
526 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM7){ "ARM7", std::underlying_type<CPUType>::type(CPUType:: ARM7) }, | |||
527 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Omni){ "Omni", std::underlying_type<CPUType>::type(CPUType:: Omni) }, | |||
528 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64){ "Ia64", std::underlying_type<CPUType>::type(CPUType:: Ia64) }, | |||
529 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64_2){ "Ia64_2", std::underlying_type<CPUType>::type(CPUType ::Ia64_2) }, | |||
530 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, CEE){ "CEE", std::underlying_type<CPUType>::type(CPUType::CEE ) }, | |||
531 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, AM33){ "AM33", std::underlying_type<CPUType>::type(CPUType:: AM33) }, | |||
532 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M32R){ "M32R", std::underlying_type<CPUType>::type(CPUType:: M32R) }, | |||
533 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, TriCore){ "TriCore", std::underlying_type<CPUType>::type(CPUType ::TriCore) }, | |||
534 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, X64){ "X64", std::underlying_type<CPUType>::type(CPUType::X64 ) }, | |||
535 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, EBC){ "EBC", std::underlying_type<CPUType>::type(CPUType::EBC ) }, | |||
536 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Thumb){ "Thumb", std::underlying_type<CPUType>::type(CPUType:: Thumb) }, | |||
537 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARMNT){ "ARMNT", std::underlying_type<CPUType>::type(CPUType:: ARMNT) }, | |||
538 | LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, D3D11_Shader){ "D3D11_Shader", std::underlying_type<CPUType>::type(CPUType ::D3D11_Shader) }, | |||
539 | }; | |||
540 | ||||
541 | static const EnumEntry<uint8_t> ProcSymFlagNames[] = { | |||
542 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasFP){ "HasFP", std::underlying_type<ProcSymFlags>::type(ProcSymFlags ::HasFP) }, | |||
543 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasIRET){ "HasIRET", std::underlying_type<ProcSymFlags>::type(ProcSymFlags ::HasIRET) }, | |||
544 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasFRET){ "HasFRET", std::underlying_type<ProcSymFlags>::type(ProcSymFlags ::HasFRET) }, | |||
545 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn){ "IsNoReturn", std::underlying_type<ProcSymFlags>::type (ProcSymFlags::IsNoReturn) }, | |||
546 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable){ "IsUnreachable", std::underlying_type<ProcSymFlags>:: type(ProcSymFlags::IsUnreachable) }, | |||
547 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv){ "HasCustomCallingConv", std::underlying_type<ProcSymFlags >::type(ProcSymFlags::HasCustomCallingConv) }, | |||
548 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline){ "IsNoInline", std::underlying_type<ProcSymFlags>::type (ProcSymFlags::IsNoInline) }, | |||
549 | LLVM_READOBJ_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo){ "HasOptimizedDebugInfo", std::underlying_type<ProcSymFlags >::type(ProcSymFlags::HasOptimizedDebugInfo) }, | |||
550 | }; | |||
551 | ||||
552 | static const EnumEntry<uint32_t> FrameProcSymFlags[] = { | |||
553 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca){ "HasAlloca", std::underlying_type<FrameProcedureOptions> ::type(FrameProcedureOptions::HasAlloca) }, | |||
554 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp){ "HasSetJmp", std::underlying_type<FrameProcedureOptions> ::type(FrameProcedureOptions::HasSetJmp) }, | |||
555 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp){ "HasLongJmp", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::HasLongJmp) }, | |||
556 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly){ "HasInlineAssembly", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::HasInlineAssembly) }, | |||
557 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling){ "HasExceptionHandling", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::HasExceptionHandling) }, | |||
558 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline){ "MarkedInline", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::MarkedInline) }, | |||
559 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,{ "HasStructuredExceptionHandling", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::HasStructuredExceptionHandling ) } | |||
560 | HasStructuredExceptionHandling){ "HasStructuredExceptionHandling", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::HasStructuredExceptionHandling ) }, | |||
561 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Naked){ "Naked", std::underlying_type<FrameProcedureOptions>:: type(FrameProcedureOptions::Naked) }, | |||
562 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks){ "SecurityChecks", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::SecurityChecks) }, | |||
563 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,{ "AsynchronousExceptionHandling", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::AsynchronousExceptionHandling ) } | |||
564 | AsynchronousExceptionHandling){ "AsynchronousExceptionHandling", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::AsynchronousExceptionHandling ) }, | |||
565 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,{ "NoStackOrderingForSecurityChecks", std::underlying_type< FrameProcedureOptions>::type(FrameProcedureOptions::NoStackOrderingForSecurityChecks ) } | |||
566 | NoStackOrderingForSecurityChecks){ "NoStackOrderingForSecurityChecks", std::underlying_type< FrameProcedureOptions>::type(FrameProcedureOptions::NoStackOrderingForSecurityChecks ) }, | |||
567 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined){ "Inlined", std::underlying_type<FrameProcedureOptions> ::type(FrameProcedureOptions::Inlined) }, | |||
568 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks){ "StrictSecurityChecks", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::StrictSecurityChecks) }, | |||
569 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers){ "SafeBuffers", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::SafeBuffers) }, | |||
570 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,{ "ProfileGuidedOptimization", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::ProfileGuidedOptimization) } | |||
571 | ProfileGuidedOptimization){ "ProfileGuidedOptimization", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::ProfileGuidedOptimization) }, | |||
572 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts){ "ValidProfileCounts", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::ValidProfileCounts) }, | |||
573 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed){ "OptimizedForSpeed", std::underlying_type<FrameProcedureOptions >::type(FrameProcedureOptions::OptimizedForSpeed) }, | |||
574 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg){ "GuardCfg", std::underlying_type<FrameProcedureOptions> ::type(FrameProcedureOptions::GuardCfg) }, | |||
575 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw){ "GuardCfw", std::underlying_type<FrameProcedureOptions> ::type(FrameProcedureOptions::GuardCfw) }, | |||
576 | }; | |||
577 | ||||
578 | static const EnumEntry<uint32_t> FrameDataFlags[] = { | |||
579 | LLVM_READOBJ_ENUM_ENT(FrameData, HasSEH){ "HasSEH", FrameData::HasSEH }, | |||
580 | LLVM_READOBJ_ENUM_ENT(FrameData, HasEH){ "HasEH", FrameData::HasEH }, | |||
581 | LLVM_READOBJ_ENUM_ENT(FrameData, IsFunctionStart){ "IsFunctionStart", FrameData::IsFunctionStart }, | |||
582 | }; | |||
583 | ||||
584 | static const EnumEntry<uint16_t> LocalFlags[] = { | |||
585 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsParameter){ "IsParameter", std::underlying_type<LocalSymFlags>::type (LocalSymFlags::IsParameter) }, | |||
586 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken){ "IsAddressTaken", std::underlying_type<LocalSymFlags> ::type(LocalSymFlags::IsAddressTaken) }, | |||
587 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated){ "IsCompilerGenerated", std::underlying_type<LocalSymFlags >::type(LocalSymFlags::IsCompilerGenerated) }, | |||
588 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate){ "IsAggregate", std::underlying_type<LocalSymFlags>::type (LocalSymFlags::IsAggregate) }, | |||
589 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated){ "IsAggregated", std::underlying_type<LocalSymFlags>:: type(LocalSymFlags::IsAggregated) }, | |||
590 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAliased){ "IsAliased", std::underlying_type<LocalSymFlags>::type (LocalSymFlags::IsAliased) }, | |||
591 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsAlias){ "IsAlias", std::underlying_type<LocalSymFlags>::type( LocalSymFlags::IsAlias) }, | |||
592 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue){ "IsReturnValue", std::underlying_type<LocalSymFlags>:: type(LocalSymFlags::IsReturnValue) }, | |||
593 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut){ "IsOptimizedOut", std::underlying_type<LocalSymFlags> ::type(LocalSymFlags::IsOptimizedOut) }, | |||
594 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal){ "IsEnregisteredGlobal", std::underlying_type<LocalSymFlags >::type(LocalSymFlags::IsEnregisteredGlobal) }, | |||
595 | LLVM_READOBJ_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic){ "IsEnregisteredStatic", std::underlying_type<LocalSymFlags >::type(LocalSymFlags::IsEnregisteredStatic) }, | |||
596 | }; | |||
597 | ||||
598 | static const EnumEntry<uint32_t> FrameCookieKinds[] = { | |||
599 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, Copy){ "Copy", std::underlying_type<FrameCookieKind>::type(FrameCookieKind ::Copy) }, | |||
600 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer){ "XorStackPointer", std::underlying_type<FrameCookieKind> ::type(FrameCookieKind::XorStackPointer) }, | |||
601 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer){ "XorFramePointer", std::underlying_type<FrameCookieKind> ::type(FrameCookieKind::XorFramePointer) }, | |||
602 | LLVM_READOBJ_ENUM_CLASS_ENT(FrameCookieKind, XorR13){ "XorR13", std::underlying_type<FrameCookieKind>::type (FrameCookieKind::XorR13) }, | |||
603 | }; | |||
604 | ||||
605 | static const EnumEntry<uint8_t> FileChecksumKindNames[] = { | |||
606 | LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None){ "None", std::underlying_type<FileChecksumKind>::type( FileChecksumKind::None) }, | |||
607 | LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5){ "MD5", std::underlying_type<FileChecksumKind>::type(FileChecksumKind ::MD5) }, | |||
608 | LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA1){ "SHA1", std::underlying_type<FileChecksumKind>::type( FileChecksumKind::SHA1) }, | |||
609 | LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256){ "SHA256", std::underlying_type<FileChecksumKind>::type (FileChecksumKind::SHA256) }, | |||
610 | }; | |||
611 | ||||
612 | template <typename T> | |||
613 | static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, | |||
614 | COFFSymbolRef Symbol, | |||
615 | uint8_t AuxSymbolIdx, const T *&Aux) { | |||
616 | ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol); | |||
617 | AuxData = AuxData.slice(AuxSymbolIdx * Obj->getSymbolTableEntrySize()); | |||
618 | Aux = reinterpret_cast<const T*>(AuxData.data()); | |||
619 | return readobj_error::success; | |||
620 | } | |||
621 | ||||
622 | void COFFDumper::cacheRelocations() { | |||
623 | if (RelocCached) | |||
624 | return; | |||
625 | RelocCached = true; | |||
626 | ||||
627 | for (const SectionRef &S : Obj->sections()) { | |||
628 | const coff_section *Section = Obj->getCOFFSection(S); | |||
629 | ||||
630 | for (const RelocationRef &Reloc : S.relocations()) | |||
631 | RelocMap[Section].push_back(Reloc); | |||
632 | ||||
633 | // Sort relocations by address. | |||
634 | std::sort(RelocMap[Section].begin(), RelocMap[Section].end(), | |||
635 | relocAddressLess); | |||
636 | } | |||
637 | } | |||
638 | ||||
639 | void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName) { | |||
640 | const data_directory *Data; | |||
641 | if (Obj->getDataDirectory(Index, Data)) | |||
642 | return; | |||
643 | W.printHex(FieldName + "RVA", Data->RelativeVirtualAddress); | |||
644 | W.printHex(FieldName + "Size", Data->Size); | |||
645 | } | |||
646 | ||||
647 | void COFFDumper::printFileHeaders() { | |||
648 | time_t TDS = Obj->getTimeDateStamp(); | |||
649 | char FormattedTime[20] = { }; | |||
650 | strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); | |||
651 | ||||
652 | { | |||
653 | DictScope D(W, "ImageFileHeader"); | |||
654 | W.printEnum ("Machine", Obj->getMachine(), | |||
655 | makeArrayRef(ImageFileMachineType)); | |||
656 | W.printNumber("SectionCount", Obj->getNumberOfSections()); | |||
657 | W.printHex ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp()); | |||
658 | W.printHex ("PointerToSymbolTable", Obj->getPointerToSymbolTable()); | |||
659 | W.printNumber("SymbolCount", Obj->getNumberOfSymbols()); | |||
660 | W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader()); | |||
661 | W.printFlags ("Characteristics", Obj->getCharacteristics(), | |||
662 | makeArrayRef(ImageFileCharacteristics)); | |||
663 | } | |||
664 | ||||
665 | // Print PE header. This header does not exist if this is an object file and | |||
666 | // not an executable. | |||
667 | const pe32_header *PEHeader = nullptr; | |||
668 | error(Obj->getPE32Header(PEHeader)); | |||
669 | if (PEHeader) | |||
670 | printPEHeader<pe32_header>(PEHeader); | |||
671 | ||||
672 | const pe32plus_header *PEPlusHeader = nullptr; | |||
673 | error(Obj->getPE32PlusHeader(PEPlusHeader)); | |||
674 | if (PEPlusHeader) | |||
675 | printPEHeader<pe32plus_header>(PEPlusHeader); | |||
676 | ||||
677 | if (const dos_header *DH = Obj->getDOSHeader()) | |||
678 | printDOSHeader(DH); | |||
679 | } | |||
680 | ||||
681 | void COFFDumper::printDOSHeader(const dos_header *DH) { | |||
682 | DictScope D(W, "DOSHeader"); | |||
683 | W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic))); | |||
684 | W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage); | |||
685 | W.printNumber("FileSizeInPages", DH->FileSizeInPages); | |||
686 | W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems); | |||
687 | W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs); | |||
688 | W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs); | |||
689 | W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs); | |||
690 | W.printNumber("InitialRelativeSS", DH->InitialRelativeSS); | |||
691 | W.printNumber("InitialSP", DH->InitialSP); | |||
692 | W.printNumber("Checksum", DH->Checksum); | |||
693 | W.printNumber("InitialIP", DH->InitialIP); | |||
694 | W.printNumber("InitialRelativeCS", DH->InitialRelativeCS); | |||
695 | W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable); | |||
696 | W.printNumber("OverlayNumber", DH->OverlayNumber); | |||
697 | W.printNumber("OEMid", DH->OEMid); | |||
698 | W.printNumber("OEMinfo", DH->OEMinfo); | |||
699 | W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader); | |||
700 | } | |||
701 | ||||
702 | template <class PEHeader> | |||
703 | void COFFDumper::printPEHeader(const PEHeader *Hdr) { | |||
704 | DictScope D(W, "ImageOptionalHeader"); | |||
705 | W.printNumber("MajorLinkerVersion", Hdr->MajorLinkerVersion); | |||
706 | W.printNumber("MinorLinkerVersion", Hdr->MinorLinkerVersion); | |||
707 | W.printNumber("SizeOfCode", Hdr->SizeOfCode); | |||
708 | W.printNumber("SizeOfInitializedData", Hdr->SizeOfInitializedData); | |||
709 | W.printNumber("SizeOfUninitializedData", Hdr->SizeOfUninitializedData); | |||
710 | W.printHex ("AddressOfEntryPoint", Hdr->AddressOfEntryPoint); | |||
711 | W.printHex ("BaseOfCode", Hdr->BaseOfCode); | |||
712 | printBaseOfDataField(Hdr); | |||
713 | W.printHex ("ImageBase", Hdr->ImageBase); | |||
714 | W.printNumber("SectionAlignment", Hdr->SectionAlignment); | |||
715 | W.printNumber("FileAlignment", Hdr->FileAlignment); | |||
716 | W.printNumber("MajorOperatingSystemVersion", | |||
717 | Hdr->MajorOperatingSystemVersion); | |||
718 | W.printNumber("MinorOperatingSystemVersion", | |||
719 | Hdr->MinorOperatingSystemVersion); | |||
720 | W.printNumber("MajorImageVersion", Hdr->MajorImageVersion); | |||
721 | W.printNumber("MinorImageVersion", Hdr->MinorImageVersion); | |||
722 | W.printNumber("MajorSubsystemVersion", Hdr->MajorSubsystemVersion); | |||
723 | W.printNumber("MinorSubsystemVersion", Hdr->MinorSubsystemVersion); | |||
724 | W.printNumber("SizeOfImage", Hdr->SizeOfImage); | |||
725 | W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders); | |||
726 | W.printEnum ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem)); | |||
727 | W.printFlags ("Characteristics", Hdr->DLLCharacteristics, | |||
728 | makeArrayRef(PEDLLCharacteristics)); | |||
729 | W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve); | |||
730 | W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit); | |||
731 | W.printNumber("SizeOfHeapReserve", Hdr->SizeOfHeapReserve); | |||
732 | W.printNumber("SizeOfHeapCommit", Hdr->SizeOfHeapCommit); | |||
733 | W.printNumber("NumberOfRvaAndSize", Hdr->NumberOfRvaAndSize); | |||
734 | ||||
735 | if (Hdr->NumberOfRvaAndSize > 0) { | |||
736 | DictScope D(W, "DataDirectory"); | |||
737 | static const char * const directory[] = { | |||
738 | "ExportTable", "ImportTable", "ResourceTable", "ExceptionTable", | |||
739 | "CertificateTable", "BaseRelocationTable", "Debug", "Architecture", | |||
740 | "GlobalPtr", "TLSTable", "LoadConfigTable", "BoundImport", "IAT", | |||
741 | "DelayImportDescriptor", "CLRRuntimeHeader", "Reserved" | |||
742 | }; | |||
743 | ||||
744 | for (uint32_t i = 0; i < Hdr->NumberOfRvaAndSize; ++i) { | |||
745 | printDataDirectory(i, directory[i]); | |||
746 | } | |||
747 | } | |||
748 | } | |||
749 | ||||
750 | void COFFDumper::printBaseOfDataField(const pe32_header *Hdr) { | |||
751 | W.printHex("BaseOfData", Hdr->BaseOfData); | |||
752 | } | |||
753 | ||||
754 | void COFFDumper::printBaseOfDataField(const pe32plus_header *) {} | |||
755 | ||||
756 | void COFFDumper::printCodeViewDebugInfo() { | |||
757 | // Print types first to build CVUDTNames, then print symbols. | |||
758 | for (const SectionRef &S : Obj->sections()) { | |||
759 | StringRef SectionName; | |||
760 | error(S.getName(SectionName)); | |||
761 | if (SectionName == ".debug$T") | |||
762 | printCodeViewTypeSection(SectionName, S); | |||
763 | } | |||
764 | for (const SectionRef &S : Obj->sections()) { | |||
765 | StringRef SectionName; | |||
766 | error(S.getName(SectionName)); | |||
767 | if (SectionName == ".debug$S") | |||
768 | printCodeViewSymbolSection(SectionName, S); | |||
769 | } | |||
770 | } | |||
771 | ||||
772 | void COFFDumper::initializeFileAndStringTables(StringRef Data) { | |||
773 | while (!Data.empty() && (CVFileChecksumTable.data() == nullptr || | |||
774 | CVStringTable.data() == nullptr)) { | |||
775 | // The section consists of a number of subsection in the following format: | |||
776 | // |SubSectionType|SubSectionSize|Contents...| | |||
777 | uint32_t SubType, SubSectionSize; | |||
778 | error(consume(Data, SubType)); | |||
779 | error(consume(Data, SubSectionSize)); | |||
780 | if (SubSectionSize > Data.size()) | |||
781 | return error(object_error::parse_failed); | |||
782 | switch (ModuleSubstreamKind(SubType)) { | |||
783 | case ModuleSubstreamKind::FileChecksums: | |||
784 | CVFileChecksumTable = Data.substr(0, SubSectionSize); | |||
785 | break; | |||
786 | case ModuleSubstreamKind::StringTable: | |||
787 | CVStringTable = Data.substr(0, SubSectionSize); | |||
788 | break; | |||
789 | default: | |||
790 | break; | |||
791 | } | |||
792 | Data = Data.drop_front(alignTo(SubSectionSize, 4)); | |||
793 | } | |||
794 | } | |||
795 | ||||
796 | void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, | |||
797 | const SectionRef &Section) { | |||
798 | StringRef SectionContents; | |||
799 | error(Section.getContents(SectionContents)); | |||
800 | StringRef Data = SectionContents; | |||
801 | ||||
802 | SmallVector<StringRef, 10> FunctionNames; | |||
803 | StringMap<StringRef> FunctionLineTables; | |||
804 | ||||
805 | ListScope D(W, "CodeViewDebugInfo"); | |||
806 | // Print the section to allow correlation with printSections. | |||
807 | W.printNumber("Section", SectionName, Obj->getSectionID(Section)); | |||
808 | ||||
809 | uint32_t Magic; | |||
810 | error(consume(Data, Magic)); | |||
811 | W.printHex("Magic", Magic); | |||
812 | if (Magic != COFF::DEBUG_SECTION_MAGIC) | |||
813 | return error(object_error::parse_failed); | |||
814 | ||||
815 | initializeFileAndStringTables(Data); | |||
816 | ||||
817 | while (!Data.empty()) { | |||
818 | // The section consists of a number of subsection in the following format: | |||
819 | // |SubSectionType|SubSectionSize|Contents...| | |||
820 | uint32_t SubType, SubSectionSize; | |||
821 | error(consume(Data, SubType)); | |||
822 | error(consume(Data, SubSectionSize)); | |||
823 | ||||
824 | ListScope S(W, "Subsection"); | |||
825 | W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes)); | |||
826 | W.printHex("SubSectionSize", SubSectionSize); | |||
827 | ||||
828 | // Get the contents of the subsection. | |||
829 | if (SubSectionSize > Data.size()) | |||
830 | return error(object_error::parse_failed); | |||
831 | StringRef Contents = Data.substr(0, SubSectionSize); | |||
832 | ||||
833 | // Add SubSectionSize to the current offset and align that offset to find | |||
834 | // the next subsection. | |||
835 | size_t SectionOffset = Data.data() - SectionContents.data(); | |||
836 | size_t NextOffset = SectionOffset + SubSectionSize; | |||
837 | NextOffset = alignTo(NextOffset, 4); | |||
838 | Data = SectionContents.drop_front(NextOffset); | |||
839 | ||||
840 | // Optionally print the subsection bytes in case our parsing gets confused | |||
841 | // later. | |||
842 | if (opts::CodeViewSubsectionBytes) | |||
843 | printBinaryBlockWithRelocs("SubSectionContents", Section, SectionContents, | |||
844 | Contents); | |||
845 | ||||
846 | switch (ModuleSubstreamKind(SubType)) { | |||
847 | case ModuleSubstreamKind::Symbols: | |||
848 | printCodeViewSymbolsSubsection(Contents, Section, SectionContents); | |||
849 | break; | |||
850 | ||||
851 | case ModuleSubstreamKind::InlineeLines: | |||
852 | printCodeViewInlineeLines(Contents); | |||
853 | break; | |||
854 | ||||
855 | case ModuleSubstreamKind::FileChecksums: | |||
856 | printCodeViewFileChecksums(Contents); | |||
857 | break; | |||
858 | ||||
859 | case ModuleSubstreamKind::Lines: { | |||
860 | // Holds a PC to file:line table. Some data to parse this subsection is | |||
861 | // stored in the other subsections, so just check sanity and store the | |||
862 | // pointers for deferred processing. | |||
863 | ||||
864 | if (SubSectionSize < 12) { | |||
865 | // There should be at least three words to store two function | |||
866 | // relocations and size of the code. | |||
867 | error(object_error::parse_failed); | |||
868 | return; | |||
869 | } | |||
870 | ||||
871 | StringRef LinkageName; | |||
872 | error(resolveSymbolName(Obj->getCOFFSection(Section), SectionOffset, | |||
873 | LinkageName)); | |||
874 | W.printString("LinkageName", LinkageName); | |||
875 | if (FunctionLineTables.count(LinkageName) != 0) { | |||
876 | // Saw debug info for this function already? | |||
877 | error(object_error::parse_failed); | |||
878 | return; | |||
879 | } | |||
880 | ||||
881 | FunctionLineTables[LinkageName] = Contents; | |||
882 | FunctionNames.push_back(LinkageName); | |||
883 | break; | |||
884 | } | |||
885 | case ModuleSubstreamKind::FrameData: { | |||
886 | // First four bytes is a relocation against the function. | |||
887 | const uint32_t *CodePtr; | |||
888 | error(consumeObject(Contents, CodePtr)); | |||
889 | StringRef LinkageName; | |||
890 | error(resolveSymbolName(Obj->getCOFFSection(Section), SectionContents, | |||
891 | CodePtr, LinkageName)); | |||
892 | W.printString("LinkageName", LinkageName); | |||
893 | ||||
894 | // To find the active frame description, search this array for the | |||
895 | // smallest PC range that includes the current PC. | |||
896 | while (!Contents.empty()) { | |||
897 | const FrameData *FD; | |||
898 | error(consumeObject(Contents, FD)); | |||
899 | DictScope S(W, "FrameData"); | |||
900 | W.printHex("RvaStart", FD->RvaStart); | |||
901 | W.printHex("CodeSize", FD->CodeSize); | |||
902 | W.printHex("LocalSize", FD->LocalSize); | |||
903 | W.printHex("ParamsSize", FD->ParamsSize); | |||
904 | W.printHex("MaxStackSize", FD->MaxStackSize); | |||
905 | W.printString("FrameFunc", | |||
906 | CVStringTable.drop_front(FD->FrameFunc).split('\0').first); | |||
907 | W.printHex("PrologSize", FD->PrologSize); | |||
908 | W.printHex("SavedRegsSize", FD->SavedRegsSize); | |||
909 | W.printFlags("Flags", FD->Flags, makeArrayRef(FrameDataFlags)); | |||
910 | } | |||
911 | break; | |||
912 | } | |||
913 | ||||
914 | // Do nothing for unrecognized subsections. | |||
915 | default: | |||
916 | break; | |||
917 | } | |||
918 | W.flush(); | |||
919 | } | |||
920 | ||||
921 | // Dump the line tables now that we've read all the subsections and know all | |||
922 | // the required information. | |||
923 | for (unsigned I = 0, E = FunctionNames.size(); I != E; ++I) { | |||
924 | StringRef Name = FunctionNames[I]; | |||
925 | ListScope S(W, "FunctionLineTable"); | |||
926 | W.printString("LinkageName", Name); | |||
927 | ||||
928 | DataExtractor DE(FunctionLineTables[Name], true, 4); | |||
929 | uint32_t Offset = 6; // Skip relocations. | |||
930 | uint16_t Flags = DE.getU16(&Offset); | |||
931 | W.printHex("Flags", Flags); | |||
932 | bool HasColumnInformation = Flags & codeview::LineFlags::HaveColumns; | |||
933 | uint32_t FunctionSize = DE.getU32(&Offset); | |||
934 | W.printHex("CodeSize", FunctionSize); | |||
935 | while (DE.isValidOffset(Offset)) { | |||
936 | // For each range of lines with the same filename, we have a segment | |||
937 | // in the line table. The filename string is accessed using double | |||
938 | // indirection to the string table subsection using the index subsection. | |||
939 | uint32_t OffsetInIndex = DE.getU32(&Offset), | |||
940 | NumLines = DE.getU32(&Offset), | |||
941 | FullSegmentSize = DE.getU32(&Offset); | |||
942 | ||||
943 | uint32_t ColumnOffset = Offset + 8 * NumLines; | |||
944 | DataExtractor ColumnDE(DE.getData(), true, 4); | |||
945 | ||||
946 | if (FullSegmentSize != | |||
947 | 12 + 8 * NumLines + (HasColumnInformation ? 4 * NumLines : 0)) { | |||
948 | error(object_error::parse_failed); | |||
949 | return; | |||
950 | } | |||
951 | ||||
952 | ListScope S(W, "FilenameSegment"); | |||
953 | printFileNameForOffset("Filename", OffsetInIndex); | |||
954 | for (unsigned LineIdx = 0; | |||
955 | LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { | |||
956 | // Then go the (PC, LineNumber) pairs. The line number is stored in the | |||
957 | // least significant 31 bits of the respective word in the table. | |||
958 | uint32_t PC = DE.getU32(&Offset), LineData = DE.getU32(&Offset); | |||
959 | if (PC >= FunctionSize) { | |||
960 | error(object_error::parse_failed); | |||
961 | return; | |||
962 | } | |||
963 | char Buffer[32]; | |||
964 | format("+0x%X", PC).snprint(Buffer, 32); | |||
965 | ListScope PCScope(W, Buffer); | |||
966 | LineInfo LI(LineData); | |||
967 | if (LI.isAlwaysStepInto()) | |||
968 | W.printString("StepInto", StringRef("Always")); | |||
969 | else if (LI.isNeverStepInto()) | |||
970 | W.printString("StepInto", StringRef("Never")); | |||
971 | else | |||
972 | W.printNumber("LineNumberStart", LI.getStartLine()); | |||
973 | W.printNumber("LineNumberEndDelta", LI.getLineDelta()); | |||
974 | W.printBoolean("IsStatement", LI.isStatement()); | |||
975 | if (HasColumnInformation && | |||
976 | ColumnDE.isValidOffsetForDataOfSize(ColumnOffset, 4)) { | |||
977 | uint16_t ColStart = ColumnDE.getU16(&ColumnOffset); | |||
978 | W.printNumber("ColStart", ColStart); | |||
979 | uint16_t ColEnd = ColumnDE.getU16(&ColumnOffset); | |||
980 | W.printNumber("ColEnd", ColEnd); | |||
981 | } | |||
982 | } | |||
983 | // Skip over the column data. | |||
984 | if (HasColumnInformation) { | |||
985 | for (unsigned LineIdx = 0; | |||
986 | LineIdx != NumLines && DE.isValidOffset(Offset); ++LineIdx) { | |||
987 | DE.getU32(&Offset); | |||
988 | } | |||
989 | } | |||
990 | } | |||
991 | } | |||
992 | } | |||
993 | ||||
994 | void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, | |||
995 | const SectionRef &Section, | |||
996 | StringRef SectionContents) { | |||
997 | if (Subsection.size() < sizeof(RecordPrefix)) | |||
998 | return error(object_error::parse_failed); | |||
999 | ||||
1000 | const coff_section *Sec = Obj->getCOFFSection(Section); | |||
1001 | ||||
1002 | // This holds the remaining data to parse. | |||
1003 | StringRef Data = Subsection; | |||
1004 | ||||
1005 | bool InFunctionScope = false; | |||
1006 | while (!Data.empty()) { | |||
1007 | const RecordPrefix *Rec; | |||
1008 | error(consumeObject(Data, Rec)); | |||
1009 | ||||
1010 | StringRef SymData = Data.substr(0, Rec->RecordLen - 2); | |||
1011 | StringRef OrigSymData = SymData; | |||
1012 | ||||
1013 | Data = Data.drop_front(Rec->RecordLen - 2); | |||
1014 | ||||
1015 | SymbolKind Kind = static_cast<SymbolKind>(uint16_t(Rec->RecordKind)); | |||
1016 | switch (Kind) { | |||
1017 | case S_LPROC32: | |||
1018 | case S_GPROC32: | |||
1019 | case S_GPROC32_ID: | |||
1020 | case S_LPROC32_ID: | |||
1021 | case S_LPROC32_DPC: | |||
1022 | case S_LPROC32_DPC_ID: { | |||
1023 | DictScope S(W, "ProcStart"); | |||
1024 | const ProcSym *Proc; | |||
1025 | error(consumeObject(SymData, Proc)); | |||
1026 | if (InFunctionScope) | |||
1027 | return error(object_error::parse_failed); | |||
1028 | InFunctionScope = true; | |||
1029 | ||||
1030 | StringRef LinkageName; | |||
1031 | StringRef DisplayName = SymData.split('\0').first; | |||
1032 | W.printHex("PtrParent", Proc->PtrParent); | |||
1033 | W.printHex("PtrEnd", Proc->PtrEnd); | |||
1034 | W.printHex("PtrNext", Proc->PtrNext); | |||
1035 | W.printHex("CodeSize", Proc->CodeSize); | |||
1036 | W.printHex("DbgStart", Proc->DbgStart); | |||
1037 | W.printHex("DbgEnd", Proc->DbgEnd); | |||
1038 | printTypeIndex("FunctionType", Proc->FunctionType); | |||
1039 | printRelocatedField("CodeOffset", Sec, SectionContents, &Proc->CodeOffset, | |||
1040 | &LinkageName); | |||
1041 | W.printHex("Segment", Proc->Segment); | |||
1042 | W.printFlags("Flags", Proc->Flags, makeArrayRef(ProcSymFlagNames)); | |||
1043 | W.printString("DisplayName", DisplayName); | |||
1044 | W.printString("LinkageName", LinkageName); | |||
1045 | break; | |||
1046 | } | |||
1047 | ||||
1048 | case S_PROC_ID_END: { | |||
1049 | W.startLine() << "ProcEnd\n"; | |||
1050 | InFunctionScope = false; | |||
1051 | break; | |||
1052 | } | |||
1053 | ||||
1054 | case S_BLOCK32: { | |||
1055 | DictScope S(W, "BlockStart"); | |||
1056 | const BlockSym *Block; | |||
1057 | error(consumeObject(SymData, Block)); | |||
1058 | ||||
1059 | StringRef BlockName = SymData.split('\0').first; | |||
1060 | StringRef LinkageName; | |||
1061 | W.printHex("PtrParent", Block->PtrParent); | |||
1062 | W.printHex("PtrEnd", Block->PtrEnd); | |||
1063 | W.printHex("CodeSize", Block->CodeSize); | |||
1064 | printRelocatedField("CodeOffset", Sec, SectionContents, | |||
1065 | &Block->CodeOffset, &LinkageName); | |||
1066 | W.printHex("Segment", Block->Segment); | |||
1067 | W.printString("BlockName", BlockName); | |||
1068 | W.printString("LinkageName", LinkageName); | |||
1069 | break; | |||
1070 | } | |||
1071 | ||||
1072 | case S_END: { | |||
1073 | W.startLine() << "BlockEnd\n"; | |||
1074 | InFunctionScope = false; | |||
1075 | break; | |||
1076 | } | |||
1077 | ||||
1078 | case S_LABEL32: { | |||
1079 | DictScope S(W, "Label"); | |||
1080 | const LabelSym *Label; | |||
1081 | error(consumeObject(SymData, Label)); | |||
1082 | ||||
1083 | StringRef DisplayName = SymData.split('\0').first; | |||
1084 | StringRef LinkageName; | |||
1085 | printRelocatedField("CodeOffset", Sec, SectionContents, | |||
1086 | &Label->CodeOffset, &LinkageName); | |||
1087 | W.printHex("Segment", Label->Segment); | |||
1088 | W.printHex("Flags", Label->Flags); | |||
1089 | W.printFlags("Flags", Label->Flags, makeArrayRef(ProcSymFlagNames)); | |||
1090 | W.printString("DisplayName", DisplayName); | |||
1091 | W.printString("LinkageName", LinkageName); | |||
1092 | break; | |||
1093 | } | |||
1094 | ||||
1095 | case S_INLINESITE: { | |||
1096 | DictScope S(W, "InlineSite"); | |||
1097 | const InlineSiteSym *InlineSite; | |||
1098 | error(consumeObject(SymData, InlineSite)); | |||
1099 | W.printHex("PtrParent", InlineSite->PtrParent); | |||
1100 | W.printHex("PtrEnd", InlineSite->PtrEnd); | |||
1101 | printTypeIndex("Inlinee", InlineSite->Inlinee); | |||
1102 | ||||
1103 | auto GetCompressedAnnotation = [&]() -> uint32_t { | |||
1104 | if (SymData.empty()) | |||
1105 | return -1; | |||
1106 | ||||
1107 | uint8_t FirstByte = SymData.front(); | |||
1108 | SymData = SymData.drop_front(); | |||
1109 | ||||
1110 | if ((FirstByte & 0x80) == 0x00) | |||
1111 | return FirstByte; | |||
1112 | ||||
1113 | if (SymData.empty()) | |||
1114 | return -1; | |||
1115 | ||||
1116 | uint8_t SecondByte = SymData.front(); | |||
1117 | SymData = SymData.drop_front(); | |||
1118 | ||||
1119 | if ((FirstByte & 0xC0) == 0x80) | |||
1120 | return ((FirstByte & 0x3F) << 8) | SecondByte; | |||
1121 | ||||
1122 | if (SymData.empty()) | |||
1123 | return -1; | |||
1124 | ||||
1125 | uint8_t ThirdByte = SymData.front(); | |||
1126 | SymData = SymData.drop_front(); | |||
1127 | ||||
1128 | if (SymData.empty()) | |||
1129 | return -1; | |||
1130 | ||||
1131 | uint8_t FourthByte = SymData.front(); | |||
1132 | SymData = SymData.drop_front(); | |||
1133 | ||||
1134 | if ((FirstByte & 0xE0) == 0xC0) | |||
1135 | return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) | | |||
1136 | (ThirdByte << 8) | FourthByte; | |||
1137 | ||||
1138 | return -1; | |||
1139 | }; | |||
1140 | auto DecodeSignedOperand = [](uint32_t Operand) -> int32_t { | |||
1141 | if (Operand & 1) | |||
1142 | return -(Operand >> 1); | |||
1143 | return Operand >> 1; | |||
1144 | }; | |||
1145 | ||||
1146 | ListScope BinaryAnnotations(W, "BinaryAnnotations"); | |||
1147 | while (!SymData.empty()) { | |||
1148 | auto OpCode = | |||
1149 | static_cast<BinaryAnnotationsOpCode>(GetCompressedAnnotation()); | |||
1150 | switch (OpCode) { | |||
1151 | case BinaryAnnotationsOpCode::Invalid: | |||
1152 | return error(object_error::parse_failed); | |||
1153 | case BinaryAnnotationsOpCode::CodeOffset: | |||
1154 | W.printHex("CodeOffset", GetCompressedAnnotation()); | |||
1155 | break; | |||
1156 | case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: | |||
1157 | W.printNumber("ChangeCodeOffsetBase", GetCompressedAnnotation()); | |||
1158 | break; | |||
1159 | case BinaryAnnotationsOpCode::ChangeCodeOffset: | |||
1160 | W.printHex("ChangeCodeOffset", GetCompressedAnnotation()); | |||
1161 | break; | |||
1162 | case BinaryAnnotationsOpCode::ChangeCodeLength: | |||
1163 | W.printHex("ChangeCodeLength", GetCompressedAnnotation()); | |||
1164 | break; | |||
1165 | case BinaryAnnotationsOpCode::ChangeFile: | |||
1166 | printFileNameForOffset("ChangeFile", GetCompressedAnnotation()); | |||
1167 | break; | |||
1168 | case BinaryAnnotationsOpCode::ChangeLineOffset: | |||
1169 | W.printNumber("ChangeLineOffset", | |||
1170 | DecodeSignedOperand(GetCompressedAnnotation())); | |||
1171 | break; | |||
1172 | case BinaryAnnotationsOpCode::ChangeLineEndDelta: | |||
1173 | W.printNumber("ChangeLineEndDelta", GetCompressedAnnotation()); | |||
1174 | break; | |||
1175 | case BinaryAnnotationsOpCode::ChangeRangeKind: | |||
1176 | W.printNumber("ChangeRangeKind", GetCompressedAnnotation()); | |||
1177 | break; | |||
1178 | case BinaryAnnotationsOpCode::ChangeColumnStart: | |||
1179 | W.printNumber("ChangeColumnStart", GetCompressedAnnotation()); | |||
1180 | break; | |||
1181 | case BinaryAnnotationsOpCode::ChangeColumnEndDelta: | |||
1182 | W.printNumber("ChangeColumnEndDelta", | |||
1183 | DecodeSignedOperand(GetCompressedAnnotation())); | |||
1184 | break; | |||
1185 | case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { | |||
1186 | uint32_t Annotation = GetCompressedAnnotation(); | |||
1187 | int32_t LineOffset = DecodeSignedOperand(Annotation >> 4); | |||
1188 | uint32_t CodeOffset = Annotation & 0xf; | |||
1189 | W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: " | |||
1190 | << W.hex(CodeOffset) << ", LineOffset: " << LineOffset | |||
1191 | << "}\n"; | |||
1192 | break; | |||
1193 | } | |||
1194 | case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { | |||
1195 | uint32_t Length = GetCompressedAnnotation(); | |||
1196 | uint32_t CodeOffset = GetCompressedAnnotation(); | |||
1197 | W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: " | |||
1198 | << W.hex(CodeOffset) << ", Length: " << W.hex(Length) | |||
1199 | << "}\n"; | |||
1200 | break; | |||
1201 | } | |||
1202 | case BinaryAnnotationsOpCode::ChangeColumnEnd: | |||
1203 | W.printNumber("ChangeColumnEnd", GetCompressedAnnotation()); | |||
1204 | break; | |||
1205 | } | |||
1206 | } | |||
1207 | break; | |||
1208 | } | |||
1209 | ||||
1210 | case S_INLINESITE_END: { | |||
1211 | DictScope S(W, "InlineSiteEnd"); | |||
1212 | break; | |||
1213 | } | |||
1214 | ||||
1215 | case S_CALLERS: | |||
1216 | case S_CALLEES: { | |||
1217 | ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers"); | |||
1218 | uint32_t Count; | |||
1219 | error(consume(SymData, Count)); | |||
1220 | for (uint32_t I = 0; I < Count; ++I) { | |||
1221 | const TypeIndex *FuncID; | |||
1222 | error(consumeObject(SymData, FuncID)); | |||
1223 | printTypeIndex("FuncID", *FuncID); | |||
1224 | } | |||
1225 | break; | |||
1226 | } | |||
1227 | ||||
1228 | case S_LOCAL: { | |||
1229 | DictScope S(W, "Local"); | |||
1230 | const LocalSym *Local; | |||
1231 | error(consumeObject(SymData, Local)); | |||
1232 | printTypeIndex("Type", Local->Type); | |||
1233 | W.printFlags("Flags", uint16_t(Local->Flags), makeArrayRef(LocalFlags)); | |||
1234 | StringRef VarName = SymData.split('\0').first; | |||
1235 | W.printString("VarName", VarName); | |||
1236 | break; | |||
1237 | } | |||
1238 | ||||
1239 | case S_DEFRANGE: { | |||
1240 | DictScope S(W, "DefRange"); | |||
1241 | const DefRangeSym *DefRange; | |||
1242 | error(consumeObject(SymData, DefRange)); | |||
1243 | W.printString( | |||
1244 | "Program", | |||
1245 | CVStringTable.drop_front(DefRange->Program).split('\0').first); | |||
1246 | printLocalVariableAddrRange(DefRange->Range, Sec, SectionContents); | |||
1247 | printLocalVariableAddrGap(SymData); | |||
1248 | break; | |||
1249 | } | |||
1250 | case S_DEFRANGE_SUBFIELD: { | |||
1251 | DictScope S(W, "DefRangeSubfield"); | |||
1252 | const DefRangeSubfieldSym *DefRangeSubfield; | |||
1253 | error(consumeObject(SymData, DefRangeSubfield)); | |||
1254 | W.printString("Program", | |||
1255 | CVStringTable.drop_front(DefRangeSubfield->Program) | |||
1256 | .split('\0') | |||
1257 | .first); | |||
1258 | W.printNumber("OffsetInParent", DefRangeSubfield->OffsetInParent); | |||
1259 | printLocalVariableAddrRange(DefRangeSubfield->Range, Sec, | |||
1260 | SectionContents); | |||
1261 | printLocalVariableAddrGap(SymData); | |||
1262 | break; | |||
1263 | } | |||
1264 | case S_DEFRANGE_REGISTER: { | |||
1265 | DictScope S(W, "DefRangeRegister"); | |||
1266 | const DefRangeRegisterSym *DefRangeRegister; | |||
1267 | error(consumeObject(SymData, DefRangeRegister)); | |||
1268 | W.printNumber("Register", DefRangeRegister->Register); | |||
1269 | W.printNumber("MayHaveNoName", DefRangeRegister->MayHaveNoName); | |||
1270 | printLocalVariableAddrRange(DefRangeRegister->Range, Sec, | |||
1271 | SectionContents); | |||
1272 | printLocalVariableAddrGap(SymData); | |||
1273 | break; | |||
1274 | } | |||
1275 | case S_DEFRANGE_SUBFIELD_REGISTER: { | |||
1276 | DictScope S(W, "DefRangeSubfieldRegister"); | |||
1277 | const DefRangeSubfieldRegisterSym *DefRangeSubfieldRegisterSym; | |||
1278 | error(consumeObject(SymData, DefRangeSubfieldRegisterSym)); | |||
1279 | W.printNumber("Register", DefRangeSubfieldRegisterSym->Register); | |||
1280 | W.printNumber("MayHaveNoName", | |||
1281 | DefRangeSubfieldRegisterSym->MayHaveNoName); | |||
1282 | W.printNumber("OffsetInParent", | |||
1283 | DefRangeSubfieldRegisterSym->OffsetInParent); | |||
1284 | printLocalVariableAddrRange(DefRangeSubfieldRegisterSym->Range, Sec, | |||
1285 | SectionContents); | |||
1286 | printLocalVariableAddrGap(SymData); | |||
1287 | break; | |||
1288 | } | |||
1289 | case S_DEFRANGE_FRAMEPOINTER_REL: { | |||
1290 | DictScope S(W, "DefRangeFramePointerRel"); | |||
1291 | const DefRangeFramePointerRelSym *DefRangeFramePointerRel; | |||
1292 | error(consumeObject(SymData, DefRangeFramePointerRel)); | |||
1293 | W.printNumber("Offset", DefRangeFramePointerRel->Offset); | |||
1294 | printLocalVariableAddrRange(DefRangeFramePointerRel->Range, Sec, | |||
1295 | SectionContents); | |||
1296 | printLocalVariableAddrGap(SymData); | |||
1297 | break; | |||
1298 | } | |||
1299 | case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: { | |||
1300 | DictScope S(W, "DefRangeFramePointerRelFullScope"); | |||
1301 | const DefRangeFramePointerRelFullScopeSym | |||
1302 | *DefRangeFramePointerRelFullScope; | |||
1303 | error(consumeObject(SymData, DefRangeFramePointerRelFullScope)); | |||
1304 | W.printNumber("Offset", DefRangeFramePointerRelFullScope->Offset); | |||
1305 | break; | |||
1306 | } | |||
1307 | case S_DEFRANGE_REGISTER_REL: { | |||
1308 | DictScope S(W, "DefRangeRegisterRel"); | |||
1309 | const DefRangeRegisterRelSym *DefRangeRegisterRel; | |||
1310 | error(consumeObject(SymData, DefRangeRegisterRel)); | |||
1311 | W.printNumber("BaseRegister", DefRangeRegisterRel->BaseRegister); | |||
1312 | W.printBoolean("HasSpilledUDTMember", | |||
1313 | DefRangeRegisterRel->hasSpilledUDTMember()); | |||
1314 | W.printNumber("OffsetInParent", DefRangeRegisterRel->offsetInParent()); | |||
1315 | W.printNumber("BasePointerOffset", | |||
1316 | DefRangeRegisterRel->BasePointerOffset); | |||
1317 | printLocalVariableAddrRange(DefRangeRegisterRel->Range, Sec, | |||
1318 | SectionContents); | |||
1319 | printLocalVariableAddrGap(SymData); | |||
1320 | break; | |||
1321 | } | |||
1322 | ||||
1323 | case S_CALLSITEINFO: { | |||
1324 | DictScope S(W, "CallSiteInfo"); | |||
1325 | const CallSiteInfoSym *CallSiteInfo; | |||
1326 | error(consumeObject(SymData, CallSiteInfo)); | |||
1327 | ||||
1328 | StringRef LinkageName; | |||
1329 | printRelocatedField("CodeOffset", Sec, SectionContents, | |||
1330 | &CallSiteInfo->CodeOffset, &LinkageName); | |||
1331 | W.printHex("Segment", CallSiteInfo->Segment); | |||
1332 | W.printHex("Reserved", CallSiteInfo->Reserved); | |||
1333 | printTypeIndex("Type", CallSiteInfo->Type); | |||
1334 | W.printString("LinkageName", LinkageName); | |||
1335 | break; | |||
1336 | } | |||
1337 | ||||
1338 | case S_HEAPALLOCSITE: { | |||
1339 | DictScope S(W, "HeapAllocationSite"); | |||
1340 | const HeapAllocationSiteSym *HeapAllocationSite; | |||
1341 | error(consumeObject(SymData, HeapAllocationSite)); | |||
1342 | ||||
1343 | StringRef LinkageName; | |||
1344 | printRelocatedField("CodeOffset", Sec, SectionContents, | |||
1345 | &HeapAllocationSite->CodeOffset, &LinkageName); | |||
1346 | W.printHex("Segment", HeapAllocationSite->Segment); | |||
1347 | W.printHex("CallInstructionSize", | |||
1348 | HeapAllocationSite->CallInstructionSize); | |||
1349 | printTypeIndex("Type", HeapAllocationSite->Type); | |||
1350 | W.printString("LinkageName", LinkageName); | |||
1351 | break; | |||
1352 | } | |||
1353 | ||||
1354 | case S_FRAMECOOKIE: { | |||
1355 | DictScope S(W, "FrameCookie"); | |||
1356 | const FrameCookieSym *FrameCookie; | |||
1357 | error(consumeObject(SymData, FrameCookie)); | |||
1358 | ||||
1359 | StringRef LinkageName; | |||
1360 | printRelocatedField("CodeOffset", Sec, SectionContents, | |||
1361 | &FrameCookie->CodeOffset, &LinkageName); | |||
1362 | W.printHex("Register", FrameCookie->Register); | |||
1363 | W.printEnum("CookieKind", uint16_t(FrameCookie->CookieKind), | |||
1364 | makeArrayRef(FrameCookieKinds)); | |||
1365 | break; | |||
1366 | } | |||
1367 | ||||
1368 | case S_LDATA32: | |||
1369 | case S_GDATA32: | |||
1370 | case S_LMANDATA: | |||
1371 | case S_GMANDATA: { | |||
1372 | DictScope S(W, "DataSym"); | |||
1373 | const DataSym *Data; | |||
1374 | error(consumeObject(SymData, Data)); | |||
1375 | ||||
1376 | StringRef DisplayName = SymData.split('\0').first; | |||
1377 | StringRef LinkageName; | |||
1378 | printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset, | |||
1379 | &LinkageName); | |||
1380 | printTypeIndex("Type", Data->Type); | |||
1381 | W.printString("DisplayName", DisplayName); | |||
1382 | W.printString("LinkageName", LinkageName); | |||
1383 | break; | |||
1384 | } | |||
1385 | ||||
1386 | case S_LTHREAD32: | |||
1387 | case S_GTHREAD32: { | |||
1388 | DictScope S(W, "ThreadLocalDataSym"); | |||
1389 | const ThreadLocalDataSym *Data; | |||
1390 | error(consumeObject(SymData, Data)); | |||
1391 | ||||
1392 | StringRef DisplayName = SymData.split('\0').first; | |||
1393 | StringRef LinkageName; | |||
1394 | printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset, | |||
1395 | &LinkageName); | |||
1396 | printTypeIndex("Type", Data->Type); | |||
1397 | W.printString("DisplayName", DisplayName); | |||
1398 | W.printString("LinkageName", LinkageName); | |||
1399 | break; | |||
1400 | } | |||
1401 | ||||
1402 | case S_OBJNAME: { | |||
1403 | DictScope S(W, "ObjectName"); | |||
1404 | const ObjNameSym *ObjName; | |||
1405 | error(consumeObject(SymData, ObjName)); | |||
1406 | W.printHex("Signature", ObjName->Signature); | |||
1407 | StringRef ObjectName = SymData.split('\0').first; | |||
1408 | W.printString("ObjectName", ObjectName); | |||
1409 | break; | |||
1410 | } | |||
1411 | ||||
1412 | case S_COMPILE3: { | |||
1413 | DictScope S(W, "CompilerFlags"); | |||
1414 | const CompileSym3 *CompFlags; | |||
1415 | error(consumeObject(SymData, CompFlags)); | |||
1416 | W.printEnum("Language", CompFlags->getLanguage(), | |||
1417 | makeArrayRef(SourceLanguages)); | |||
1418 | W.printFlags("Flags", CompFlags->flags & ~0xff, | |||
1419 | makeArrayRef(CompileSym3FlagNames)); | |||
1420 | W.printEnum("Machine", unsigned(CompFlags->Machine), | |||
1421 | makeArrayRef(CPUTypeNames)); | |||
1422 | std::string FrontendVersion; | |||
1423 | { | |||
1424 | raw_string_ostream Out(FrontendVersion); | |||
1425 | Out << CompFlags->VersionFrontendMajor << '.' | |||
1426 | << CompFlags->VersionFrontendMinor << '.' | |||
1427 | << CompFlags->VersionFrontendBuild << '.' | |||
1428 | << CompFlags->VersionFrontendQFE; | |||
1429 | } | |||
1430 | std::string BackendVersion; | |||
1431 | { | |||
1432 | raw_string_ostream Out(BackendVersion); | |||
1433 | Out << CompFlags->VersionBackendMajor << '.' | |||
1434 | << CompFlags->VersionBackendMinor << '.' | |||
1435 | << CompFlags->VersionBackendBuild << '.' | |||
1436 | << CompFlags->VersionBackendQFE; | |||
1437 | } | |||
1438 | W.printString("FrontendVersion", FrontendVersion); | |||
1439 | W.printString("BackendVersion", BackendVersion); | |||
1440 | StringRef VersionName = SymData.split('\0').first; | |||
1441 | W.printString("VersionName", VersionName); | |||
1442 | break; | |||
1443 | } | |||
1444 | ||||
1445 | case S_FRAMEPROC: { | |||
1446 | DictScope S(W, "FrameProc"); | |||
1447 | const FrameProcSym *FrameProc; | |||
1448 | error(consumeObject(SymData, FrameProc)); | |||
1449 | W.printHex("TotalFrameBytes", FrameProc->TotalFrameBytes); | |||
1450 | W.printHex("PaddingFrameBytes", FrameProc->PaddingFrameBytes); | |||
1451 | W.printHex("OffsetToPadding", FrameProc->OffsetToPadding); | |||
1452 | W.printHex("BytesOfCalleeSavedRegisters", FrameProc->BytesOfCalleeSavedRegisters); | |||
1453 | W.printHex("OffsetOfExceptionHandler", FrameProc->OffsetOfExceptionHandler); | |||
1454 | W.printHex("SectionIdOfExceptionHandler", FrameProc->SectionIdOfExceptionHandler); | |||
1455 | W.printFlags("Flags", FrameProc->Flags, makeArrayRef(FrameProcSymFlags)); | |||
1456 | break; | |||
1457 | } | |||
1458 | ||||
1459 | case S_UDT: | |||
1460 | case S_COBOLUDT: { | |||
1461 | DictScope S(W, "UDT"); | |||
1462 | const UDTSym *UDT; | |||
1463 | error(consumeObject(SymData, UDT)); | |||
1464 | printTypeIndex("Type", UDT->Type); | |||
1465 | StringRef UDTName = SymData.split('\0').first; | |||
1466 | W.printString("UDTName", UDTName); | |||
1467 | break; | |||
1468 | } | |||
1469 | ||||
1470 | case S_BPREL32: { | |||
1471 | DictScope S(W, "BPRelativeSym"); | |||
1472 | const BPRelativeSym *BPRel; | |||
1473 | error(consumeObject(SymData, BPRel)); | |||
1474 | W.printNumber("Offset", BPRel->Offset); | |||
1475 | printTypeIndex("Type", BPRel->Type); | |||
1476 | StringRef VarName = SymData.split('\0').first; | |||
1477 | W.printString("VarName", VarName); | |||
1478 | break; | |||
1479 | } | |||
1480 | ||||
1481 | case S_REGREL32: { | |||
1482 | DictScope S(W, "RegRelativeSym"); | |||
1483 | const RegRelativeSym *RegRel; | |||
1484 | error(consumeObject(SymData, RegRel)); | |||
1485 | W.printHex("Offset", RegRel->Offset); | |||
1486 | printTypeIndex("Type", RegRel->Type); | |||
1487 | W.printHex("Register", RegRel->Register); | |||
1488 | StringRef VarName = SymData.split('\0').first; | |||
1489 | W.printString("VarName", VarName); | |||
1490 | break; | |||
1491 | } | |||
1492 | ||||
1493 | case S_BUILDINFO: { | |||
1494 | DictScope S(W, "BuildInfo"); | |||
1495 | const BuildInfoSym *BuildInfo; | |||
1496 | error(consumeObject(SymData, BuildInfo)); | |||
1497 | W.printNumber("BuildId", BuildInfo->BuildId); | |||
1498 | break; | |||
1499 | } | |||
1500 | ||||
1501 | case S_CONSTANT: | |||
1502 | case S_MANCONSTANT: { | |||
1503 | DictScope S(W, "Constant"); | |||
1504 | const ConstantSym *Constant; | |||
1505 | error(consumeObject(SymData, Constant)); | |||
1506 | printTypeIndex("Type", Constant->Type); | |||
1507 | APSInt Value; | |||
1508 | if (consume(SymData, Value)) | |||
1509 | error(object_error::parse_failed); | |||
1510 | W.printNumber("Value", Value); | |||
1511 | StringRef Name = SymData.split('\0').first; | |||
1512 | W.printString("Name", Name); | |||
1513 | break; | |||
1514 | } | |||
1515 | ||||
1516 | default: { | |||
1517 | DictScope S(W, "UnknownSym"); | |||
1518 | W.printHex("Kind", unsigned(Kind)); | |||
1519 | W.printHex("Size", Rec->RecordLen); | |||
1520 | break; | |||
1521 | } | |||
1522 | } | |||
1523 | ||||
1524 | if (opts::CodeViewSubsectionBytes) | |||
1525 | printBinaryBlockWithRelocs("SymData", Section, SectionContents, | |||
1526 | OrigSymData); | |||
1527 | W.flush(); | |||
1528 | } | |||
1529 | W.flush(); | |||
1530 | } | |||
1531 | ||||
1532 | void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { | |||
1533 | StringRef Data = Subsection; | |||
1534 | while (!Data.empty()) { | |||
1535 | DictScope S(W, "FileChecksum"); | |||
1536 | const FileChecksum *FC; | |||
1537 | error(consumeObject(Data, FC)); | |||
1538 | if (FC->FileNameOffset >= CVStringTable.size()) | |||
1539 | error(object_error::parse_failed); | |||
1540 | StringRef Filename = | |||
1541 | CVStringTable.drop_front(FC->FileNameOffset).split('\0').first; | |||
1542 | W.printHex("Filename", Filename, FC->FileNameOffset); | |||
1543 | W.printHex("ChecksumSize", FC->ChecksumSize); | |||
1544 | W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind), | |||
1545 | makeArrayRef(FileChecksumKindNames)); | |||
1546 | if (FC->ChecksumSize >= Data.size()) | |||
1547 | error(object_error::parse_failed); | |||
1548 | StringRef ChecksumBytes = Data.substr(0, FC->ChecksumSize); | |||
1549 | W.printBinary("ChecksumBytes", ChecksumBytes); | |||
1550 | unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) - | |||
1551 | sizeof(FileChecksum); | |||
1552 | Data = Data.drop_front(PaddedSize); | |||
1553 | } | |||
1554 | } | |||
1555 | ||||
1556 | void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { | |||
1557 | StringRef Data = Subsection; | |||
1558 | uint32_t Signature; | |||
1559 | error(consume(Data, Signature)); | |||
1560 | bool HasExtraFiles = Signature == unsigned(InlineeLinesSignature::ExtraFiles); | |||
1561 | ||||
1562 | while (!Data.empty()) { | |||
1563 | const InlineeSourceLine *ISL; | |||
1564 | error(consumeObject(Data, ISL)); | |||
1565 | DictScope S(W, "InlineeSourceLine"); | |||
1566 | printTypeIndex("Inlinee", ISL->Inlinee); | |||
1567 | printFileNameForOffset("FileID", ISL->FileID); | |||
1568 | W.printNumber("SourceLineNum", ISL->SourceLineNum); | |||
1569 | ||||
1570 | if (HasExtraFiles) { | |||
1571 | uint32_t ExtraFileCount; | |||
1572 | error(consume(Data, ExtraFileCount)); | |||
1573 | W.printNumber("ExtraFileCount", ExtraFileCount); | |||
1574 | ListScope ExtraFiles(W, "ExtraFiles"); | |||
1575 | for (unsigned I = 0; I < ExtraFileCount; ++I) { | |||
1576 | uint32_t FileID; | |||
1577 | error(consume(Data, FileID)); | |||
1578 | printFileNameForOffset("FileID", FileID); | |||
1579 | } | |||
1580 | } | |||
1581 | } | |||
1582 | } | |||
1583 | ||||
1584 | void COFFDumper::printLocalVariableAddrRange( | |||
1585 | const LocalVariableAddrRange &Range, const coff_section *Sec, | |||
1586 | StringRef SectionContents) { | |||
1587 | DictScope S(W, "LocalVariableAddrRange"); | |||
1588 | printRelocatedField("OffsetStart", Sec, SectionContents, &Range.OffsetStart); | |||
1589 | W.printHex("ISectStart", Range.ISectStart); | |||
1590 | W.printHex("Range", Range.Range); | |||
1591 | } | |||
1592 | ||||
1593 | void COFFDumper::printLocalVariableAddrGap(StringRef &SymData) { | |||
1594 | while (!SymData.empty()) { | |||
| ||||
1595 | const LocalVariableAddrGap *Gap; | |||
1596 | error(consumeObject(SymData, Gap)); | |||
1597 | ListScope S(W, "LocalVariableAddrGap"); | |||
1598 | W.printHex("GapStartOffset", Gap->GapStartOffset); | |||
| ||||
1599 | W.printHex("Range", Gap->Range); | |||
1600 | } | |||
1601 | } | |||
1602 | ||||
1603 | StringRef COFFDumper::getFileNameForFileOffset(uint32_t FileOffset) { | |||
1604 | // The file checksum subsection should precede all references to it. | |||
1605 | if (!CVFileChecksumTable.data() || !CVStringTable.data()) | |||
1606 | error(object_error::parse_failed); | |||
1607 | // Check if the file checksum table offset is valid. | |||
1608 | if (FileOffset >= CVFileChecksumTable.size()) | |||
1609 | error(object_error::parse_failed); | |||
1610 | ||||
1611 | // The string table offset comes first before the file checksum. | |||
1612 | StringRef Data = CVFileChecksumTable.drop_front(FileOffset); | |||
1613 | uint32_t StringOffset; | |||
1614 | error(consume(Data, StringOffset)); | |||
1615 | ||||
1616 | // Check if the string table offset is valid. | |||
1617 | if (StringOffset >= CVStringTable.size()) | |||
1618 | error(object_error::parse_failed); | |||
1619 | ||||
1620 | // Return the null-terminated string. | |||
1621 | return CVStringTable.drop_front(StringOffset).split('\0').first; | |||
1622 | } | |||
1623 | ||||
1624 | void COFFDumper::printFileNameForOffset(StringRef Label, uint32_t FileOffset) { | |||
1625 | W.printHex(Label, getFileNameForFileOffset(FileOffset), FileOffset); | |||
1626 | } | |||
1627 | ||||
1628 | void COFFDumper::mergeCodeViewTypes(MemoryTypeTableBuilder &CVTypes) { | |||
1629 | for (const SectionRef &S : Obj->sections()) { | |||
1630 | StringRef SectionName; | |||
1631 | error(S.getName(SectionName)); | |||
1632 | if (SectionName == ".debug$T") { | |||
1633 | StringRef Data; | |||
1634 | error(S.getContents(Data)); | |||
1635 | unsigned Magic = *reinterpret_cast<const ulittle32_t *>(Data.data()); | |||
1636 | if (Magic != 4) | |||
1637 | error(object_error::parse_failed); | |||
1638 | Data = Data.drop_front(4); | |||
1639 | ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()), | |||
1640 | Data.size()); | |||
1641 | if (!mergeTypeStreams(CVTypes, Bytes)) | |||
1642 | return error(object_error::parse_failed); | |||
1643 | } | |||
1644 | } | |||
1645 | } | |||
1646 | ||||
1647 | void COFFDumper::printCodeViewTypeSection(StringRef SectionName, | |||
1648 | const SectionRef &Section) { | |||
1649 | ListScope D(W, "CodeViewTypes"); | |||
1650 | W.printNumber("Section", SectionName, Obj->getSectionID(Section)); | |||
1651 | ||||
1652 | StringRef Data; | |||
1653 | error(Section.getContents(Data)); | |||
1654 | if (opts::CodeViewSubsectionBytes) | |||
1655 | W.printBinaryBlock("Data", Data); | |||
1656 | ||||
1657 | uint32_t Magic; | |||
1658 | error(consume(Data, Magic)); | |||
1659 | W.printHex("Magic", Magic); | |||
1660 | if (Magic != COFF::DEBUG_SECTION_MAGIC) | |||
1661 | return error(object_error::parse_failed); | |||
1662 | ||||
1663 | ArrayRef<uint8_t> BinaryData(reinterpret_cast<const uint8_t *>(Data.data()), | |||
1664 | Data.size()); | |||
1665 | if (!CVTD.dump(BinaryData)) { | |||
1666 | W.flush(); | |||
1667 | error(object_error::parse_failed); | |||
1668 | } | |||
1669 | } | |||
1670 | ||||
1671 | void COFFDumper::printSections() { | |||
1672 | ListScope SectionsD(W, "Sections"); | |||
1673 | int SectionNumber = 0; | |||
1674 | for (const SectionRef &Sec : Obj->sections()) { | |||
1675 | ++SectionNumber; | |||
1676 | const coff_section *Section = Obj->getCOFFSection(Sec); | |||
1677 | ||||
1678 | StringRef Name; | |||
1679 | error(Sec.getName(Name)); | |||
1680 | ||||
1681 | DictScope D(W, "Section"); | |||
1682 | W.printNumber("Number", SectionNumber); | |||
1683 | W.printBinary("Name", Name, Section->Name); | |||
1684 | W.printHex ("VirtualSize", Section->VirtualSize); | |||
1685 | W.printHex ("VirtualAddress", Section->VirtualAddress); | |||
1686 | W.printNumber("RawDataSize", Section->SizeOfRawData); | |||
1687 | W.printHex ("PointerToRawData", Section->PointerToRawData); | |||
1688 | W.printHex ("PointerToRelocations", Section->PointerToRelocations); | |||
1689 | W.printHex ("PointerToLineNumbers", Section->PointerToLinenumbers); | |||
1690 | W.printNumber("RelocationCount", Section->NumberOfRelocations); | |||
1691 | W.printNumber("LineNumberCount", Section->NumberOfLinenumbers); | |||
1692 | W.printFlags ("Characteristics", Section->Characteristics, | |||
1693 | makeArrayRef(ImageSectionCharacteristics), | |||
1694 | COFF::SectionCharacteristics(0x00F00000)); | |||
1695 | ||||
1696 | if (opts::SectionRelocations) { | |||
1697 | ListScope D(W, "Relocations"); | |||
1698 | for (const RelocationRef &Reloc : Sec.relocations()) | |||
1699 | printRelocation(Sec, Reloc); | |||
1700 | } | |||
1701 | ||||
1702 | if (opts::SectionSymbols) { | |||
1703 | ListScope D(W, "Symbols"); | |||
1704 | for (const SymbolRef &Symbol : Obj->symbols()) { | |||
1705 | if (!Sec.containsSymbol(Symbol)) | |||
1706 | continue; | |||
1707 | ||||
1708 | printSymbol(Symbol); | |||
1709 | } | |||
1710 | } | |||
1711 | ||||
1712 | if (opts::SectionData && | |||
1713 | !(Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { | |||
1714 | StringRef Data; | |||
1715 | error(Sec.getContents(Data)); | |||
1716 | ||||
1717 | W.printBinaryBlock("SectionData", Data); | |||
1718 | } | |||
1719 | } | |||
1720 | } | |||
1721 | ||||
1722 | void COFFDumper::printRelocations() { | |||
1723 | ListScope D(W, "Relocations"); | |||
1724 | ||||
1725 | int SectionNumber = 0; | |||
1726 | for (const SectionRef &Section : Obj->sections()) { | |||
1727 | ++SectionNumber; | |||
1728 | StringRef Name; | |||
1729 | error(Section.getName(Name)); | |||
1730 | ||||
1731 | bool PrintedGroup = false; | |||
1732 | for (const RelocationRef &Reloc : Section.relocations()) { | |||
1733 | if (!PrintedGroup) { | |||
1734 | W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; | |||
1735 | W.indent(); | |||
1736 | PrintedGroup = true; | |||
1737 | } | |||
1738 | ||||
1739 | printRelocation(Section, Reloc); | |||
1740 | } | |||
1741 | ||||
1742 | if (PrintedGroup) { | |||
1743 | W.unindent(); | |||
1744 | W.startLine() << "}\n"; | |||
1745 | } | |||
1746 | } | |||
1747 | } | |||
1748 | ||||
1749 | void COFFDumper::printRelocation(const SectionRef &Section, | |||
1750 | const RelocationRef &Reloc, uint64_t Bias) { | |||
1751 | uint64_t Offset = Reloc.getOffset() - Bias; | |||
1752 | uint64_t RelocType = Reloc.getType(); | |||
1753 | SmallString<32> RelocName; | |||
1754 | StringRef SymbolName; | |||
1755 | Reloc.getTypeName(RelocName); | |||
1756 | symbol_iterator Symbol = Reloc.getSymbol(); | |||
1757 | if (Symbol != Obj->symbol_end()) { | |||
1758 | Expected<StringRef> SymbolNameOrErr = Symbol->getName(); | |||
1759 | error(errorToErrorCode(SymbolNameOrErr.takeError())); | |||
1760 | SymbolName = *SymbolNameOrErr; | |||
1761 | } | |||
1762 | ||||
1763 | if (opts::ExpandRelocs) { | |||
1764 | DictScope Group(W, "Relocation"); | |||
1765 | W.printHex("Offset", Offset); | |||
1766 | W.printNumber("Type", RelocName, RelocType); | |||
1767 | W.printString("Symbol", SymbolName.empty() ? "-" : SymbolName); | |||
1768 | } else { | |||
1769 | raw_ostream& OS = W.startLine(); | |||
1770 | OS << W.hex(Offset) | |||
1771 | << " " << RelocName | |||
1772 | << " " << (SymbolName.empty() ? "-" : SymbolName) | |||
1773 | << "\n"; | |||
1774 | } | |||
1775 | } | |||
1776 | ||||
1777 | void COFFDumper::printSymbols() { | |||
1778 | ListScope Group(W, "Symbols"); | |||
1779 | ||||
1780 | for (const SymbolRef &Symbol : Obj->symbols()) | |||
1781 | printSymbol(Symbol); | |||
1782 | } | |||
1783 | ||||
1784 | void COFFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); } | |||
1785 | ||||
1786 | static ErrorOr<StringRef> | |||
1787 | getSectionName(const llvm::object::COFFObjectFile *Obj, int32_t SectionNumber, | |||
1788 | const coff_section *Section) { | |||
1789 | if (Section) { | |||
1790 | StringRef SectionName; | |||
1791 | if (std::error_code EC = Obj->getSectionName(Section, SectionName)) | |||
1792 | return EC; | |||
1793 | return SectionName; | |||
1794 | } | |||
1795 | if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG) | |||
1796 | return StringRef("IMAGE_SYM_DEBUG"); | |||
1797 | if (SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE) | |||
1798 | return StringRef("IMAGE_SYM_ABSOLUTE"); | |||
1799 | if (SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED) | |||
1800 | return StringRef("IMAGE_SYM_UNDEFINED"); | |||
1801 | return StringRef(""); | |||
1802 | } | |||
1803 | ||||
1804 | void COFFDumper::printSymbol(const SymbolRef &Sym) { | |||
1805 | DictScope D(W, "Symbol"); | |||
1806 | ||||
1807 | COFFSymbolRef Symbol = Obj->getCOFFSymbol(Sym); | |||
1808 | const coff_section *Section; | |||
1809 | if (std::error_code EC = Obj->getSection(Symbol.getSectionNumber(), Section)) { | |||
1810 | W.startLine() << "Invalid section number: " << EC.message() << "\n"; | |||
1811 | W.flush(); | |||
1812 | return; | |||
1813 | } | |||
1814 | ||||
1815 | StringRef SymbolName; | |||
1816 | if (Obj->getSymbolName(Symbol, SymbolName)) | |||
1817 | SymbolName = ""; | |||
1818 | ||||
1819 | StringRef SectionName = ""; | |||
1820 | ErrorOr<StringRef> Res = | |||
1821 | getSectionName(Obj, Symbol.getSectionNumber(), Section); | |||
1822 | if (Res) | |||
1823 | SectionName = *Res; | |||
1824 | ||||
1825 | W.printString("Name", SymbolName); | |||
1826 | W.printNumber("Value", Symbol.getValue()); | |||
1827 | W.printNumber("Section", SectionName, Symbol.getSectionNumber()); | |||
1828 | W.printEnum ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType)); | |||
1829 | W.printEnum ("ComplexType", Symbol.getComplexType(), | |||
1830 | makeArrayRef(ImageSymDType)); | |||
1831 | W.printEnum ("StorageClass", Symbol.getStorageClass(), | |||
1832 | makeArrayRef(ImageSymClass)); | |||
1833 | W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols()); | |||
1834 | ||||
1835 | for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) { | |||
1836 | if (Symbol.isFunctionDefinition()) { | |||
1837 | const coff_aux_function_definition *Aux; | |||
1838 | error(getSymbolAuxData(Obj, Symbol, I, Aux)); | |||
1839 | ||||
1840 | DictScope AS(W, "AuxFunctionDef"); | |||
1841 | W.printNumber("TagIndex", Aux->TagIndex); | |||
1842 | W.printNumber("TotalSize", Aux->TotalSize); | |||
1843 | W.printHex("PointerToLineNumber", Aux->PointerToLinenumber); | |||
1844 | W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); | |||
1845 | ||||
1846 | } else if (Symbol.isAnyUndefined()) { | |||
1847 | const coff_aux_weak_external *Aux; | |||
1848 | error(getSymbolAuxData(Obj, Symbol, I, Aux)); | |||
1849 | ||||
1850 | ErrorOr<COFFSymbolRef> Linked = Obj->getSymbol(Aux->TagIndex); | |||
1851 | StringRef LinkedName; | |||
1852 | std::error_code EC = Linked.getError(); | |||
1853 | if (EC || (EC = Obj->getSymbolName(*Linked, LinkedName))) { | |||
1854 | LinkedName = ""; | |||
1855 | error(EC); | |||
1856 | } | |||
1857 | ||||
1858 | DictScope AS(W, "AuxWeakExternal"); | |||
1859 | W.printNumber("Linked", LinkedName, Aux->TagIndex); | |||
1860 | W.printEnum ("Search", Aux->Characteristics, | |||
1861 | makeArrayRef(WeakExternalCharacteristics)); | |||
1862 | ||||
1863 | } else if (Symbol.isFileRecord()) { | |||
1864 | const char *FileName; | |||
1865 | error(getSymbolAuxData(Obj, Symbol, I, FileName)); | |||
1866 | ||||
1867 | DictScope AS(W, "AuxFileRecord"); | |||
1868 | ||||
1869 | StringRef Name(FileName, Symbol.getNumberOfAuxSymbols() * | |||
1870 | Obj->getSymbolTableEntrySize()); | |||
1871 | W.printString("FileName", Name.rtrim(StringRef("\0", 1))); | |||
1872 | break; | |||
1873 | } else if (Symbol.isSectionDefinition()) { | |||
1874 | const coff_aux_section_definition *Aux; | |||
1875 | error(getSymbolAuxData(Obj, Symbol, I, Aux)); | |||
1876 | ||||
1877 | int32_t AuxNumber = Aux->getNumber(Symbol.isBigObj()); | |||
1878 | ||||
1879 | DictScope AS(W, "AuxSectionDef"); | |||
1880 | W.printNumber("Length", Aux->Length); | |||
1881 | W.printNumber("RelocationCount", Aux->NumberOfRelocations); | |||
1882 | W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers); | |||
1883 | W.printHex("Checksum", Aux->CheckSum); | |||
1884 | W.printNumber("Number", AuxNumber); | |||
1885 | W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); | |||
1886 | ||||
1887 | if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT | |||
1888 | && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { | |||
1889 | const coff_section *Assoc; | |||
1890 | StringRef AssocName = ""; | |||
1891 | std::error_code EC = Obj->getSection(AuxNumber, Assoc); | |||
1892 | ErrorOr<StringRef> Res = getSectionName(Obj, AuxNumber, Assoc); | |||
1893 | if (Res) | |||
1894 | AssocName = *Res; | |||
1895 | if (!EC) | |||
1896 | EC = Res.getError(); | |||
1897 | if (EC) { | |||
1898 | AssocName = ""; | |||
1899 | error(EC); | |||
1900 | } | |||
1901 | ||||
1902 | W.printNumber("AssocSection", AssocName, AuxNumber); | |||
1903 | } | |||
1904 | } else if (Symbol.isCLRToken()) { | |||
1905 | const coff_aux_clr_token *Aux; | |||
1906 | error(getSymbolAuxData(Obj, Symbol, I, Aux)); | |||
1907 | ||||
1908 | ErrorOr<COFFSymbolRef> ReferredSym = | |||
1909 | Obj->getSymbol(Aux->SymbolTableIndex); | |||
1910 | StringRef ReferredName; | |||
1911 | std::error_code EC = ReferredSym.getError(); | |||
1912 | if (EC || (EC = Obj->getSymbolName(*ReferredSym, ReferredName))) { | |||
1913 | ReferredName = ""; | |||
1914 | error(EC); | |||
1915 | } | |||
1916 | ||||
1917 | DictScope AS(W, "AuxCLRToken"); | |||
1918 | W.printNumber("AuxType", Aux->AuxType); | |||
1919 | W.printNumber("Reserved", Aux->Reserved); | |||
1920 | W.printNumber("SymbolTableIndex", ReferredName, Aux->SymbolTableIndex); | |||
1921 | ||||
1922 | } else { | |||
1923 | W.startLine() << "<unhandled auxiliary record>\n"; | |||
1924 | } | |||
1925 | } | |||
1926 | } | |||
1927 | ||||
1928 | void COFFDumper::printUnwindInfo() { | |||
1929 | ListScope D(W, "UnwindInformation"); | |||
1930 | switch (Obj->getMachine()) { | |||
1931 | case COFF::IMAGE_FILE_MACHINE_AMD64: { | |||
1932 | Win64EH::Dumper Dumper(W); | |||
1933 | Win64EH::Dumper::SymbolResolver | |||
1934 | Resolver = [](const object::coff_section *Section, uint64_t Offset, | |||
1935 | SymbolRef &Symbol, void *user_data) -> std::error_code { | |||
1936 | COFFDumper *Dumper = reinterpret_cast<COFFDumper *>(user_data); | |||
1937 | return Dumper->resolveSymbol(Section, Offset, Symbol); | |||
1938 | }; | |||
1939 | Win64EH::Dumper::Context Ctx(*Obj, Resolver, this); | |||
1940 | Dumper.printData(Ctx); | |||
1941 | break; | |||
1942 | } | |||
1943 | case COFF::IMAGE_FILE_MACHINE_ARMNT: { | |||
1944 | ARM::WinEH::Decoder Decoder(W); | |||
1945 | Decoder.dumpProcedureData(*Obj); | |||
1946 | break; | |||
1947 | } | |||
1948 | default: | |||
1949 | W.printEnum("unsupported Image Machine", Obj->getMachine(), | |||
1950 | makeArrayRef(ImageFileMachineType)); | |||
1951 | break; | |||
1952 | } | |||
1953 | } | |||
1954 | ||||
1955 | void COFFDumper::printImportedSymbols( | |||
1956 | iterator_range<imported_symbol_iterator> Range) { | |||
1957 | for (const ImportedSymbolRef &I : Range) { | |||
1958 | StringRef Sym; | |||
1959 | error(I.getSymbolName(Sym)); | |||
1960 | uint16_t Ordinal; | |||
1961 | error(I.getOrdinal(Ordinal)); | |||
1962 | W.printNumber("Symbol", Sym, Ordinal); | |||
1963 | } | |||
1964 | } | |||
1965 | ||||
1966 | void COFFDumper::printDelayImportedSymbols( | |||
1967 | const DelayImportDirectoryEntryRef &I, | |||
1968 | iterator_range<imported_symbol_iterator> Range) { | |||
1969 | int Index = 0; | |||
1970 | for (const ImportedSymbolRef &S : Range) { | |||
1971 | DictScope Import(W, "Import"); | |||
1972 | StringRef Sym; | |||
1973 | error(S.getSymbolName(Sym)); | |||
1974 | uint16_t Ordinal; | |||
1975 | error(S.getOrdinal(Ordinal)); | |||
1976 | W.printNumber("Symbol", Sym, Ordinal); | |||
1977 | uint64_t Addr; | |||
1978 | error(I.getImportAddress(Index++, Addr)); | |||
1979 | W.printHex("Address", Addr); | |||
1980 | } | |||
1981 | } | |||
1982 | ||||
1983 | void COFFDumper::printCOFFImports() { | |||
1984 | // Regular imports | |||
1985 | for (const ImportDirectoryEntryRef &I : Obj->import_directories()) { | |||
1986 | DictScope Import(W, "Import"); | |||
1987 | StringRef Name; | |||
1988 | error(I.getName(Name)); | |||
1989 | W.printString("Name", Name); | |||
1990 | uint32_t Addr; | |||
1991 | error(I.getImportLookupTableRVA(Addr)); | |||
1992 | W.printHex("ImportLookupTableRVA", Addr); | |||
1993 | error(I.getImportAddressTableRVA(Addr)); | |||
1994 | W.printHex("ImportAddressTableRVA", Addr); | |||
1995 | printImportedSymbols(I.imported_symbols()); | |||
1996 | } | |||
1997 | ||||
1998 | // Delay imports | |||
1999 | for (const DelayImportDirectoryEntryRef &I : Obj->delay_import_directories()) { | |||
2000 | DictScope Import(W, "DelayImport"); | |||
2001 | StringRef Name; | |||
2002 | error(I.getName(Name)); | |||
2003 | W.printString("Name", Name); | |||
2004 | const delay_import_directory_table_entry *Table; | |||
2005 | error(I.getDelayImportTable(Table)); | |||
2006 | W.printHex("Attributes", Table->Attributes); | |||
2007 | W.printHex("ModuleHandle", Table->ModuleHandle); | |||
2008 | W.printHex("ImportAddressTable", Table->DelayImportAddressTable); | |||
2009 | W.printHex("ImportNameTable", Table->DelayImportNameTable); | |||
2010 | W.printHex("BoundDelayImportTable", Table->BoundDelayImportTable); | |||
2011 | W.printHex("UnloadDelayImportTable", Table->UnloadDelayImportTable); | |||
2012 | printDelayImportedSymbols(I, I.imported_symbols()); | |||
2013 | } | |||
2014 | } | |||
2015 | ||||
2016 | void COFFDumper::printCOFFExports() { | |||
2017 | for (const ExportDirectoryEntryRef &E : Obj->export_directories()) { | |||
2018 | DictScope Export(W, "Export"); | |||
2019 | ||||
2020 | StringRef Name; | |||
2021 | uint32_t Ordinal, RVA; | |||
2022 | ||||
2023 | error(E.getSymbolName(Name)); | |||
2024 | error(E.getOrdinal(Ordinal)); | |||
2025 | error(E.getExportRVA(RVA)); | |||
2026 | ||||
2027 | W.printNumber("Ordinal", Ordinal); | |||
2028 | W.printString("Name", Name); | |||
2029 | W.printHex("RVA", RVA); | |||
2030 | } | |||
2031 | } | |||
2032 | ||||
2033 | void COFFDumper::printCOFFDirectives() { | |||
2034 | for (const SectionRef &Section : Obj->sections()) { | |||
2035 | StringRef Contents; | |||
2036 | StringRef Name; | |||
2037 | ||||
2038 | error(Section.getName(Name)); | |||
2039 | if (Name != ".drectve") | |||
2040 | continue; | |||
2041 | ||||
2042 | error(Section.getContents(Contents)); | |||
2043 | ||||
2044 | W.printString("Directive(s)", Contents); | |||
2045 | } | |||
2046 | } | |||
2047 | ||||
2048 | static StringRef getBaseRelocTypeName(uint8_t Type) { | |||
2049 | switch (Type) { | |||
2050 | case COFF::IMAGE_REL_BASED_ABSOLUTE: return "ABSOLUTE"; | |||
2051 | case COFF::IMAGE_REL_BASED_HIGH: return "HIGH"; | |||
2052 | case COFF::IMAGE_REL_BASED_LOW: return "LOW"; | |||
2053 | case COFF::IMAGE_REL_BASED_HIGHLOW: return "HIGHLOW"; | |||
2054 | case COFF::IMAGE_REL_BASED_HIGHADJ: return "HIGHADJ"; | |||
2055 | case COFF::IMAGE_REL_BASED_ARM_MOV32T: return "ARM_MOV32(T)"; | |||
2056 | case COFF::IMAGE_REL_BASED_DIR64: return "DIR64"; | |||
2057 | default: return "unknown (" + llvm::utostr(Type) + ")"; | |||
2058 | } | |||
2059 | } | |||
2060 | ||||
2061 | void COFFDumper::printCOFFBaseReloc() { | |||
2062 | ListScope D(W, "BaseReloc"); | |||
2063 | for (const BaseRelocRef &I : Obj->base_relocs()) { | |||
2064 | uint8_t Type; | |||
2065 | uint32_t RVA; | |||
2066 | error(I.getRVA(RVA)); | |||
2067 | error(I.getType(Type)); | |||
2068 | DictScope Import(W, "Entry"); | |||
2069 | W.printString("Type", getBaseRelocTypeName(Type)); | |||
2070 | W.printHex("Address", RVA); | |||
2071 | } | |||
2072 | } | |||
2073 | ||||
2074 | void COFFDumper::printStackMap() const { | |||
2075 | object::SectionRef StackMapSection; | |||
2076 | for (auto Sec : Obj->sections()) { | |||
2077 | StringRef Name; | |||
2078 | Sec.getName(Name); | |||
2079 | if (Name == ".llvm_stackmaps") { | |||
2080 | StackMapSection = Sec; | |||
2081 | break; | |||
2082 | } | |||
2083 | } | |||
2084 | ||||
2085 | if (StackMapSection == object::SectionRef()) | |||
2086 | return; | |||
2087 | ||||
2088 | StringRef StackMapContents; | |||
2089 | StackMapSection.getContents(StackMapContents); | |||
2090 | ArrayRef<uint8_t> StackMapContentsArray( | |||
2091 | reinterpret_cast<const uint8_t*>(StackMapContents.data()), | |||
2092 | StackMapContents.size()); | |||
2093 | ||||
2094 | if (Obj->isLittleEndian()) | |||
2095 | prettyPrintStackMap( | |||
2096 | llvm::outs(), | |||
2097 | StackMapV1Parser<support::little>(StackMapContentsArray)); | |||
2098 | else | |||
2099 | prettyPrintStackMap(llvm::outs(), | |||
2100 | StackMapV1Parser<support::big>(StackMapContentsArray)); | |||
2101 | } | |||
2102 | ||||
2103 | void llvm::dumpCodeViewMergedTypes( | |||
2104 | ScopedPrinter &Writer, llvm::codeview::MemoryTypeTableBuilder &CVTypes) { | |||
2105 | // Flatten it first, then run our dumper on it. | |||
2106 | ListScope S(Writer, "MergedTypeStream"); | |||
2107 | SmallString<0> Buf; | |||
2108 | CVTypes.ForEachRecord([&](TypeIndex TI, MemoryTypeTableBuilder::Record *R) { | |||
2109 | // The record data doesn't include the 16 bit size. | |||
2110 | Buf.push_back(R->size() & 0xff); | |||
2111 | Buf.push_back((R->size() >> 8) & 0xff); | |||
2112 | Buf.append(R->data(), R->data() + R->size()); | |||
2113 | }); | |||
2114 | CVTypeDumper CVTD(Writer, opts::CodeViewSubsectionBytes); | |||
2115 | ArrayRef<uint8_t> BinaryData(reinterpret_cast<const uint8_t *>(Buf.data()), | |||
2116 | Buf.size()); | |||
2117 | if (!CVTD.dump(BinaryData)) { | |||
2118 | Writer.flush(); | |||
2119 | error(object_error::parse_failed); | |||
2120 | } | |||
2121 | } |