llvm.org GIT mirror llvm / 785cf2e
[Object][XCOFF] Add support for 64-bit file header and section header dumping. Adds a readobj dumper for 32-bit and 64-bit section header tables, and extend support for the file-header dumping to include 64-bit object files. Also refactors the binary file parsing to be done in a helper function in an attempt to cleanup error handeling. Differential Revision: https://reviews.llvm.org/D63843 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365524 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Fertile a month ago
14 changed file(s) with 660 addition(s) and 214 deletion(s). Raw diff Collapse all Expand all
4545 pecoff_executable, ///< PECOFF executable file
4646 windows_resource, ///< Windows compiled resource file (.res)
4747 xcoff_object_32, ///< 32-bit XCOFF object file
48 xcoff_object_64, ///< 64-bit XCOFF object file
4849 wasm_object, ///< WebAssembly Object file
4950 pdb, ///< Windows PDB debug info file
5051 };
5050 // Object and children.
5151 ID_StartObjects,
5252 ID_COFF,
53
5354 ID_XCOFF32, // AIX XCOFF 32-bit
55 ID_XCOFF64, // AIX XCOFF 64-bit
5456
5557 ID_ELF32L, // ELF 32-bit, little endian
5658 ID_ELF32B, // ELF 32-bit, big endian
120122 return TypeID == ID_COFF;
121123 }
122124
123 bool isXCOFF() const { return TypeID == ID_XCOFF32; }
125 bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
124126
125127 bool isWasm() const { return TypeID == ID_Wasm; }
126128
358358 createCOFFObjectFile(MemoryBufferRef Object);
359359
360360 static Expected>
361 createXCOFFObjectFile(MemoryBufferRef Object);
361 createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
362362
363363 static Expected>
364364 createELFObjectFile(MemoryBufferRef Object);
3333 namespace llvm {
3434 namespace object {
3535
36 struct XCOFFFileHeader {
36 struct XCOFFFileHeader32 {
3737 support::ubig16_t Magic;
3838 support::ubig16_t NumberOfSections;
3939
4747 support::ubig16_t Flags;
4848 };
4949
50 struct XCOFFSectionHeader {
50 struct XCOFFFileHeader64 {
51 support::ubig16_t Magic;
52 support::ubig16_t NumberOfSections;
53
54 // Unix time value, value of 0 indicates no timestamp.
55 // Negative values are reserved.
56 support::big32_t TimeStamp;
57
58 support::ubig64_t SymbolTableOffset; // File offset to symbol table.
59 support::ubig16_t AuxHeaderSize;
60 support::ubig16_t Flags;
61 support::ubig32_t NumberOfSymTableEntries;
62 };
63
64 struct XCOFFSectionHeader32 {
5165 char Name[XCOFF::SectionNameSize];
5266 support::ubig32_t PhysicalAddress;
5367 support::ubig32_t VirtualAddress;
5872 support::ubig16_t NumberOfRelocations;
5973 support::ubig16_t NumberOfLineNumbers;
6074 support::big32_t Flags;
75
76 StringRef getName() const;
77 };
78
79 struct XCOFFSectionHeader64 {
80 char Name[XCOFF::SectionNameSize];
81 support::ubig64_t PhysicalAddress;
82 support::ubig64_t VirtualAddress;
83 support::ubig64_t SectionSize;
84 support::big64_t FileOffsetToRawData;
85 support::big64_t FileOffsetToRelocationInfo;
86 support::big64_t FileOffsetToLineNumberInfo;
87 support::ubig32_t NumberOfRelocations;
88 support::ubig32_t NumberOfLineNumbers;
89 support::big32_t Flags;
90 char Padding[4];
91
92 StringRef getName() const;
6193 };
6294
6395 struct XCOFFSymbolEntry {
96128
97129 class XCOFFObjectFile : public ObjectFile {
98130 private:
99 const XCOFFFileHeader *FileHdrPtr = nullptr;
100 const XCOFFSectionHeader *SectionHdrTablePtr = nullptr;
131 const void *FileHeader = nullptr;
132 const void *SectionHeaderTable = nullptr;
133
101134 const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
102135 XCOFFStringTable StringTable = {0, nullptr};
103136
137 const XCOFFFileHeader32 *fileHeader32() const;
138 const XCOFFFileHeader64 *fileHeader64() const;
139
140 const XCOFFSectionHeader32 *sectionHeaderTable32() const;
141 const XCOFFSectionHeader64 *sectionHeaderTable64() const;
142
104143 size_t getFileHeaderSize() const;
105144 size_t getSectionHeaderSize() const;
106145
107 const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
146 const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
147 const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
148 void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
149 uintptr_t getSectionHeaderTableAddress() const;
150
151 // This returns a pointer to the start of the storage for the name field of
152 // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
153 // null-terminated.
154 const char *getSectionNameInternal(DataRefImpl Sec) const;
155
156 int32_t getSectionFlags(DataRefImpl Sec) const;
157
108158 static bool isReservedSectionNumber(int16_t SectionNumber);
109 std::error_code getSectionByNum(int16_t Num,
110 const XCOFFSectionHeader *&Result) const;
159 Expected getSectionByNum(int16_t Num) const;
160
161 // Constructor and "create" factory function. The constructor is only a thin
162 // wrapper around the base constructor. The "create" function fills out the
163 // XCOFF-specific information and performs the error checking along the way.
164 XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
165 static Expected> create(unsigned Type,
166 MemoryBufferRef MBR);
167
168 // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
169 // and an XCOFFStringTable if parsing succeeded.
170 static Expected parseStringTable(const XCOFFObjectFile *Obj,
171 uint64_t Offset);
172
173 // Make a friend so it can call the private 'create' function.
174 friend Expected>
175 ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
111176
112177 public:
178 // Interface inherited from base classes.
113179 void moveSymbolNext(DataRefImpl &Symb) const override;
114180 uint32_t getSymbolFlags(DataRefImpl Symb) const override;
115181 basic_symbol_iterator symbol_begin() const override;
155221 Expected getStartAddress() const override;
156222 bool isRelocatableObject() const override;
157223
158 XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
159
160 const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
224 // Below here is the non-inherited interface.
225 bool is64Bit() const;
226
161227 const XCOFFSymbolEntry *getPointerToSymbolTable() const {
228 assert(!is64Bit() && "Symbol table handling not supported yet.");
162229 return SymbolTblPtr;
163230 }
164231
166233 getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
167234
168235 const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
236
237 // File header related interfaces.
169238 uint16_t getMagic() const;
170239 uint16_t getNumberOfSections() const;
171240 int32_t getTimeStamp() const;
172 uint32_t getSymbolTableOffset() const;
173
174 // Returns the value as encoded in the object file.
175 // Negative values are reserved for future use.
176 int32_t getRawNumberOfSymbolTableEntries() const;
177
178 // Returns a sanitized value, useable as an index into the symbol table.
179 uint32_t getLogicalNumberOfSymbolTableEntries() const;
241
242 // Symbol table offset and entry count are handled differently between
243 // XCOFF32 and XCOFF64.
244 uint32_t getSymbolTableOffset32() const;
245 uint64_t getSymbolTableOffset64() const;
246
247 // Note that this value is signed and might return a negative value. Negative
248 // values are reserved for future use.
249 int32_t getRawNumberOfSymbolTableEntries32() const;
250
251 // The sanitized value appropriate to use as an index into the symbol table.
252 uint32_t getLogicalNumberOfSymbolTableEntries32() const;
253
254 uint32_t getNumberOfSymbolTableEntries64() const;
255
180256 uint16_t getOptionalHeaderSize() const;
181 uint16_t getFlags() const { return FileHdrPtr->Flags; };
257 uint16_t getFlags() const;
258
259 // Section header table related interfaces.
260 ArrayRef sections32() const;
261 ArrayRef sections64() const;
182262 }; // XCOFFObjectFile
183263
184264 } // namespace object
6565 // XCOFF format
6666 if (startswith(Magic, "\x01\xDF"))
6767 return file_magic::xcoff_object_32;
68 if (startswith(Magic, "\x01\xF7"))
69 return file_magic::xcoff_object_64;
6870 break;
6971
7072 case 0xDE: // 0x0B17C0DE = BC wraper
6969 case file_magic::pecoff_executable:
7070 case file_magic::bitcode:
7171 case file_magic::xcoff_object_32:
72 case file_magic::xcoff_object_64:
7273 case file_magic::wasm_object:
7374 return ObjectFile::createSymbolicFile(Buffer, Type, Context);
7475 case file_magic::macho_universal_binary:
149149 case file_magic::pecoff_executable:
150150 return createCOFFObjectFile(Object);
151151 case file_magic::xcoff_object_32:
152 return createXCOFFObjectFile(Object);
152 return createXCOFFObjectFile(Object, Binary::ID_XCOFF32);
153 case file_magic::xcoff_object_64:
154 return createXCOFFObjectFile(Object, Binary::ID_XCOFF64);
153155 case file_magic::wasm_object:
154156 return createWasmObjectFile(Object);
155157 }
6969 case file_magic::macho_kext_bundle:
7070 case file_magic::pecoff_executable:
7171 case file_magic::xcoff_object_32:
72 case file_magic::xcoff_object_64:
7273 case file_magic::wasm_object:
7374 return ObjectFile::createObjectFile(Object, Type);
7475 case file_magic::coff_import_library:
2121 namespace llvm {
2222 namespace object {
2323
24 enum { XCOFF32FileHeaderSize = 20 };
25 static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
26 "Wrong size for XCOFF file header.");
27
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
39 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
40 // Returns unexpected_eof on error.
24 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
25 // 'M'. Returns a pointer to the underlying object on success.
4126 template
42 static std::error_code getObject(const T *&Obj, MemoryBufferRef M,
43 const void *Ptr,
44 const uint64_t Size = sizeof(T)) {
27 static Expected getObject(MemoryBufferRef M, const void *Ptr,
28 const uint64_t Size = sizeof(T)) {
4529 uintptr_t Addr = uintptr_t(Ptr);
4630 if (std::error_code EC = Binary::checkOffset(M, Addr, Size))
47 return EC;
48 Obj = reinterpret_cast(Addr);
49 return std::error_code();
31 return errorCodeToError(EC);
32 return reinterpret_cast(Addr);
33 }
34
35 static uintptr_t getWithOffset(uintptr_t Base, ptrdiff_t Offset) {
36 return reinterpret_cast(reinterpret_cast(Base) +
37 Offset);
5038 }
5139
5240 template static const T *viewAs(uintptr_t in) {
5947 : StringRef(Name, Size);
6048 }
6149
62 const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
63 auto Sec = viewAs(Ref.p);
64 #ifndef NDEBUG
65 if (Sec < SectionHdrTablePtr ||
66 Sec >= (SectionHdrTablePtr + getNumberOfSections()))
50 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
51 uintptr_t TableAddress) const {
52 if (Addr < TableAddress)
6753 report_fatal_error("Section header outside of section header table.");
6854
69 uintptr_t Offset = uintptr_t(Sec) - uintptr_t(SectionHdrTablePtr);
55 uintptr_t Offset = Addr - TableAddress;
56 if (Offset >= getSectionHeaderSize() * getNumberOfSections())
57 report_fatal_error("Section header outside of section header table.");
58
7059 if (Offset % getSectionHeaderSize() != 0)
7160 report_fatal_error(
7261 "Section header pointer does not point to a valid section header.");
62 }
63
64 const XCOFFSectionHeader32 *
65 XCOFFObjectFile::toSection32(DataRefImpl Ref) const {
66 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
67 #ifndef NDEBUG
68 checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
7369 #endif
74 return Sec;
70 return viewAs(Ref.p);
71 }
72
73 const XCOFFSectionHeader64 *
74 XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
75 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
76 #ifndef NDEBUG
77 checkSectionAddress(Ref.p, getSectionHeaderTableAddress());
78 #endif
79 return viewAs(Ref.p);
7580 }
7681
7782 const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
83 assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
7884 assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
7985 auto SymEntPtr = viewAs(Ref.p);
8086 return SymEntPtr;
8187 }
8288
83 // The next 2 functions are not exactly necessary yet, but they are useful to
84 // abstract over the size difference between XCOFF32 and XCOFF64 structure
85 // definitions.
86 size_t XCOFFObjectFile::getFileHeaderSize() const {
87 return sizeof(XCOFFFileHeader);
88 }
89
90 size_t XCOFFObjectFile::getSectionHeaderSize() const {
91 return sizeof(XCOFFSectionHeader);
92 }
93
94 uint16_t XCOFFObjectFile::getMagic() const { return FileHdrPtr->Magic; }
89 const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
90 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
91 return static_cast(FileHeader);
92 }
93
94 const XCOFFFileHeader64 *XCOFFObjectFile::fileHeader64() const {
95 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
96 return static_cast(FileHeader);
97 }
98
99 const XCOFFSectionHeader32 *
100 XCOFFObjectFile::sectionHeaderTable32() const {
101 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
102 return static_cast(SectionHeaderTable);
103 }
104
105 const XCOFFSectionHeader64 *
106 XCOFFObjectFile::sectionHeaderTable64() const {
107 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
108 return static_cast(SectionHeaderTable);
109 }
95110
96111 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
97112 const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
98
99113 SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
100114 Symb.p = reinterpret_cast(SymEntPtr);
101115 }
157171 if (isReservedSectionNumber(SectNum))
158172 return section_end();
159173
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));
174 Expected ExpSec = getSectionByNum(SectNum);
175 if (!ExpSec)
176 return ExpSec.takeError();
177
178 return section_iterator(SectionRef(ExpSec.get(), this));
168179 }
169180
170181 void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
173184 }
174185
175186 Expected XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
176 const char *Name = toSection(Sec)->Name;
177 auto NulCharPtr =
178 static_cast(memchr(Name, '\0', XCOFF::SectionNameSize));
179 return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
180 : StringRef(Name, XCOFF::SectionNameSize);
187 return generateStringRef(getSectionNameInternal(Sec), XCOFF::SectionNameSize);
181188 }
182189
183190 uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
184 return toSection(Sec)->VirtualAddress;
191 return is64Bit() ? toSection64(Sec)->VirtualAddress
192 : toSection32(Sec)->VirtualAddress;
185193 }
186194
187195 uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const {
188196 // Section numbers in XCOFF are numbered beginning at 1. A section number of
189197 // zero is used to indicate that a symbol is being imported or is undefined.
190 return toSection(Sec) - SectionHdrTablePtr + 1;
198 if (is64Bit())
199 return toSection64(Sec) - sectionHeaderTable64() + 1;
200 else
201 return toSection32(Sec) - sectionHeaderTable32() + 1;
191202 }
192203
193204 uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const {
194 return toSection(Sec)->SectionSize;
205 return is64Bit() ? toSection64(Sec)->SectionSize
206 : toSection32(Sec)->SectionSize;
195207 }
196208
197209 Expected>
212224 }
213225
214226 bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
215 return toSection(Sec)->Flags & XCOFF::STYP_TEXT;
227 return getSectionFlags(Sec) & XCOFF::STYP_TEXT;
216228 }
217229
218230 bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
219 unsigned Flags = toSection(Sec)->Flags;
231 uint32_t Flags = getSectionFlags(Sec);
220232 return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
221233 }
222234
223235 bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
224 unsigned Flags = toSection(Sec)->Flags;
236 uint32_t Flags = getSectionFlags(Sec);
225237 return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
226238 }
227239
276288 }
277289
278290 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
291 assert(!is64Bit() && "64-bit support not implemented yet.");
279292 DataRefImpl SymDRI;
280293 SymDRI.p = reinterpret_cast(SymbolTblPtr);
281294 return basic_symbol_iterator(SymbolRef(SymDRI, this));
282295 }
283296
284297 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
298 assert(!is64Bit() && "64-bit support not implemented yet.");
285299 DataRefImpl SymDRI;
286300 SymDRI.p = reinterpret_cast(
287 SymbolTblPtr + getLogicalNumberOfSymbolTableEntries());
301 SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
288302 return basic_symbol_iterator(SymbolRef(SymDRI, this));
289303 }
290304
291305 section_iterator XCOFFObjectFile::section_begin() const {
292306 DataRefImpl DRI;
293 DRI.p = reinterpret_cast(SectionHdrTablePtr);
307 DRI.p = getSectionHeaderTableAddress();
294308 return section_iterator(SectionRef(DRI, this));
295309 }
296310
297311 section_iterator XCOFFObjectFile::section_end() const {
298312 DataRefImpl DRI;
299 DRI.p =
300 reinterpret_cast(SectionHdrTablePtr + getNumberOfSections());
313 DRI.p = getWithOffset(getSectionHeaderTableAddress(),
314 getNumberOfSections() * getSectionHeaderSize());
301315 return section_iterator(SectionRef(DRI, this));
302316 }
303317
304 uint8_t XCOFFObjectFile::getBytesInAddress() const {
305 // Only support 32-bit object files for now ...
306 assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
307 return 4;
308 }
318 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
309319
310320 StringRef XCOFFObjectFile::getFileFormatName() const {
311 assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
312 return "aixcoff-rs6000";
321 return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
313322 }
314323
315324 Triple::ArchType XCOFFObjectFile::getArch() const {
316 assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
317 return Triple::ppc;
325 return is64Bit() ? Triple::ppc64 : Triple::ppc;
318326 }
319327
320328 SubtargetFeatures XCOFFObjectFile::getFeatures() const {
334342 return 0;
335343 }
336344
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;
345 size_t XCOFFObjectFile::getFileHeaderSize() const {
346 return is64Bit() ? sizeof(XCOFFFileHeader64) : sizeof(XCOFFFileHeader32);
347 }
348
349 size_t XCOFFObjectFile::getSectionHeaderSize() const {
350 return is64Bit() ? sizeof(XCOFFSectionHeader64) :
351 sizeof(XCOFFSectionHeader32);
352 }
353
354 bool XCOFFObjectFile::is64Bit() const {
355 return Binary::ID_XCOFF64 == getType();
356 }
357
358 uint16_t XCOFFObjectFile::getMagic() const {
359 return is64Bit() ? fileHeader64()->Magic : fileHeader32()->Magic;
360 }
361
362 Expected XCOFFObjectFile::getSectionByNum(int16_t Num) const {
363 if (Num <= 0 || Num > getNumberOfSections())
364 return errorCodeToError(object_error::invalid_section_index);
365
366 DataRefImpl DRI;
367 DRI.p = getWithOffset(getSectionHeaderTableAddress(),
368 getSectionHeaderSize() * (Num - 1));
369 return DRI;
346370 }
347371
348372 Expected
349373 XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
374 assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
350375 int16_t SectionNum = SymEntPtr->SectionNumber;
351376
352377 switch (SectionNum) {
356381 return "N_ABS";
357382 case XCOFF::N_UNDEF:
358383 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 }
384 default:
385 Expected SecRef = getSectionByNum(SectionNum);
386 if (SecRef)
387 return generateStringRef(getSectionNameInternal(SecRef.get()),
388 XCOFF::SectionNameSize);
389 return SecRef.takeError();
367390 }
368391 }
369392
372395 }
373396
374397 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
398 return is64Bit() ? fileHeader64()->NumberOfSections
399 : fileHeader32()->NumberOfSections;
400 }
401
402 int32_t XCOFFObjectFile::getTimeStamp() const {
403 return is64Bit() ? fileHeader64()->TimeStamp : fileHeader32()->TimeStamp;
404 }
405
406 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
407 return is64Bit() ? fileHeader64()->AuxHeaderSize
408 : fileHeader32()->AuxHeaderSize;
409 }
410
411 uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
412 return fileHeader32()->SymbolTableOffset;
413 }
414
415 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
416 // As far as symbol table size is concerned, if this field is negative it is
417 // to be treated as a 0. However since this field is also used for printing we
418 // don't want to truncate any negative values.
419 return fileHeader32()->NumberOfSymTableEntries;
420 }
421
422 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
423 return (fileHeader32()->NumberOfSymTableEntries >= 0
424 ? fileHeader32()->NumberOfSymTableEntries
391425 : 0);
392426 }
393427
394 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
395 return FileHdrPtr->AuxHeaderSize;
396 }
397
398 XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
399 : ObjectFile(Binary::ID_XCOFF32, Object) {
400
401 // Current location within the file.
402 uint64_t CurPtr = 0;
403
404 if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr)))
405 return;
406
407 CurPtr += getFileHeaderSize();
428 uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
429 return fileHeader64()->SymbolTableOffset;
430 }
431
432 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
433 return fileHeader64()->NumberOfSymTableEntries;
434 }
435
436 uint16_t XCOFFObjectFile::getFlags() const {
437 return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
438 }
439
440 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec) const {
441 return is64Bit() ? toSection64(Sec)->Name : toSection32(Sec)->Name;
442 }
443
444 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
445 return reinterpret_cast(SectionHeaderTable);
446 }
447
448 int32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec) const {
449 return is64Bit() ? toSection64(Sec)->Flags : toSection32(Sec)->Flags;
450 }
451
452 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type, MemoryBufferRef Object)
453 : ObjectFile(Type, Object) {
454 assert(Type == Binary::ID_XCOFF32 || Type == Binary::ID_XCOFF64);
455 }
456
457 ArrayRef XCOFFObjectFile::sections64() const {
458 assert(is64Bit() && "64-bit interface called for non 64-bit file.");
459 const XCOFFSectionHeader64 *TablePtr = sectionHeaderTable64();
460 return ArrayRef(TablePtr,
461 TablePtr + getNumberOfSections());
462 }
463
464 ArrayRef XCOFFObjectFile::sections32() const {
465 assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
466 const XCOFFSectionHeader32 *TablePtr = sectionHeaderTable32();
467 return ArrayRef(TablePtr,
468 TablePtr + getNumberOfSections());
469 }
470
471 Expected
472 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
473 // If there is a string table, then the buffer must contain at least 4 bytes
474 // for the string table's size. Not having a string table is not an error.
475 if (auto EC = Binary::checkOffset(
476 Obj->Data, reinterpret_cast(Obj->base() + Offset), 4))
477 return XCOFFStringTable{0, nullptr};
478
479 // Read the size out of the buffer.
480 uint32_t Size = support::endian::read32be(Obj->base() + Offset);
481
482 // If the size is less then 4, then the string table is just a size and no
483 // string data.
484 if (Size <= 4)
485 return XCOFFStringTable{4, nullptr};
486
487 auto StringTableOrErr =
488 getObject(Obj->Data, Obj->base() + Offset, Size);
489 if (Error E = StringTableOrErr.takeError())
490 return std::move(E);
491
492 const char *StringTablePtr = StringTableOrErr.get();
493 if (StringTablePtr[Size - 1] != '\0')
494 return errorCodeToError(object_error::string_table_non_null_end);
495
496 return XCOFFStringTable{Size, StringTablePtr};
497 }
498
499 Expected>
500 XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
501 // Can't use make_unique because of the private constructor.
502 std::unique_ptr Obj;
503 Obj.reset(new XCOFFObjectFile(Type, MBR));
504
505 uint64_t CurOffset = 0;
506 const auto *Base = Obj->base();
507 MemoryBufferRef Data = Obj->Data;
508
509 // Parse file header.
510 auto FileHeaderOrErr =
511 getObject(Data, Base + CurOffset, Obj->getFileHeaderSize());
512 if (Error E = FileHeaderOrErr.takeError())
513 return std::move(E);
514 Obj->FileHeader = FileHeaderOrErr.get();
515
516 CurOffset += Obj->getFileHeaderSize();
408517 // TODO FIXME we don't have support for an optional header yet, so just skip
409518 // past it.
410 CurPtr += FileHdrPtr->AuxHeaderSize;
411
412 if (getNumberOfSections() != 0) {
413 if ((EC = getObject(SectionHdrTablePtr, Data, base() + CurPtr,
414 getNumberOfSections() * getSectionHeaderSize())))
415 return;
519 CurOffset += Obj->getOptionalHeaderSize();
520
521 // Parse the section header table if it is present.
522 if (Obj->getNumberOfSections()) {
523 auto SecHeadersOrErr = getObject(Data, Base + CurOffset,
524 Obj->getNumberOfSections() *
525 Obj->getSectionHeaderSize());
526 if (Error E = SecHeadersOrErr.takeError())
527 return std::move(E);
528 Obj->SectionHeaderTable = SecHeadersOrErr.get();
416529 }
417530
418 if (getLogicalNumberOfSymbolTableEntries() == 0)
419 return;
420
421 // Get pointer to the symbol table.
422 CurPtr = FileHdrPtr->SymbolTableOffset;
531 // 64-bit object supports only file header and section headers for now.
532 if (Obj->is64Bit())
533 return std::move(Obj);
534
535 // If there is no symbol table we are done parsing the memory buffer.
536 if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
537 return std::move(Obj);
538
539 // Parse symbol table.
540 CurOffset = Obj->fileHeader32()->SymbolTableOffset;
423541 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 }
542 Obj->getLogicalNumberOfSymbolTableEntries32();
543 auto SymTableOrErr =
544 getObject(Data, Base + CurOffset, SymbolTableSize);
545 if (Error E = SymTableOrErr.takeError())
546 return std::move(E);
547 Obj->SymbolTblPtr = SymTableOrErr.get();
548 CurOffset += SymbolTableSize;
549
550 // Parse String table.
551 Expected StringTableOrErr =
552 parseStringTable(Obj.get(), CurOffset);
553 if (Error E = StringTableOrErr.takeError())
554 return std::move(E);
555 Obj->StringTable = StringTableOrErr.get();
556
557 return std::move(Obj);
450558 }
451559
452560 Expected>
453 ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object) {
454 StringRef Data = Object.getBuffer();
455 file_magic Type = identify_magic(Data);
456 std::error_code EC;
457 std::unique_ptr Ret;
458
459 if (Type == file_magic::xcoff_object_32) {
460 Ret.reset(new XCOFFObjectFile(Object, EC));
461 } else {
462 llvm_unreachable("Encountered an unexpected binary file type!");
463 }
464
465 if (EC)
466 return errorCodeToError(EC);
467 return std::move(Ret);
561 ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
562 unsigned FileType) {
563 return XCOFFObjectFile::create(FileType, MemBufRef);
564 }
565
566 StringRef XCOFFSectionHeader32::getName() const {
567 return generateStringRef(Name, XCOFF::SectionNameSize);
568 }
569
570 StringRef XCOFFSectionHeader64::getName() const {
571 return generateStringRef(Name, XCOFF::SectionNameSize);
468572 }
469573
470574 } // namespace object
0 # RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic.o | \
11 # RUN: FileCheck --check-prefix=FILEHEADER %s
2 #
3 # RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic-64.o | \
4 # RUN: FileCheck --check-prefix=FILEHEADER64 %s
25
36 # RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic-neg-time.o | \
47 # RUN: FileCheck --check-prefix=NEGTIME %s
1922 # FILEHEADER-NEXT: OptionalHeaderSize: 0x1C
2023 # FILEHEADER-NEXT: Flags: 0x0
2124 # FILEHEADER-NEXT: }
25
26 # FILEHEADER64: File: {{.*}}xcoff-basic-64.o
27 # FILEHEADER64-NEXT: Format: aix5coff64-rs6000
28 # FILEHEADER64-NEXT: Arch: powerpc64
29 # FILEHEADER64-NEXT: AddressSize: 64bit
30 # FILEHEADER64-NEXT: FileHeader {
31 # FILEHEADER64-NEXT: Magic: 0x1F7
32 # FILEHEADER64-NEXT: NumberOfSections: 5
33 # FILEHEADER64-NEXT: TimeStamp: 2019-03-18T20:03:47Z (0x5C8FF9A3)
34 # FILEHEADER64-NEXT: SymbolTableOffset: 0x54C
35 # FILEHEADER64-NEXT: SymbolTableEntries: 58
36 # FILEHEADER64-NEXT: OptionalHeaderSize: 0x0
37 # FILEHEADER64-NEXT: Flags: 0x0
38 # FILEHEADER64-NEXT: }
2239
2340 # NEGTIME: File: {{.*}}xcoff-basic-neg-time.o
2441 # NEGTIME-NEXT: Format: aixcoff-rs6000
0 # RUN: llvm-readobj --section-headers %p/Inputs/xcoff-basic.o | \
1 # RUN: FileCheck --check-prefix=SEC32 %s
2
3 # RUN: llvm-readobj --section-headers %p/Inputs/xcoff-basic-64.o | \
4 # RUN: FileCheck --check-prefix=SEC64 %s
5
6 # SEC32: File: {{.*}}xcoff-basic.o
7 # SEC32-NEXT: Format: aixcoff-rs6000
8 # SEC32-NEXT: Arch: powerpc
9 # SEC32-NEXT: AddressSize: 32bit
10 # SEC32-NEXT: Sections [
11 # SEC32-NEXT: Section {
12 # SEC32-NEXT: Index: 1
13 # SEC32-NEXT: Name: .text
14 # SEC32-NEXT: PhysicalAddress: 0x0
15 # SEC32-NEXT: VirtualAddress: 0x0
16 # SEC32-NEXT: Size: 0x100
17 # SEC32-NEXT: RawDataOffset: 0x200
18 # SEC32-NEXT: RelocationPointer: 0x3D8
19 # SEC32-NEXT: LineNumberPointer: 0x4E6
20 # SEC32-NEXT: NumberOfRelocations: 8
21 # SEC32-NEXT: NumberOfLineNumbers: 12
22 # SEC32-NEXT: Type: STYP_TEXT (0x20)
23 # SEC32-NEXT: }
24 # SEC32-NEXT: Section {
25 # SEC32-NEXT: Index: 2
26 # SEC32-NEXT: Name: .data
27 # SEC32-NEXT: PhysicalAddress: 0x100
28 # SEC32-NEXT: VirtualAddress: 0x100
29 # SEC32-NEXT: Size: 0x68
30 # SEC32-NEXT: RawDataOffset: 0x300
31 # SEC32-NEXT: RelocationPointer: 0x428
32 # SEC32-NEXT: LineNumberPointer: 0x0
33 # SEC32-NEXT: NumberOfRelocations: 19
34 # SEC32-NEXT: NumberOfLineNumbers: 0
35 # SEC32-NEXT: Type: STYP_DATA (0x40)
36 # SEC32-NEXT: }
37 # SEC32-NEXT: Section {
38 # SEC32-NEXT: Index: 3
39 # SEC32-NEXT: Name: .bss
40 # SEC32-NEXT: PhysicalAddress: 0x168
41 # SEC32-NEXT: VirtualAddress: 0x168
42 # SEC32-NEXT: Size: 0x4
43 # SEC32-NEXT: RawDataOffset: 0x0
44 # SEC32-NEXT: RelocationPointer: 0x0
45 # SEC32-NEXT: LineNumberPointer: 0x0
46 # SEC32-NEXT: NumberOfRelocations: 0
47 # SEC32-NEXT: NumberOfLineNumbers: 0
48 # SEC32-NEXT: Type: STYP_BSS (0x80)
49 # SEC32-NEXT: }
50 # SEC32-NEXT: Section {
51 # SEC32-NEXT: Index: 4
52 # SEC32-NEXT: Name: .tdata
53 # SEC32-NEXT: PhysicalAddress: 0x0
54 # SEC32-NEXT: VirtualAddress: 0x0
55 # SEC32-NEXT: Size: 0x4
56 # SEC32-NEXT: RawDataOffset: 0x368
57 # SEC32-NEXT: RelocationPointer: 0x47A
58 # SEC32-NEXT: LineNumberPointer: 0x0
59 # SEC32-NEXT: NumberOfRelocations: 0
60 # SEC32-NEXT: NumberOfLineNumbers: 0
61 # SEC32-NEXT: Type: STYP_TDATA (0x400)
62 # SEC32-NEXT: }
63 # SEC32-NEXT: Section {
64 # SEC32-NEXT: Index: 5
65 # SEC32-NEXT: Name: .tbss
66 # SEC32-NEXT: PhysicalAddress: 0x4
67 # SEC32-NEXT: VirtualAddress: 0x4
68 # SEC32-NEXT: Size: 0x8
69 # SEC32-NEXT: RawDataOffset: 0x0
70 # SEC32-NEXT: RelocationPointer: 0x0
71 # SEC32-NEXT: LineNumberPointer: 0x0
72 # SEC32-NEXT: NumberOfRelocations: 0
73 # SEC32-NEXT: NumberOfLineNumbers: 0
74 # SEC32-NEXT: Type: STYP_TBSS (0x800)
75 # SEC32-NEXT: }
76 # SEC32-NEXT: Section {
77 # SEC32-NEXT: Index: 6
78 # SEC32-NEXT: Name: .debug
79 # SEC32-NEXT: PhysicalAddress: 0x0
80 # SEC32-NEXT: VirtualAddress: 0x0
81 # SEC32-NEXT: Size: 0x6C
82 # SEC32-NEXT: RawDataOffset: 0x36C
83 # SEC32-NEXT: RelocationPointer: 0x0
84 # SEC32-NEXT: LineNumberPointer: 0x0
85 # SEC32-NEXT: NumberOfRelocations: 0
86 # SEC32-NEXT: NumberOfLineNumbers: 0
87 # SEC32-NEXT: Type: STYP_DEBUG (0x2000)
88 # SEC32-NEXT: }
89 # SEC32-NEXT: ]
90
91
92 # SEC64: File: {{.*}}xcoff-basic-64.o
93 # SEC64-NEXT: Format: aix5coff64-rs6000
94 # SEC64-NEXT: Arch: powerpc64
95 # SEC64-NEXT: AddressSize: 64bit
96 # SEC64-NEXT: Sections [
97 # SEC64-NEXT: Section {
98 # SEC64-NEXT: Index: 1
99 # SEC64-NEXT: Name: .text
100 # SEC64-NEXT: PhysicalAddress: 0x0
101 # SEC64-NEXT: VirtualAddress: 0x0
102 # SEC64-NEXT: Size: 0x100
103 # SEC64-NEXT: RawDataOffset: 0x200
104 # SEC64-NEXT: RelocationPointer: 0x3C4
105 # SEC64-NEXT: LineNumberPointer: 0x0
106 # SEC64-NEXT: NumberOfRelocations: 9
107 # SEC64-NEXT: NumberOfLineNumbers: 0
108 # SEC64-NEXT: Type: STYP_TEXT (0x20)
109 # SEC64-NEXT: }
110 # SEC64-NEXT: Section {
111 # SEC64-NEXT: Index: 2
112 # SEC64-NEXT: Name: .data
113 # SEC64-NEXT: PhysicalAddress: 0x100
114 # SEC64-NEXT: VirtualAddress: 0x100
115 # SEC64-NEXT: Size: 0xC0
116 # SEC64-NEXT: RawDataOffset: 0x300
117 # SEC64-NEXT: RelocationPointer: 0x442
118 # SEC64-NEXT: LineNumberPointer: 0x0
119 # SEC64-NEXT: NumberOfRelocations: 19
120 # SEC64-NEXT: NumberOfLineNumbers: 0
121 # SEC64-NEXT: Type: STYP_DATA (0x40)
122 # SEC64-NEXT: }
123 # SEC64-NEXT: Section {
124 # SEC64-NEXT: Index: 3
125 # SEC64-NEXT: Name: .bss
126 # SEC64-NEXT: PhysicalAddress: 0x1C0
127 # SEC64-NEXT: VirtualAddress: 0x1C0
128 # SEC64-NEXT: Size: 0x8
129 # SEC64-NEXT: RawDataOffset: 0x0
130 # SEC64-NEXT: RelocationPointer: 0x0
131 # SEC64-NEXT: LineNumberPointer: 0x0
132 # SEC64-NEXT: NumberOfRelocations: 0
133 # SEC64-NEXT: NumberOfLineNumbers: 0
134 # SEC64-NEXT: Type: STYP_BSS (0x80)
135 # SEC64-NEXT: }
136 # SEC64-NEXT: Section {
137 # SEC64-NEXT: Index: 4
138 # SEC64-NEXT: Name: .tdata
139 # SEC64-NEXT: PhysicalAddress: 0x0
140 # SEC64-NEXT: VirtualAddress: 0x0
141 # SEC64-NEXT: Size: 0x4
142 # SEC64-NEXT: RawDataOffset: 0x3C0
143 # SEC64-NEXT: RelocationPointer: 0x54C
144 # SEC64-NEXT: LineNumberPointer: 0x0
145 # SEC64-NEXT: NumberOfRelocations: 0
146 # SEC64-NEXT: NumberOfLineNumbers: 0
147 # SEC64-NEXT: Type: STYP_TDATA (0x400)
148 # SEC64-NEXT: }
149 # SEC64-NEXT: Section {
150 # SEC64-NEXT: Index: 5
151 # SEC64-NEXT: Name: .tbss
152 # SEC64-NEXT: PhysicalAddress: 0x4
153 # SEC64-NEXT: VirtualAddress: 0x4
154 # SEC64-NEXT: Size: 0x8
155 # SEC64-NEXT: RawDataOffset: 0x0
156 # SEC64-NEXT: RelocationPointer: 0x0
157 # SEC64-NEXT: LineNumberPointer: 0x0
158 # SEC64-NEXT: NumberOfRelocations: 0
159 # SEC64-NEXT: NumberOfLineNumbers: 0
160 # SEC64-NEXT: Type: STYP_TBSS (0x800)
161 # SEC64-NEXT: }
162 # SEC64-NEXT: ]
163
3535 void printNeededLibraries() override;
3636
3737 private:
38 template void printSectionHeaders(ArrayRef Sections);
39
3840 const XCOFFObjectFile &Obj;
41
42 // Least significant 3 bits are reserved.
43 static constexpr unsigned SectionFlagsReservedMask = 0x7;
3944 };
4045 } // anonymous namespace
4146
6469 TimeStamp);
6570 }
6671
67 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset());
68 int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries();
69 if (SymTabEntries >= 0)
70 W.printNumber("SymbolTableEntries", SymTabEntries);
71 else
72 W.printHex("SymbolTableEntries", "Reserved Value", SymTabEntries);
72 // The number of symbol table entries is an unsigned value in 64-bit objects
73 // and a signed value (with negative values being 'reserved') in 32-bit
74 // objects.
75 if (Obj.is64Bit()) {
76 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset64());
77 W.printNumber("SymbolTableEntries", Obj.getNumberOfSymbolTableEntries64());
78 } else {
79 W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset32());
80 int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries32();
81 if (SymTabEntries >= 0)
82 W.printNumber("SymbolTableEntries", SymTabEntries);
83 else
84 W.printHex("SymbolTableEntries", "Reserved Value", SymTabEntries);
85 }
7386
7487 W.printHex("OptionalHeaderSize", Obj.getOptionalHeaderSize());
7588 W.printHex("Flags", Obj.getFlags());
7992 }
8093
8194 void XCOFFDumper::printSectionHeaders() {
82 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
95 if (Obj.is64Bit())
96 printSectionHeaders(Obj.sections64());
97 else
98 printSectionHeaders(Obj.sections32());
8399 }
84100
85101 void XCOFFDumper::printRelocations() {
106122 llvm_unreachable("Unimplemented functionality for XCOFFDumper");
107123 }
108124
125 static const EnumEntry SectionTypeFlagsNames[] = {
126 #define ECase(X) \
127 { #X, XCOFF::X }
128 ECase(STYP_PAD), ECase(STYP_DWARF), ECase(STYP_TEXT),
129 ECase(STYP_DATA), ECase(STYP_BSS), ECase(STYP_EXCEPT),
130 ECase(STYP_INFO), ECase(STYP_TDATA), ECase(STYP_TBSS),
131 ECase(STYP_LOADER), ECase(STYP_DEBUG), ECase(STYP_TYPCHK),
132 ECase(STYP_OVRFLO)
133 #undef ECase
134 };
135
136 template
137 void XCOFFDumper::printSectionHeaders(ArrayRef Sections) {
138 ListScope Group(W, "Sections");
139
140 uint16_t Index = 1;
141 for (const T &Sec : Sections) {
142 DictScope SecDS(W, "Section");
143
144 W.printNumber("Index", Index++);
145 W.printString("Name", Sec.getName());
146
147 W.printHex("PhysicalAddress", Sec.PhysicalAddress);
148 W.printHex("VirtualAddress", Sec.VirtualAddress);
149 W.printHex("Size", Sec.SectionSize);
150 W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
151 W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
152 W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
153
154 // TODO Need to add overflow handling when NumberOfX == _OVERFLOW_MARKER
155 // in 32-bit object files.
156 W.printNumber("NumberOfRelocations", Sec.NumberOfRelocations);
157 W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
158
159 // The most significant 16-bits represent the DWARF section subtype. For
160 // now we just dump the section type flags.
161 uint16_t Flags = Sec.Flags & 0xffffu;
162 if (Flags & SectionFlagsReservedMask)
163 W.printHex("Flags", "Reserved", Flags);
164 else
165 W.printEnum("Type", Flags, makeArrayRef(SectionTypeFlagsNames));
166 }
167
168 if (opts::SectionRelocations)
169 report_fatal_error("Dumping section relocations is unimplemented");
170
171 if (opts::SectionSymbols)
172 report_fatal_error("Dumping symbols is unimplemented");
173
174 if (opts::SectionData)
175 report_fatal_error("Dumping section data is unimplemented");
176 }
177
109178 namespace llvm {
110179 std::error_code createXCOFFDumper(const object::ObjectFile *Obj,
111180 ScopedPrinter &Writer,
2828 } // namespace
2929
3030 std::error_code XCOFFDumper::dump() {
31 std::error_code EC;
3231 dumpHeader();
33 EC = dumpSymbols();
34 return EC;
32 return dumpSymbols();
3533 }
3634
3735 void XCOFFDumper::dumpHeader() {
38 const XCOFFFileHeader *FileHdrPtr = Obj.getFileHeader();
3936
40 YAMLObj.Header.Magic = FileHdrPtr->Magic;
41 YAMLObj.Header.NumberOfSections = FileHdrPtr->NumberOfSections;
42 YAMLObj.Header.TimeStamp = FileHdrPtr->TimeStamp;
43 YAMLObj.Header.SymbolTableOffset = FileHdrPtr->SymbolTableOffset;
44 YAMLObj.Header.NumberOfSymTableEntries = FileHdrPtr->NumberOfSymTableEntries;
45 YAMLObj.Header.AuxHeaderSize = FileHdrPtr->AuxHeaderSize;
46 YAMLObj.Header.Flags = FileHdrPtr->Flags;
37 YAMLObj.Header.Magic = Obj.getMagic();
38 YAMLObj.Header.NumberOfSections = Obj.getNumberOfSections();
39 YAMLObj.Header.TimeStamp = Obj.getTimeStamp();
40
41 // TODO FIXME only dump 32 bit header for now.
42 if (Obj.is64Bit())
43 report_fatal_error("64-bit XCOFF files not supported yet.");
44 YAMLObj.Header.SymbolTableOffset = Obj.getSymbolTableOffset32();
45
46 YAMLObj.Header.NumberOfSymTableEntries =
47 Obj.getRawNumberOfSymbolTableEntries32();
48 YAMLObj.Header.AuxHeaderSize = Obj.getOptionalHeaderSize();
49 YAMLObj.Header.Flags = Obj.getFlags();
4750 }
4851
4952 std::error_code XCOFFDumper::dumpSymbols() {