1 //===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the XCOFFObjectFile class.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/XCOFFObjectFile.h"
25 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
26 // 'M'. Returns a pointer to the underlying object on success.
28 static Expected
<const T
*> getObject(MemoryBufferRef M
, const void *Ptr
,
29 const uint64_t Size
= sizeof(T
)) {
30 uintptr_t Addr
= uintptr_t(Ptr
);
31 if (std::error_code EC
= Binary::checkOffset(M
, Addr
, Size
))
32 return errorCodeToError(EC
);
33 return reinterpret_cast<const T
*>(Addr
);
36 static uintptr_t getWithOffset(uintptr_t Base
, ptrdiff_t Offset
) {
37 return reinterpret_cast<uintptr_t>(reinterpret_cast<const char *>(Base
) +
41 template <typename T
> static const T
*viewAs(uintptr_t in
) {
42 return reinterpret_cast<const T
*>(in
);
45 static StringRef
generateXCOFFFixedNameStringRef(const char *Name
) {
47 static_cast<const char *>(memchr(Name
, '\0', XCOFF::NameSize
));
48 return NulCharPtr
? StringRef(Name
, NulCharPtr
- Name
)
49 : StringRef(Name
, XCOFF::NameSize
);
52 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr
,
53 uintptr_t TableAddress
) const {
54 if (Addr
< TableAddress
)
55 report_fatal_error("Section header outside of section header table.");
57 uintptr_t Offset
= Addr
- TableAddress
;
58 if (Offset
>= getSectionHeaderSize() * getNumberOfSections())
59 report_fatal_error("Section header outside of section header table.");
61 if (Offset
% getSectionHeaderSize() != 0)
63 "Section header pointer does not point to a valid section header.");
66 const XCOFFSectionHeader32
*
67 XCOFFObjectFile::toSection32(DataRefImpl Ref
) const {
68 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
70 checkSectionAddress(Ref
.p
, getSectionHeaderTableAddress());
72 return viewAs
<XCOFFSectionHeader32
>(Ref
.p
);
75 const XCOFFSectionHeader64
*
76 XCOFFObjectFile::toSection64(DataRefImpl Ref
) const {
77 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
79 checkSectionAddress(Ref
.p
, getSectionHeaderTableAddress());
81 return viewAs
<XCOFFSectionHeader64
>(Ref
.p
);
84 const XCOFFSymbolEntry
*XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref
) const {
85 assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
86 assert(Ref
.p
!= 0 && "Symbol table pointer can not be nullptr!");
88 checkSymbolEntryPointer(Ref
.p
);
90 auto SymEntPtr
= viewAs
<XCOFFSymbolEntry
>(Ref
.p
);
94 const XCOFFFileHeader32
*XCOFFObjectFile::fileHeader32() const {
95 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
96 return static_cast<const XCOFFFileHeader32
*>(FileHeader
);
99 const XCOFFFileHeader64
*XCOFFObjectFile::fileHeader64() const {
100 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
101 return static_cast<const XCOFFFileHeader64
*>(FileHeader
);
104 const XCOFFSectionHeader32
*
105 XCOFFObjectFile::sectionHeaderTable32() const {
106 assert(!is64Bit() && "32-bit interface called on 64-bit object file.");
107 return static_cast<const XCOFFSectionHeader32
*>(SectionHeaderTable
);
110 const XCOFFSectionHeader64
*
111 XCOFFObjectFile::sectionHeaderTable64() const {
112 assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
113 return static_cast<const XCOFFSectionHeader64
*>(SectionHeaderTable
);
116 void XCOFFObjectFile::moveSymbolNext(DataRefImpl
&Symb
) const {
117 const XCOFFSymbolEntry
*SymEntPtr
= toSymbolEntry(Symb
);
118 SymEntPtr
+= SymEntPtr
->NumberOfAuxEntries
+ 1;
120 // This function is used by basic_symbol_iterator, which allows to
121 // point to the end-of-symbol-table address.
122 if (reinterpret_cast<uintptr_t>(SymEntPtr
) != getEndOfSymbolTableAddress())
123 checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr
));
125 Symb
.p
= reinterpret_cast<uintptr_t>(SymEntPtr
);
129 XCOFFObjectFile::getStringTableEntry(uint32_t Offset
) const {
130 // The byte offset is relative to the start of the string table.
131 // A byte offset value of 0 is a null or zero-length symbol
132 // name. A byte offset in the range 1 to 3 (inclusive) points into the length
133 // field; as a soft-error recovery mechanism, we treat such cases as having an
136 return StringRef(nullptr, 0);
138 if (StringTable
.Data
!= nullptr && StringTable
.Size
> Offset
)
139 return (StringTable
.Data
+ Offset
);
141 return make_error
<GenericBinaryError
>("Bad offset for string table entry",
142 object_error::parse_failed
);
146 XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt
*CFileEntPtr
) const {
147 if (CFileEntPtr
->NameInStrTbl
.Magic
!=
148 XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC
)
149 return generateXCOFFFixedNameStringRef(CFileEntPtr
->Name
);
150 return getStringTableEntry(CFileEntPtr
->NameInStrTbl
.Offset
);
153 Expected
<StringRef
> XCOFFObjectFile::getSymbolName(DataRefImpl Symb
) const {
154 const XCOFFSymbolEntry
*SymEntPtr
= toSymbolEntry(Symb
);
156 // A storage class value with the high-order bit on indicates that the name is
157 // a symbolic debugger stabstring.
158 if (SymEntPtr
->StorageClass
& 0x80)
159 return StringRef("Unimplemented Debug Name");
161 if (SymEntPtr
->NameInStrTbl
.Magic
!= XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC
)
162 return generateXCOFFFixedNameStringRef(SymEntPtr
->SymbolName
);
164 return getStringTableEntry(SymEntPtr
->NameInStrTbl
.Offset
);
167 Expected
<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb
) const {
169 llvm_unreachable("Not yet implemented!");
173 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb
) const {
174 assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
175 return toSymbolEntry(Symb
)->Value
;
178 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb
) const {
180 llvm_unreachable("Not yet implemented!");
184 Expected
<SymbolRef::Type
>
185 XCOFFObjectFile::getSymbolType(DataRefImpl Symb
) const {
186 llvm_unreachable("Not yet implemented!");
187 return SymbolRef::ST_Other
;
190 Expected
<section_iterator
>
191 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb
) const {
192 const XCOFFSymbolEntry
*SymEntPtr
= toSymbolEntry(Symb
);
193 int16_t SectNum
= SymEntPtr
->SectionNumber
;
195 if (isReservedSectionNumber(SectNum
))
196 return section_end();
198 Expected
<DataRefImpl
> ExpSec
= getSectionByNum(SectNum
);
200 return ExpSec
.takeError();
202 return section_iterator(SectionRef(ExpSec
.get(), this));
205 void XCOFFObjectFile::moveSectionNext(DataRefImpl
&Sec
) const {
206 const char *Ptr
= reinterpret_cast<const char *>(Sec
.p
);
207 Sec
.p
= reinterpret_cast<uintptr_t>(Ptr
+ getSectionHeaderSize());
210 Expected
<StringRef
> XCOFFObjectFile::getSectionName(DataRefImpl Sec
) const {
211 return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec
));
214 uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec
) const {
215 // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
218 return toSection64(Sec
)->VirtualAddress
;
220 return toSection32(Sec
)->VirtualAddress
;
223 uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec
) const {
224 // Section numbers in XCOFF are numbered beginning at 1. A section number of
225 // zero is used to indicate that a symbol is being imported or is undefined.
227 return toSection64(Sec
) - sectionHeaderTable64() + 1;
229 return toSection32(Sec
) - sectionHeaderTable32() + 1;
232 uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec
) const {
233 // Avoid ternary due to failure to convert the ubig32_t value to a unit64_t
236 return toSection64(Sec
)->SectionSize
;
238 return toSection32(Sec
)->SectionSize
;
241 Expected
<ArrayRef
<uint8_t>>
242 XCOFFObjectFile::getSectionContents(DataRefImpl Sec
) const {
243 llvm_unreachable("Not yet implemented!");
246 uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec
) const {
248 llvm_unreachable("Not yet implemented!");
252 bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec
) const {
254 llvm_unreachable("Not yet implemented!");
258 bool XCOFFObjectFile::isSectionText(DataRefImpl Sec
) const {
259 return getSectionFlags(Sec
) & XCOFF::STYP_TEXT
;
262 bool XCOFFObjectFile::isSectionData(DataRefImpl Sec
) const {
263 uint32_t Flags
= getSectionFlags(Sec
);
264 return Flags
& (XCOFF::STYP_DATA
| XCOFF::STYP_TDATA
);
267 bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec
) const {
268 uint32_t Flags
= getSectionFlags(Sec
);
269 return Flags
& (XCOFF::STYP_BSS
| XCOFF::STYP_TBSS
);
272 bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec
) const {
274 llvm_unreachable("Not yet implemented!");
278 relocation_iterator
XCOFFObjectFile::section_rel_begin(DataRefImpl Sec
) const {
279 llvm_unreachable("Not yet implemented!");
280 return relocation_iterator(RelocationRef());
283 relocation_iterator
XCOFFObjectFile::section_rel_end(DataRefImpl Sec
) const {
284 llvm_unreachable("Not yet implemented!");
285 return relocation_iterator(RelocationRef());
288 void XCOFFObjectFile::moveRelocationNext(DataRefImpl
&Rel
) const {
289 llvm_unreachable("Not yet implemented!");
293 uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel
) const {
294 llvm_unreachable("Not yet implemented!");
299 symbol_iterator
XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel
) const {
300 llvm_unreachable("Not yet implemented!");
301 return symbol_iterator(SymbolRef());
304 uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel
) const {
305 llvm_unreachable("Not yet implemented!");
310 void XCOFFObjectFile::getRelocationTypeName(
311 DataRefImpl Rel
, SmallVectorImpl
<char> &Result
) const {
312 llvm_unreachable("Not yet implemented!");
316 uint32_t XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb
) const {
318 llvm_unreachable("Not yet implemented!");
322 basic_symbol_iterator
XCOFFObjectFile::symbol_begin() const {
323 assert(!is64Bit() && "64-bit support not implemented yet.");
325 SymDRI
.p
= reinterpret_cast<uintptr_t>(SymbolTblPtr
);
326 return basic_symbol_iterator(SymbolRef(SymDRI
, this));
329 basic_symbol_iterator
XCOFFObjectFile::symbol_end() const {
330 assert(!is64Bit() && "64-bit support not implemented yet.");
332 SymDRI
.p
= reinterpret_cast<uintptr_t>(
333 SymbolTblPtr
+ getLogicalNumberOfSymbolTableEntries32());
334 return basic_symbol_iterator(SymbolRef(SymDRI
, this));
337 section_iterator
XCOFFObjectFile::section_begin() const {
339 DRI
.p
= getSectionHeaderTableAddress();
340 return section_iterator(SectionRef(DRI
, this));
343 section_iterator
XCOFFObjectFile::section_end() const {
345 DRI
.p
= getWithOffset(getSectionHeaderTableAddress(),
346 getNumberOfSections() * getSectionHeaderSize());
347 return section_iterator(SectionRef(DRI
, this));
350 uint8_t XCOFFObjectFile::getBytesInAddress() const { return is64Bit() ? 8 : 4; }
352 StringRef
XCOFFObjectFile::getFileFormatName() const {
353 return is64Bit() ? "aix5coff64-rs6000" : "aixcoff-rs6000";
356 Triple::ArchType
XCOFFObjectFile::getArch() const {
357 return is64Bit() ? Triple::ppc64
: Triple::ppc
;
360 SubtargetFeatures
XCOFFObjectFile::getFeatures() const {
361 llvm_unreachable("Not yet implemented!");
362 return SubtargetFeatures();
365 bool XCOFFObjectFile::isRelocatableObject() const {
367 llvm_unreachable("Not yet implemented!");
371 Expected
<uint64_t> XCOFFObjectFile::getStartAddress() const {
372 // TODO FIXME Should get from auxiliary_header->o_entry when support for the
373 // auxiliary_header is added.
377 size_t XCOFFObjectFile::getFileHeaderSize() const {
378 return is64Bit() ? sizeof(XCOFFFileHeader64
) : sizeof(XCOFFFileHeader32
);
381 size_t XCOFFObjectFile::getSectionHeaderSize() const {
382 return is64Bit() ? sizeof(XCOFFSectionHeader64
) :
383 sizeof(XCOFFSectionHeader32
);
386 bool XCOFFObjectFile::is64Bit() const {
387 return Binary::ID_XCOFF64
== getType();
390 uint16_t XCOFFObjectFile::getMagic() const {
391 return is64Bit() ? fileHeader64()->Magic
: fileHeader32()->Magic
;
394 Expected
<DataRefImpl
> XCOFFObjectFile::getSectionByNum(int16_t Num
) const {
395 if (Num
<= 0 || Num
> getNumberOfSections())
396 return errorCodeToError(object_error::invalid_section_index
);
399 DRI
.p
= getWithOffset(getSectionHeaderTableAddress(),
400 getSectionHeaderSize() * (Num
- 1));
405 XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry
*SymEntPtr
) const {
406 assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
407 int16_t SectionNum
= SymEntPtr
->SectionNumber
;
409 switch (SectionNum
) {
417 Expected
<DataRefImpl
> SecRef
= getSectionByNum(SectionNum
);
419 return generateXCOFFFixedNameStringRef(
420 getSectionNameInternal(SecRef
.get()));
421 return SecRef
.takeError();
425 bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber
) {
426 return (SectionNumber
<= 0 && SectionNumber
>= -2);
429 uint16_t XCOFFObjectFile::getNumberOfSections() const {
430 return is64Bit() ? fileHeader64()->NumberOfSections
431 : fileHeader32()->NumberOfSections
;
434 int32_t XCOFFObjectFile::getTimeStamp() const {
435 return is64Bit() ? fileHeader64()->TimeStamp
: fileHeader32()->TimeStamp
;
438 uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
439 return is64Bit() ? fileHeader64()->AuxHeaderSize
440 : fileHeader32()->AuxHeaderSize
;
443 uint32_t XCOFFObjectFile::getSymbolTableOffset32() const {
444 return fileHeader32()->SymbolTableOffset
;
447 int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries32() const {
448 // As far as symbol table size is concerned, if this field is negative it is
449 // to be treated as a 0. However since this field is also used for printing we
450 // don't want to truncate any negative values.
451 return fileHeader32()->NumberOfSymTableEntries
;
454 uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries32() const {
455 return (fileHeader32()->NumberOfSymTableEntries
>= 0
456 ? fileHeader32()->NumberOfSymTableEntries
460 uint64_t XCOFFObjectFile::getSymbolTableOffset64() const {
461 return fileHeader64()->SymbolTableOffset
;
464 uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
465 return fileHeader64()->NumberOfSymTableEntries
;
468 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
469 uint32_t NumberOfSymTableEntries
=
470 is64Bit() ? getNumberOfSymbolTableEntries64()
471 : getLogicalNumberOfSymbolTableEntries32();
472 return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr
),
473 XCOFF::SymbolTableEntrySize
* NumberOfSymTableEntries
);
476 void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr
) const {
477 if (SymbolEntPtr
< reinterpret_cast<uintptr_t>(SymbolTblPtr
))
478 report_fatal_error("Symbol table entry is outside of symbol table.");
480 if (SymbolEntPtr
>= getEndOfSymbolTableAddress())
481 report_fatal_error("Symbol table entry is outside of symbol table.");
483 ptrdiff_t Offset
= reinterpret_cast<const char *>(SymbolEntPtr
) -
484 reinterpret_cast<const char *>(SymbolTblPtr
);
486 if (Offset
% XCOFF::SymbolTableEntrySize
!= 0)
488 "Symbol table entry position is not valid inside of symbol table.");
491 uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr
) const {
492 return (reinterpret_cast<const char *>(SymbolEntPtr
) -
493 reinterpret_cast<const char *>(SymbolTblPtr
)) /
494 XCOFF::SymbolTableEntrySize
;
497 uint16_t XCOFFObjectFile::getFlags() const {
498 return is64Bit() ? fileHeader64()->Flags
: fileHeader32()->Flags
;
501 const char *XCOFFObjectFile::getSectionNameInternal(DataRefImpl Sec
) const {
502 return is64Bit() ? toSection64(Sec
)->Name
: toSection32(Sec
)->Name
;
505 uintptr_t XCOFFObjectFile::getSectionHeaderTableAddress() const {
506 return reinterpret_cast<uintptr_t>(SectionHeaderTable
);
509 int32_t XCOFFObjectFile::getSectionFlags(DataRefImpl Sec
) const {
510 return is64Bit() ? toSection64(Sec
)->Flags
: toSection32(Sec
)->Flags
;
513 XCOFFObjectFile::XCOFFObjectFile(unsigned int Type
, MemoryBufferRef Object
)
514 : ObjectFile(Type
, Object
) {
515 assert(Type
== Binary::ID_XCOFF32
|| Type
== Binary::ID_XCOFF64
);
518 ArrayRef
<XCOFFSectionHeader64
> XCOFFObjectFile::sections64() const {
519 assert(is64Bit() && "64-bit interface called for non 64-bit file.");
520 const XCOFFSectionHeader64
*TablePtr
= sectionHeaderTable64();
521 return ArrayRef
<XCOFFSectionHeader64
>(TablePtr
,
522 TablePtr
+ getNumberOfSections());
525 ArrayRef
<XCOFFSectionHeader32
> XCOFFObjectFile::sections32() const {
526 assert(!is64Bit() && "32-bit interface called for non 32-bit file.");
527 const XCOFFSectionHeader32
*TablePtr
= sectionHeaderTable32();
528 return ArrayRef
<XCOFFSectionHeader32
>(TablePtr
,
529 TablePtr
+ getNumberOfSections());
532 Expected
<XCOFFStringTable
>
533 XCOFFObjectFile::parseStringTable(const XCOFFObjectFile
*Obj
, uint64_t Offset
) {
534 // If there is a string table, then the buffer must contain at least 4 bytes
535 // for the string table's size. Not having a string table is not an error.
536 if (auto EC
= Binary::checkOffset(
537 Obj
->Data
, reinterpret_cast<uintptr_t>(Obj
->base() + Offset
), 4))
538 return XCOFFStringTable
{0, nullptr};
540 // Read the size out of the buffer.
541 uint32_t Size
= support::endian::read32be(Obj
->base() + Offset
);
543 // If the size is less then 4, then the string table is just a size and no
546 return XCOFFStringTable
{4, nullptr};
548 auto StringTableOrErr
=
549 getObject
<char>(Obj
->Data
, Obj
->base() + Offset
, Size
);
550 if (Error E
= StringTableOrErr
.takeError())
553 const char *StringTablePtr
= StringTableOrErr
.get();
554 if (StringTablePtr
[Size
- 1] != '\0')
555 return errorCodeToError(object_error::string_table_non_null_end
);
557 return XCOFFStringTable
{Size
, StringTablePtr
};
560 Expected
<std::unique_ptr
<XCOFFObjectFile
>>
561 XCOFFObjectFile::create(unsigned Type
, MemoryBufferRef MBR
) {
562 // Can't use std::make_unique because of the private constructor.
563 std::unique_ptr
<XCOFFObjectFile
> Obj
;
564 Obj
.reset(new XCOFFObjectFile(Type
, MBR
));
566 uint64_t CurOffset
= 0;
567 const auto *Base
= Obj
->base();
568 MemoryBufferRef Data
= Obj
->Data
;
570 // Parse file header.
571 auto FileHeaderOrErr
=
572 getObject
<void>(Data
, Base
+ CurOffset
, Obj
->getFileHeaderSize());
573 if (Error E
= FileHeaderOrErr
.takeError())
575 Obj
->FileHeader
= FileHeaderOrErr
.get();
577 CurOffset
+= Obj
->getFileHeaderSize();
578 // TODO FIXME we don't have support for an optional header yet, so just skip
580 CurOffset
+= Obj
->getOptionalHeaderSize();
582 // Parse the section header table if it is present.
583 if (Obj
->getNumberOfSections()) {
584 auto SecHeadersOrErr
= getObject
<void>(Data
, Base
+ CurOffset
,
585 Obj
->getNumberOfSections() *
586 Obj
->getSectionHeaderSize());
587 if (Error E
= SecHeadersOrErr
.takeError())
589 Obj
->SectionHeaderTable
= SecHeadersOrErr
.get();
592 // 64-bit object supports only file header and section headers for now.
594 return std::move(Obj
);
596 // If there is no symbol table we are done parsing the memory buffer.
597 if (Obj
->getLogicalNumberOfSymbolTableEntries32() == 0)
598 return std::move(Obj
);
600 // Parse symbol table.
601 CurOffset
= Obj
->fileHeader32()->SymbolTableOffset
;
602 uint64_t SymbolTableSize
= (uint64_t)(sizeof(XCOFFSymbolEntry
)) *
603 Obj
->getLogicalNumberOfSymbolTableEntries32();
605 getObject
<XCOFFSymbolEntry
>(Data
, Base
+ CurOffset
, SymbolTableSize
);
606 if (Error E
= SymTableOrErr
.takeError())
608 Obj
->SymbolTblPtr
= SymTableOrErr
.get();
609 CurOffset
+= SymbolTableSize
;
611 // Parse String table.
612 Expected
<XCOFFStringTable
> StringTableOrErr
=
613 parseStringTable(Obj
.get(), CurOffset
);
614 if (Error E
= StringTableOrErr
.takeError())
616 Obj
->StringTable
= StringTableOrErr
.get();
618 return std::move(Obj
);
621 Expected
<std::unique_ptr
<ObjectFile
>>
622 ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef
,
624 return XCOFFObjectFile::create(FileType
, MemBufRef
);
627 StringRef
XCOFFSectionHeader32::getName() const {
628 return generateXCOFFFixedNameStringRef(Name
);
631 StringRef
XCOFFSectionHeader64::getName() const {
632 return generateXCOFFFixedNameStringRef(Name
);
635 XCOFF::StorageClass
XCOFFSymbolRef::getStorageClass() const {
636 return OwningObjectPtr
->toSymbolEntry(SymEntDataRef
)->StorageClass
;
639 uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
640 return OwningObjectPtr
->toSymbolEntry(SymEntDataRef
)->NumberOfAuxEntries
;
643 const XCOFFCsectAuxEnt32
*XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
644 assert(!OwningObjectPtr
->is64Bit() &&
645 "32-bit interface called on 64-bit object file.");
646 assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
648 // In XCOFF32, the csect auxilliary entry is always the last auxiliary
649 // entry for the symbol.
650 uintptr_t AuxAddr
= getWithOffset(
651 SymEntDataRef
.p
, XCOFF::SymbolTableEntrySize
* getNumberOfAuxEntries());
654 OwningObjectPtr
->checkSymbolEntryPointer(AuxAddr
);
657 return reinterpret_cast<const XCOFFCsectAuxEnt32
*>(AuxAddr
);
660 uint16_t XCOFFSymbolRef::getType() const {
661 return OwningObjectPtr
->toSymbolEntry(SymEntDataRef
)->SymbolType
;
664 int16_t XCOFFSymbolRef::getSectionNumber() const {
665 return OwningObjectPtr
->toSymbolEntry(SymEntDataRef
)->SectionNumber
;
668 bool XCOFFSymbolRef::hasCsectAuxEnt() const {
669 XCOFF::StorageClass SC
= getStorageClass();
670 return (SC
== XCOFF::C_EXT
|| SC
== XCOFF::C_WEAKEXT
||
671 SC
== XCOFF::C_HIDEXT
);
674 bool XCOFFSymbolRef::isFunction() const {
675 if (OwningObjectPtr
->is64Bit())
676 report_fatal_error("64-bit support is unimplemented yet.");
678 if (getType() & FUNCTION_SYM
)
681 if (!hasCsectAuxEnt())
684 const XCOFFCsectAuxEnt32
*CsectAuxEnt
= getXCOFFCsectAuxEnt32();
686 // A function definition should be a label definition.
687 if ((CsectAuxEnt
->SymbolAlignmentAndType
& SYM_TYPE_MASK
) != XCOFF::XTY_LD
)
690 if (CsectAuxEnt
->StorageMappingClass
!= XCOFF::XMC_PR
)
693 int16_t SectNum
= getSectionNumber();
694 Expected
<DataRefImpl
> SI
= OwningObjectPtr
->getSectionByNum(SectNum
);
698 return (OwningObjectPtr
->getSectionFlags(SI
.get()) & XCOFF::STYP_TEXT
);
701 } // namespace object