llvm.org GIT mirror llvm / 76ee591
[XCOFF] Implement parsing symbol table for xcoffobjfile and output as yaml format Summary: This patch implement parsing symbol table for xcoffobjfile and output as yaml format. Parsing auxiliary entries of a symbol will be in a separate patch. The XCOFF object file (aix_xcoff.o) used in the test comes from -bash-4.2$ cat test.c extern int i; extern int TestforXcoff; int main() { i++; TestforXcoff--; } Patch by DiggerLin Reviewers: sfertile, hubert.reinterpretcast, MaskRay, daltenty Differential Revision: https://reviews.llvm.org/D61532 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361832 91177308-0d34-0410-b5e6-96231b3b80d8 Jason Liu 2 months ago
9 changed file(s) with 507 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
1212 #ifndef LLVM_BINARYFORMAT_XCOFF_H
1313 #define LLVM_BINARYFORMAT_XCOFF_H
1414
15 #include
16
1517 namespace llvm {
1618 namespace XCOFF {
1719
1820 // Constants used in the XCOFF definition.
19 enum { SectionNameSize = 8 };
21 enum { SectionNameSize = 8, SymbolNameSize = 8 };
22 enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
2023
2124 // Flags for defining the section type. Used for the s_flags field of
2225 // the section header structure. Defined in the system header `scnhdr.h`.
3639 STYP_OVRFLO = 0x8000
3740 };
3841
42 // STORAGE CLASSES, n_sclass field of syment.
43 // The values come from `storclass.h` and `dbxstclass.h`.
44 enum StorageClass : uint8_t {
45 // Storage classes used for symbolic debugging symbols.
46 C_FILE = 103, // File name
47 C_BINCL = 108, // Beginning of include file
48 C_EINCL = 109, // Ending of include file
49 C_GSYM = 128, // Global variable
50 C_STSYM = 133, // Statically allocated symbol
51 C_BCOMM = 135, // Beginning of common block
52 C_ECOMM = 137, // End of common block
53 C_ENTRY = 141, // Alternate entry
54 C_BSTAT = 143, // Beginning of static block
55 C_ESTAT = 144, // End of static block
56 C_GTLS = 145, // Global thread-local variable
57 C_STTLS = 146, // Static thread-local variable
58
59 // Storage classes used for DWARF symbols.
60 C_DWARF = 112, // DWARF section symbol
61
62 // Storage classes used for absolute symbols.
63 C_LSYM = 129, // Automatic variable allocated on stack
64 C_PSYM = 130, // Argument to subroutine allocated on stack
65 C_RSYM = 131, // Register variable
66 C_RPSYM = 132, // Argument to function or procedure stored in register
67 C_ECOML = 136, // Local member of common block
68 C_FUN = 142, // Function or procedure
69
70 // Storage classes used for undefined external symbols or
71 // symbols of general sections.
72 C_EXT = 2, // External symbol
73 C_WEAKEXT = 111, // Weak external symbol
74
75 // Storage classes used for symbols of general sections.
76 C_NULL = 0,
77 C_STAT = 3, // Static
78 C_BLOCK = 100, // ".bb" or ".eb"
79 C_FCN = 101, // ".bf" or ".ef"
80 C_HIDEXT = 107, // Un-named external symbol
81 C_INFO = 110, // Comment string in .info section
82 C_DECL = 140, // Declaration of object (type)
83
84 // Storage classes - Obsolete/Undocumented.
85 C_AUTO = 1, // Automatic variable
86 C_REG = 4, // Register variable
87 C_EXTDEF = 5, // External definition
88 C_LABEL = 6, // Label
89 C_ULABEL = 7, // Undefined label
90 C_MOS = 8, // Member of structure
91 C_ARG = 9, // Function argument
92 C_STRTAG = 10, // Structure tag
93 C_MOU = 11, // Member of union
94 C_UNTAG = 12, // Union tag
95 C_TPDEF = 13, // Type definition
96 C_USTATIC = 14, // Undefined static
97 C_ENTAG = 15, // Enumeration tag
98 C_MOE = 16, // Member of enumeration
99 C_REGPARM = 17, // Register parameter
100 C_FIELD = 18, // Bit field
101 C_EOS = 102, // End of structure
102 C_LINE = 104,
103 C_ALIAS = 105, // Duplicate tag
104 C_HIDDEN = 106, // Special storage class for external
105 C_EFCN = 255, // Physical end of function
106
107 // Storage classes - reserved
108 C_TCSYM = 134 // Reserved
109 };
110
39111 } // end namespace XCOFF
40112 } // end namespace llvm
41113
6060 support::big32_t Flags;
6161 };
6262
63 struct XCOFFSymbolEntry {
64 enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
65 typedef struct {
66 support::big32_t Magic; // Zero indicates name in string table.
67 support::ubig32_t Offset;
68 } NameInStrTblType;
69
70 typedef struct {
71 uint8_t LanguageId;
72 uint8_t CpuTypeId;
73 } CFileLanguageIdAndTypeIdType;
74
75 union {
76 char SymbolName[XCOFF::SymbolNameSize];
77 NameInStrTblType NameInStrTbl;
78 };
79
80 support::ubig32_t Value; // Symbol value; storage class-dependent.
81 support::big16_t SectionNumber;
82
83 union {
84 support::ubig16_t SymbolType;
85 CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
86 };
87
88 XCOFF::StorageClass StorageClass;
89 uint8_t NumberOfAuxEntries;
90 };
91
92 struct XCOFFStringTable {
93 uint32_t Size;
94 const char *Data;
95 };
96
6397 class XCOFFObjectFile : public ObjectFile {
6498 private:
6599 const XCOFFFileHeader *FileHdrPtr = nullptr;
66100 const XCOFFSectionHeader *SectionHdrTablePtr = nullptr;
101 const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
102 XCOFFStringTable StringTable = {0, nullptr};
67103
68104 size_t getFileHeaderSize() const;
69105 size_t getSectionHeaderSize() const;
70106
71107 const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
72
108 static bool isReservedSectionNumber(int16_t SectionNumber);
109 std::error_code getSectionByNum(int16_t Num,
110 const XCOFFSectionHeader *&Result) const;
73111
74112 public:
75113 void moveSymbolNext(DataRefImpl &Symb) const override;
120158 XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
121159
122160 const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
161 const XCOFFSymbolEntry *getPointerToSymbolTable() const {
162 return SymbolTblPtr;
163 }
123164
165 Expected
166 getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
167
168 const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
124169 uint16_t getMagic() const;
125170 uint16_t getNumberOfSections() const;
126 int32_t getTimeStamp() const;
127 uint32_t getSymbolTableOffset() const;
171 int32_t getTimeStamp() const;
172 uint32_t getSymbolTableOffset() const;
128173
129 // Note that this value is signed and might return a negative value. Negative
130 // values are reserved for future use.
131 int32_t getNumberOfSymbolTableEntries() const;
174 // Returns the value as encoded in the object file.
175 // Negative values are reserved for future use.
176 int32_t getRawNumberOfSymbolTableEntries() const;
132177
178 // Returns a sanitized value, useable as an index into the symbol table.
179 uint32_t getLogicalNumberOfSymbolTableEntries() const;
133180 uint16_t getOptionalHeaderSize() const;
134 uint16_t getFlags() const;
181 uint16_t getFlags() const { return FileHdrPtr->Flags; };
135182 }; // XCOFFObjectFile
136183
137184 } // namespace object
1111 #ifndef LLVM_OBJECTYAML_XCOFFYAML_H
1212 #define LLVM_OBJECTYAML_XCOFFYAML_H
1313
14 #include "llvm/BinaryFormat/XCOFF.h"
1415 #include "llvm/ObjectYAML/YAML.h"
15 #include <cstdint>
16 #include <vector>
1617
1718 namespace llvm {
1819 namespace XCOFFYAML {
2728 llvm::yaml::Hex16 Flags;
2829 };
2930
31 struct Symbol {
32 StringRef SymbolName;
33 llvm::yaml::Hex32 Value; // Symbol value; storage class-dependent.
34 StringRef SectionName;
35 llvm::yaml::Hex16 Type;
36 XCOFF::StorageClass StorageClass;
37 uint8_t NumberOfAuxEntries; // Number of auxiliary entries
38 };
39
3040 struct Object {
3141 FileHeader Header;
42 std::vector Symbols;
3243 Object();
3344 };
3445 } // namespace XCOFFYAML
46 } // namespace llvm
47 LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
48 namespace llvm {
49 namespace yaml {
3550
36 namespace yaml {
51 template <> struct ScalarEnumerationTraits {
52 static void enumeration(IO &IO, XCOFF::StorageClass &Value);
53 };
3754
3855 template <> struct MappingTraits {
3956 static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
4360 static void mapping(IO &IO, XCOFFYAML::Object &Obj);
4461 };
4562
63 template <> struct MappingTraits {
64 static void mapping(IO &IO, XCOFFYAML::Symbol &S);
65 };
66
4667 } // namespace yaml
4768 } // namespace llvm
4869
2525 static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
2626 "Wrong size for XCOFF file header.");
2727
28 // Sets EC and returns false if there is less than 'Size' bytes left in the
29 // buffer at 'Offset'.
30 static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Offset,
31 uint64_t Size) {
32 if (M.getBufferSize() < Offset + Size) {
33 EC = object_error::unexpected_eof;
34 return false;
35 }
36 return true;
37 }
38
2839 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
2940 // Returns unexpected_eof on error.
3041 template
4253 return reinterpret_cast(in);
4354 }
4455
56 static StringRef generateStringRef(const char *Name, uint64_t Size) {
57 auto NulCharPtr = static_cast(memchr(Name, '\0', Size));
58 return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
59 : StringRef(Name, Size);
60 }
61
4562 const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
4663 auto Sec = viewAs(Ref.p);
4764 #ifndef NDEBUG
5774 return Sec;
5875 }
5976
77 const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
78 assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
79 auto SymEntPtr = viewAs(Ref.p);
80 return SymEntPtr;
81 }
82
6083 // The next 2 functions are not exactly necessary yet, but they are useful to
6184 // abstract over the size difference between XCOFF32 and XCOFF64 structure
6285 // definitions.
6891 return sizeof(XCOFFSectionHeader);
6992 }
7093
94 uint16_t XCOFFObjectFile::getMagic() const { return FileHdrPtr->Magic; }
95
7196 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
72 llvm_unreachable("Not yet implemented!");
73 return;
97 const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
98
99 SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
100 Symb.p = reinterpret_cast(SymEntPtr);
74101 }
75102
76103 Expected XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
77 StringRef Result;
78 llvm_unreachable("Not yet implemented!");
79 return Result;
104 const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
105
106 if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
107 return generateStringRef(SymEntPtr->SymbolName, XCOFF::SymbolNameSize);
108
109 // A storage class value with the high-order bit on indicates that the name is
110 // a symbolic debugger stabstring.
111 if (SymEntPtr->StorageClass & 0x80)
112 return StringRef("Unimplemented Debug Name");
113
114 uint32_t Offset = SymEntPtr->NameInStrTbl.Offset;
115 // The byte offset is relative to the start of the string table
116 // or .debug section. A byte offset value of 0 is a null or zero-length symbol
117 // name. A byte offset in the range 1 to 3 (inclusive) points into the length
118 // field; as a soft-error recovery mechanism, we treat such cases as having an
119 // offset of 0.
120 if (Offset < 4)
121 return StringRef(nullptr, 0);
122
123 if (StringTable.Data != nullptr && StringTable.Size > Offset)
124 return (StringTable.Data + Offset);
125
126 return make_error("Symbol Name parse failed",
127 object_error::parse_failed);
80128 }
81129
82130 Expected XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
86134 }
87135
88136 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
89 uint64_t Result = 0;
90 llvm_unreachable("Not yet implemented!");
91 return Result;
137 return toSymbolEntry(Symb)->Value;
92138 }
93139
94140 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
105151
106152 Expected
107153 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
108 llvm_unreachable("Not yet implemented!");
109 return section_iterator(SectionRef());
154 const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
155 int16_t SectNum = SymEntPtr->SectionNumber;
156
157 if (isReservedSectionNumber(SectNum))
158 return section_end();
159
160 const XCOFFSectionHeader *Sec;
161 if (std::error_code EC = getSectionByNum(SectNum, Sec))
162 return errorCodeToError(EC);
163
164 DataRefImpl SecDRI;
165 SecDRI.p = reinterpret_cast(Sec);
166
167 return section_iterator(SectionRef(SecDRI, this));
110168 }
111169
112170 void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
218276 }
219277
220278 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
221 llvm_unreachable("Not yet implemented!");
222 return basic_symbol_iterator(SymbolRef());
279 DataRefImpl SymDRI;
280 SymDRI.p = reinterpret_cast(SymbolTblPtr);
281 return basic_symbol_iterator(SymbolRef(SymDRI, this));
223282 }
224283
225284 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
226 llvm_unreachable("Not yet implemented!");
227 return basic_symbol_iterator(SymbolRef());
285 DataRefImpl SymDRI;
286 SymDRI.p = reinterpret_cast(
287 SymbolTblPtr + getLogicalNumberOfSymbolTableEntries());
288 return basic_symbol_iterator(SymbolRef(SymDRI, this));
228289 }
229290
230291 section_iterator XCOFFObjectFile::section_begin() const {
242303
243304 uint8_t XCOFFObjectFile::getBytesInAddress() const {
244305 // Only support 32-bit object files for now ...
245 assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
306 assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
246307 return 4;
247308 }
248309
273334 return 0;
274335 }
275336
337 std::error_code
338 XCOFFObjectFile::getSectionByNum(int16_t Num,
339 const XCOFFSectionHeader *&Result) const {
340 if (Num > 0 && static_cast(Num) <= getNumberOfSections()) {
341 Result = SectionHdrTablePtr + (Num - 1);
342 return std::error_code();
343 }
344
345 return object_error::invalid_section_index;
346 }
347
348 Expected
349 XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
350 int16_t SectionNum = SymEntPtr->SectionNumber;
351
352 switch (SectionNum) {
353 case XCOFF::N_DEBUG:
354 return "N_DEBUG";
355 case XCOFF::N_ABS:
356 return "N_ABS";
357 case XCOFF::N_UNDEF:
358 return "N_UNDEF";
359 default: {
360 const XCOFFSectionHeader *SectHeaderPtr;
361 std::error_code EC;
362 if ((EC = getSectionByNum(SectionNum, SectHeaderPtr)))
363 return errorCodeToError(EC);
364 else
365 return generateStringRef(SectHeaderPtr->Name, XCOFF::SectionNameSize);
366 }
367 }
368 }
369
370 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
371 return (SectionNumber <= 0 && SectionNumber >= -2);
372 }
373
374 uint16_t XCOFFObjectFile::getNumberOfSections() const {
375 return FileHdrPtr->NumberOfSections;
376 }
377
378 int32_t XCOFFObjectFile::getTimeStamp() const { return FileHdrPtr->TimeStamp; }
379
380 uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
381 return FileHdrPtr->SymbolTableOffset;
382 }
383
384 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries() const {
385 return FileHdrPtr->NumberOfSymTableEntries;
386 }
387
388 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries() const {
389 return (FileHdrPtr->NumberOfSymTableEntries >= 0
390 ? FileHdrPtr->NumberOfSymTableEntries
391 : 0);
392 }
393
394 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
395 return FileHdrPtr->AuxHeaderSize;
396 }
397
276398 XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
277399 : ObjectFile(Binary::ID_XCOFF32, Object) {
278400
292414 getNumberOfSections() * getSectionHeaderSize())))
293415 return;
294416 }
295 }
296
297 uint16_t XCOFFObjectFile::getMagic() const {
298 return FileHdrPtr->Magic;
299 }
300
301 uint16_t XCOFFObjectFile::getNumberOfSections() const {
302 return FileHdrPtr->NumberOfSections;
303 }
304
305 int32_t XCOFFObjectFile::getTimeStamp() const {
306 return FileHdrPtr->TimeStamp;
307 }
308
309 uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
310 return FileHdrPtr->SymbolTableOffset;
311 }
312
313 int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
314 // As far as symbol table size is concerned, if this field is negative it is
315 // to be treated as a 0. However since this field is also used for printing we
316 // don't want to truncate any negative values.
317 return FileHdrPtr->NumberOfSymTableEntries;
318 }
319
320 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
321 return FileHdrPtr->AuxHeaderSize;
322 }
323
324 uint16_t XCOFFObjectFile::getFlags() const {
325 return FileHdrPtr->Flags;
417
418 if (getLogicalNumberOfSymbolTableEntries() == 0)
419 return;
420
421 // Get pointer to the symbol table.
422 CurPtr = FileHdrPtr->SymbolTableOffset;
423 uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
424 getLogicalNumberOfSymbolTableEntries();
425
426 if ((EC = getObject(SymbolTblPtr, Data, base() + CurPtr, SymbolTableSize)))
427 return;
428
429 // Move pointer to the string table.
430 CurPtr += SymbolTableSize;
431
432 if (CurPtr + 4 > Data.getBufferSize())
433 return;
434
435 StringTable.Size = support::endian::read32be(base() + CurPtr);
436
437 if (StringTable.Size <= 4)
438 return;
439
440 // Check for whether the String table has the size indicated by length
441 // field
442 if (!checkSize(Data, EC, CurPtr, StringTable.Size))
443 return;
444
445 StringTable.Data = reinterpret_cast(base() + CurPtr);
446 if (StringTable.Data[StringTable.Size - 1] != '\0') {
447 EC = object_error::string_table_non_null_end;
448 return;
449 }
326450 }
327451
328452 Expected>
1010 //===----------------------------------------------------------------------===//
1111
1212 #include "llvm/ObjectYAML/XCOFFYAML.h"
13 #include "llvm/BinaryFormat/XCOFF.h"
1314 #include
1415
1516 namespace llvm {
2021 } // namespace XCOFFYAML
2122
2223 namespace yaml {
24
25 void ScalarEnumerationTraits::enumeration(
26 IO &IO, XCOFF::StorageClass &Value) {
27 #define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
28 ECase(C_NULL);
29 ECase(C_AUTO);
30 ECase(C_EXT);
31 ECase(C_STAT);
32 ECase(C_REG);
33 ECase(C_EXTDEF);
34 ECase(C_LABEL);
35 ECase(C_ULABEL);
36 ECase(C_MOS);
37 ECase(C_ARG);
38 ECase(C_STRTAG);
39 ECase(C_MOU);
40 ECase(C_UNTAG);
41 ECase(C_TPDEF);
42 ECase(C_USTATIC);
43 ECase(C_ENTAG);
44 ECase(C_MOE);
45 ECase(C_REGPARM);
46 ECase(C_FIELD);
47 ECase(C_BLOCK);
48 ECase(C_FCN);
49 ECase(C_EOS);
50 ECase(C_FILE);
51 ECase(C_LINE);
52 ECase(C_ALIAS);
53 ECase(C_HIDDEN);
54 ECase(C_HIDEXT);
55 ECase(C_BINCL);
56 ECase(C_EINCL);
57 ECase(C_INFO);
58 ECase(C_WEAKEXT);
59 ECase(C_DWARF);
60 ECase(C_GSYM);
61 ECase(C_LSYM);
62 ECase(C_PSYM);
63 ECase(C_RSYM);
64 ECase(C_RPSYM);
65 ECase(C_STSYM);
66 ECase(C_TCSYM);
67 ECase(C_BCOMM);
68 ECase(C_ECOML);
69 ECase(C_ECOMM);
70 ECase(C_DECL);
71 ECase(C_ENTRY);
72 ECase(C_FUN);
73 ECase(C_BSTAT);
74 ECase(C_ESTAT);
75 ECase(C_GTLS);
76 ECase(C_STTLS);
77 ECase(C_EFCN);
78 #undef ECase
79 }
2380
2481 void MappingTraits::mapping(
2582 IO &IO, XCOFFYAML::FileHeader &FileHdr) {
3289 IO.mapRequired("Flags", FileHdr.Flags);
3390 }
3491
92 void MappingTraits::mapping(IO &IO, XCOFFYAML::Symbol &S) {
93 IO.mapRequired("Name", S.SymbolName);
94 IO.mapRequired("Value", S.Value);
95 IO.mapRequired("Section", S.SectionName);
96 IO.mapRequired("Type", S.Type);
97 IO.mapRequired("StorageClass", S.StorageClass);
98 IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
99 }
100
35101 void MappingTraits::mapping(IO &IO, XCOFFYAML::Object &Obj) {
36102 IO.mapTag("!XCOFF", true);
37103 IO.mapRequired("FileHeader", Obj.Header);
104 IO.mapRequired("Symbols", Obj.Symbols);
38105 }
39106
40107 } // namespace yaml
11 # Test that we can parse the XCOFF object file correctly.
22 # CHECK: --- !XCOFF
33 # CHECK-NEXT: FileHeader:
4 # CHECK-NEXT: MagicNumber: 0x01DF
5 # CHECK-NEXT: NumberOfSections: 2
6 # CHECK-NEXT: CreationTime: 1548692020
7 # CHECK-NEXT: OffsetToSymbolTable: 0x00000108
8 # CHECK-NEXT: EntriesInSymbolTable: 18
9 # CHECK-NEXT: AuxiliaryHeaderSize: 0
10 # CHECK-NEXT: Flags: 0x0000
4 # CHECK-NEXT: MagicNumber: 0x01DF
5 # CHECK-NEXT: NumberOfSections: 2
6 # CHECK-NEXT: CreationTime: 1552337792
7 # CHECK-NEXT: OffsetToSymbolTable: 0x0000013A
8 # CHECK-NEXT: EntriesInSymbolTable: 22
9 # CHECK-NEXT: AuxiliaryHeaderSize: 0
10 # CHECK-NEXT: Flags: 0x0000
11
12 # CHECK: Symbols:
13 # CHECK-NEXT: - Name: .file
14 # CHECK-NEXT: Value: 0x00000000
15 # CHECK-NEXT: Section: N_DEBUG
16 # CHECK-NEXT: Type: 0x0003
17 # CHECK-NEXT: StorageClass: C_FILE
18 # CHECK-NEXT: NumberOfAuxEntries: 1
19 # CHECK-NEXT: - Name: i
20 # CHECK-NEXT: Value: 0x00000000
21 # CHECK-NEXT: Section: N_UNDEF
22 # CHECK-NEXT: Type: 0x0000
23 # CHECK-NEXT: StorageClass: C_EXT
24 # CHECK-NEXT: NumberOfAuxEntries: 1
25 # CHECK-NEXT: - Name: TestforXcoff
26 # CHECK-NEXT: Value: 0x00000000
27 # CHECK-NEXT: Section: N_UNDEF
28 # CHECK-NEXT: Type: 0x0000
29 # CHECK-NEXT: StorageClass: C_EXT
30 # CHECK-NEXT: NumberOfAuxEntries: 1
31 # CHECK-NEXT: - Name: .text
32 # CHECK-NEXT: Value: 0x00000000
33 # CHECK-NEXT: Section: .text
34 # CHECK-NEXT: Type: 0x0000
35 # CHECK-NEXT: StorageClass: C_HIDEXT
36 # CHECK-NEXT: NumberOfAuxEntries: 1
37 # CHECK-NEXT: - Name: .main
38 # CHECK-NEXT: Value: 0x00000000
39 # CHECK-NEXT: Section: .text
40 # CHECK-NEXT: Type: 0x0000
41 # CHECK-NEXT: StorageClass: C_EXT
42 # CHECK-NEXT: NumberOfAuxEntries: 1
43 # CHECK-NEXT: - Name: main
44 # CHECK-NEXT: Value: 0x00000060
45 # CHECK-NEXT: Section: .data
46 # CHECK-NEXT: Type: 0x0000
47 # CHECK-NEXT: StorageClass: C_HIDEXT
48 # CHECK-NEXT: NumberOfAuxEntries: 1
49 # CHECK-NEXT: - Name: main
50 # CHECK-NEXT: Value: 0x00000060
51 # CHECK-NEXT: Section: .data
52 # CHECK-NEXT: Type: 0x0000
53 # CHECK-NEXT: StorageClass: C_EXT
54 # CHECK-NEXT: NumberOfAuxEntries: 1
55 # CHECK-NEXT: - Name: .data
56 # CHECK-NEXT: Value: 0x00000070
57 # CHECK-NEXT: Section: .data
58 # CHECK-NEXT: Type: 0x0000
59 # CHECK-NEXT: StorageClass: C_HIDEXT
60 # CHECK-NEXT: NumberOfAuxEntries: 1
61 # CHECK-NEXT: - Name: TOC
62 # CHECK-NEXT: Value: 0x00000074
63 # CHECK-NEXT: Section: .data
64 # CHECK-NEXT: Type: 0x0000
65 # CHECK-NEXT: StorageClass: C_HIDEXT
66 # CHECK-NEXT: NumberOfAuxEntries: 1
67 # CHECK-NEXT: - Name: i
68 # CHECK-NEXT: Value: 0x00000074
69 # CHECK-NEXT: Section: .data
70 # CHECK-NEXT: Type: 0x0000
71 # CHECK-NEXT: StorageClass: C_HIDEXT
72 # CHECK-NEXT: NumberOfAuxEntries: 1
73 # CHECK-NEXT: - Name: TestforXcoff
74 # CHECK-NEXT: Value: 0x00000078
75 # CHECK-NEXT: Section: .data
76 # CHECK-NEXT: Type: 0x0000
77 # CHECK-NEXT: StorageClass: C_HIDEXT
78 # CHECK-NEXT: NumberOfAuxEntries: 1
79 # CHECK-NEXT: ...
6565 }
6666
6767 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset());
68 int32_t SymTabEntries = Obj.getNumberOfSymbolTableEntries();
68 int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries();
6969 if (SymTabEntries >= 0)
7070 W.printNumber("SymbolTableEntries", SymTabEntries);
7171 else
1818 const object::XCOFFObjectFile &Obj;
1919 XCOFFYAML::Object YAMLObj;
2020 void dumpHeader();
21 std::error_code dumpSymbols();
2122
2223 public:
23 XCOFFDumper(const object::XCOFFObjectFile &obj);
24 XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
25 std::error_code dump();
2426 XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
2527 };
2628 } // namespace
2729
28 XCOFFDumper::XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {
30 std::error_code XCOFFDumper::dump() {
31 std::error_code EC;
2932 dumpHeader();
33 EC = dumpSymbols();
34 return EC;
3035 }
3136
3237 void XCOFFDumper::dumpHeader() {
4146 YAMLObj.Header.Flags = FileHdrPtr->Flags;
4247 }
4348
49 std::error_code XCOFFDumper::dumpSymbols() {
50 std::vector &Symbols = YAMLObj.Symbols;
51
52 for (const SymbolRef &S : Obj.symbols()) {
53 DataRefImpl SymbolDRI = S.getRawDataRefImpl();
54 const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
55 XCOFFYAML::Symbol Sym;
56
57 Expected SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
58 if (!SymNameRefOrErr) {
59 return errorToErrorCode(SymNameRefOrErr.takeError());
60 }
61 Sym.SymbolName = SymNameRefOrErr.get();
62
63 Sym.Value = SymbolEntPtr->Value;
64
65 Expected SectionNameRefOrErr =
66 Obj.getSymbolSectionName(SymbolEntPtr);
67 if (!SectionNameRefOrErr)
68 return errorToErrorCode(SectionNameRefOrErr.takeError());
69
70 Sym.SectionName = SectionNameRefOrErr.get();
71
72 Sym.Type = SymbolEntPtr->SymbolType;
73 Sym.StorageClass = SymbolEntPtr->StorageClass;
74 Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
75 Symbols.push_back(Sym);
76 }
77
78 return std::error_code();
79 }
80
4481 std::error_code xcoff2yaml(raw_ostream &Out,
4582 const object::XCOFFObjectFile &Obj) {
4683 XCOFFDumper Dumper(Obj);
84
85 if (std::error_code EC = Dumper.dump())
86 return EC;
87
4788 yaml::Output Yout(Out);
4889 Yout << Dumper.getYAMLObj();
4990