1ab2eb2bfSHubert Tong //===--- XCOFFObjectFile.cpp - XCOFF object file implementation -----------===// 2ab2eb2bfSHubert Tong // 3ab2eb2bfSHubert Tong // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ab2eb2bfSHubert Tong // See https://llvm.org/LICENSE.txt for license information. 5ab2eb2bfSHubert Tong // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ab2eb2bfSHubert Tong // 7ab2eb2bfSHubert Tong //===----------------------------------------------------------------------===// 8ab2eb2bfSHubert Tong // 9ab2eb2bfSHubert Tong // This file defines the XCOFFObjectFile class. 10ab2eb2bfSHubert Tong // 11ab2eb2bfSHubert Tong //===----------------------------------------------------------------------===// 12ab2eb2bfSHubert Tong 13ab2eb2bfSHubert Tong #include "llvm/Object/XCOFFObjectFile.h" 14ab2eb2bfSHubert Tong #include "llvm/ADT/ArrayRef.h" 15ab2eb2bfSHubert Tong #include "llvm/Support/BinaryStreamReader.h" 16ab2eb2bfSHubert Tong #include "llvm/Support/Endian.h" 17ab2eb2bfSHubert Tong #include "llvm/Support/ErrorHandling.h" 18ab2eb2bfSHubert Tong #include "llvm/Support/MathExtras.h" 19ab2eb2bfSHubert Tong #include <cstddef> 20ab2eb2bfSHubert Tong #include <cstring> 21ab2eb2bfSHubert Tong 22ab2eb2bfSHubert Tong namespace llvm { 23ab2eb2bfSHubert Tong namespace object { 24ab2eb2bfSHubert Tong 25a93a33cbSSean Fertile enum { XCOFF32FileHeaderSize = 20 }; 26a93a33cbSSean Fertile static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize, 27a93a33cbSSean Fertile "Wrong size for XCOFF file header."); 28a93a33cbSSean Fertile 29ab2eb2bfSHubert Tong // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m. 30ab2eb2bfSHubert Tong // Returns unexpected_eof on error. 31ab2eb2bfSHubert Tong template <typename T> 32ab2eb2bfSHubert Tong static std::error_code getObject(const T *&Obj, MemoryBufferRef M, 33ab2eb2bfSHubert Tong const void *Ptr, 34ab2eb2bfSHubert Tong const uint64_t Size = sizeof(T)) { 35ab2eb2bfSHubert Tong uintptr_t Addr = uintptr_t(Ptr); 36ab2eb2bfSHubert Tong if (std::error_code EC = Binary::checkOffset(M, Addr, Size)) 37ab2eb2bfSHubert Tong return EC; 38ab2eb2bfSHubert Tong Obj = reinterpret_cast<const T *>(Addr); 39ab2eb2bfSHubert Tong return std::error_code(); 40ab2eb2bfSHubert Tong } 41ab2eb2bfSHubert Tong 42a93a33cbSSean Fertile template <typename T> static const T *viewAs(uintptr_t in) { 43a93a33cbSSean Fertile return reinterpret_cast<const T *>(in); 44a93a33cbSSean Fertile } 45a93a33cbSSean Fertile 46a93a33cbSSean Fertile const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const { 47a93a33cbSSean Fertile auto Sec = viewAs<XCOFFSectionHeader>(Ref.p); 48a93a33cbSSean Fertile #ifndef NDEBUG 49a93a33cbSSean Fertile if (Sec < SectionHdrTablePtr || 50a93a33cbSSean Fertile Sec >= (SectionHdrTablePtr + getNumberOfSections())) 51a93a33cbSSean Fertile report_fatal_error("Section header outside of section header table."); 52a93a33cbSSean Fertile 53a93a33cbSSean Fertile uintptr_t Offset = uintptr_t(Sec) - uintptr_t(SectionHdrTablePtr); 54a93a33cbSSean Fertile if (Offset % getSectionHeaderSize() != 0) 55a93a33cbSSean Fertile report_fatal_error( 56a93a33cbSSean Fertile "Section header pointer does not point to a valid section header."); 57a93a33cbSSean Fertile #endif 58a93a33cbSSean Fertile return Sec; 59a93a33cbSSean Fertile } 60a93a33cbSSean Fertile 61a93a33cbSSean Fertile // The next 2 functions are not exactly necessary yet, but they are useful to 62a93a33cbSSean Fertile // abstract over the size difference between XCOFF32 and XCOFF64 structure 63a93a33cbSSean Fertile // definitions. 64a93a33cbSSean Fertile size_t XCOFFObjectFile::getFileHeaderSize() const { 65a93a33cbSSean Fertile return sizeof(XCOFFFileHeader); 66a93a33cbSSean Fertile } 67a93a33cbSSean Fertile 68a93a33cbSSean Fertile size_t XCOFFObjectFile::getSectionHeaderSize() const { 69a93a33cbSSean Fertile return sizeof(XCOFFSectionHeader); 70a93a33cbSSean Fertile } 71a93a33cbSSean Fertile 72ab2eb2bfSHubert Tong void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 73ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 74ab2eb2bfSHubert Tong return; 75ab2eb2bfSHubert Tong } 76ab2eb2bfSHubert Tong 77ab2eb2bfSHubert Tong Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const { 78ab2eb2bfSHubert Tong StringRef Result; 79ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 80ab2eb2bfSHubert Tong return Result; 81ab2eb2bfSHubert Tong } 82ab2eb2bfSHubert Tong 83ab2eb2bfSHubert Tong Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const { 84ab2eb2bfSHubert Tong uint64_t Result = 0; 85ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 86ab2eb2bfSHubert Tong return Result; 87ab2eb2bfSHubert Tong } 88ab2eb2bfSHubert Tong 89ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { 90ab2eb2bfSHubert Tong uint64_t Result = 0; 91ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 92ab2eb2bfSHubert Tong return Result; 93ab2eb2bfSHubert Tong } 94ab2eb2bfSHubert Tong 95ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const { 96ab2eb2bfSHubert Tong uint64_t Result = 0; 97ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 98ab2eb2bfSHubert Tong return Result; 99ab2eb2bfSHubert Tong } 100ab2eb2bfSHubert Tong 101ab2eb2bfSHubert Tong Expected<SymbolRef::Type> 102ab2eb2bfSHubert Tong XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const { 103ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 104ab2eb2bfSHubert Tong return SymbolRef::ST_Other; 105ab2eb2bfSHubert Tong } 106ab2eb2bfSHubert Tong 107ab2eb2bfSHubert Tong Expected<section_iterator> 108ab2eb2bfSHubert Tong XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const { 109ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 110ab2eb2bfSHubert Tong return section_iterator(SectionRef()); 111ab2eb2bfSHubert Tong } 112ab2eb2bfSHubert Tong 113ab2eb2bfSHubert Tong void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const { 114a93a33cbSSean Fertile const char *Ptr = reinterpret_cast<const char *>(Sec.p); 115a93a33cbSSean Fertile Sec.p = reinterpret_cast<uintptr_t>(Ptr + getSectionHeaderSize()); 116ab2eb2bfSHubert Tong } 117ab2eb2bfSHubert Tong 1188be28cdcSFangrui Song Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const { 119a93a33cbSSean Fertile const char *Name = toSection(Sec)->Name; 120a93a33cbSSean Fertile auto NulCharPtr = 121a93a33cbSSean Fertile static_cast<const char *>(memchr(Name, '\0', XCOFF::SectionNameSize)); 1228be28cdcSFangrui Song return NulCharPtr ? StringRef(Name, NulCharPtr - Name) 123a93a33cbSSean Fertile : StringRef(Name, XCOFF::SectionNameSize); 124ab2eb2bfSHubert Tong } 125ab2eb2bfSHubert Tong 126ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const { 127a93a33cbSSean Fertile return toSection(Sec)->VirtualAddress; 128ab2eb2bfSHubert Tong } 129ab2eb2bfSHubert Tong 130ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSectionIndex(DataRefImpl Sec) const { 131a93a33cbSSean Fertile // Section numbers in XCOFF are numbered beginning at 1. A section number of 132a93a33cbSSean Fertile // zero is used to indicate that a symbol is being imported or is undefined. 133a93a33cbSSean Fertile return toSection(Sec) - SectionHdrTablePtr + 1; 134ab2eb2bfSHubert Tong } 135ab2eb2bfSHubert Tong 136ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSectionSize(DataRefImpl Sec) const { 137a93a33cbSSean Fertile return toSection(Sec)->SectionSize; 138ab2eb2bfSHubert Tong } 139ab2eb2bfSHubert Tong 140ab2eb2bfSHubert Tong std::error_code XCOFFObjectFile::getSectionContents(DataRefImpl Sec, 141ab2eb2bfSHubert Tong StringRef &Res) const { 142ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 143ab2eb2bfSHubert Tong return std::error_code(); 144ab2eb2bfSHubert Tong } 145ab2eb2bfSHubert Tong 146ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const { 147ab2eb2bfSHubert Tong uint64_t Result = 0; 148ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 149ab2eb2bfSHubert Tong return Result; 150ab2eb2bfSHubert Tong } 151ab2eb2bfSHubert Tong 152ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const { 153ab2eb2bfSHubert Tong bool Result = false; 154ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 155ab2eb2bfSHubert Tong return Result; 156ab2eb2bfSHubert Tong } 157ab2eb2bfSHubert Tong 158ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const { 159a93a33cbSSean Fertile return toSection(Sec)->Flags & XCOFF::STYP_TEXT; 160ab2eb2bfSHubert Tong } 161ab2eb2bfSHubert Tong 162ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const { 163a93a33cbSSean Fertile unsigned Flags = toSection(Sec)->Flags; 164a93a33cbSSean Fertile return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA); 165ab2eb2bfSHubert Tong } 166ab2eb2bfSHubert Tong 167ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const { 168a93a33cbSSean Fertile unsigned Flags = toSection(Sec)->Flags; 169a93a33cbSSean Fertile return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS); 170ab2eb2bfSHubert Tong } 171ab2eb2bfSHubert Tong 172ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const { 173ab2eb2bfSHubert Tong bool Result = false; 174ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 175ab2eb2bfSHubert Tong return Result; 176ab2eb2bfSHubert Tong } 177ab2eb2bfSHubert Tong 178ab2eb2bfSHubert Tong relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const { 179ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 180ab2eb2bfSHubert Tong return relocation_iterator(RelocationRef()); 181ab2eb2bfSHubert Tong } 182ab2eb2bfSHubert Tong 183ab2eb2bfSHubert Tong relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const { 184ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 185ab2eb2bfSHubert Tong return relocation_iterator(RelocationRef()); 186ab2eb2bfSHubert Tong } 187ab2eb2bfSHubert Tong 188ab2eb2bfSHubert Tong void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 189ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 190ab2eb2bfSHubert Tong return; 191ab2eb2bfSHubert Tong } 192ab2eb2bfSHubert Tong 193ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const { 194ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 195ab2eb2bfSHubert Tong uint64_t Result = 0; 196ab2eb2bfSHubert Tong return Result; 197ab2eb2bfSHubert Tong } 198ab2eb2bfSHubert Tong 199ab2eb2bfSHubert Tong symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { 200ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 201ab2eb2bfSHubert Tong return symbol_iterator(SymbolRef()); 202ab2eb2bfSHubert Tong } 203ab2eb2bfSHubert Tong 204ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const { 205ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 206ab2eb2bfSHubert Tong uint64_t Result = 0; 207ab2eb2bfSHubert Tong return Result; 208ab2eb2bfSHubert Tong } 209ab2eb2bfSHubert Tong 210ab2eb2bfSHubert Tong void XCOFFObjectFile::getRelocationTypeName( 211ab2eb2bfSHubert Tong DataRefImpl Rel, SmallVectorImpl<char> &Result) const { 212ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 213ab2eb2bfSHubert Tong return; 214ab2eb2bfSHubert Tong } 215ab2eb2bfSHubert Tong 216ab2eb2bfSHubert Tong uint32_t XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const { 217ab2eb2bfSHubert Tong uint32_t Result = 0; 218ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 219ab2eb2bfSHubert Tong return Result; 220ab2eb2bfSHubert Tong } 221ab2eb2bfSHubert Tong 222ab2eb2bfSHubert Tong basic_symbol_iterator XCOFFObjectFile::symbol_begin() const { 223ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 224ab2eb2bfSHubert Tong return basic_symbol_iterator(SymbolRef()); 225ab2eb2bfSHubert Tong } 226ab2eb2bfSHubert Tong 227ab2eb2bfSHubert Tong basic_symbol_iterator XCOFFObjectFile::symbol_end() const { 228ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 229ab2eb2bfSHubert Tong return basic_symbol_iterator(SymbolRef()); 230ab2eb2bfSHubert Tong } 231ab2eb2bfSHubert Tong 232ab2eb2bfSHubert Tong section_iterator XCOFFObjectFile::section_begin() const { 233a93a33cbSSean Fertile DataRefImpl DRI; 234a93a33cbSSean Fertile DRI.p = reinterpret_cast<uintptr_t>(SectionHdrTablePtr); 235a93a33cbSSean Fertile return section_iterator(SectionRef(DRI, this)); 236ab2eb2bfSHubert Tong } 237ab2eb2bfSHubert Tong 238ab2eb2bfSHubert Tong section_iterator XCOFFObjectFile::section_end() const { 239a93a33cbSSean Fertile DataRefImpl DRI; 240a93a33cbSSean Fertile DRI.p = 241a93a33cbSSean Fertile reinterpret_cast<uintptr_t>(SectionHdrTablePtr + getNumberOfSections()); 242a93a33cbSSean Fertile return section_iterator(SectionRef(DRI, this)); 243ab2eb2bfSHubert Tong } 244ab2eb2bfSHubert Tong 245ab2eb2bfSHubert Tong uint8_t XCOFFObjectFile::getBytesInAddress() const { 246*fd75ee91SSean Fertile // Only support 32-bit object files for now ... 247*fd75ee91SSean Fertile assert(getFileHeaderSize() == XCOFF32FileHeaderSize); 248*fd75ee91SSean Fertile return 4; 249ab2eb2bfSHubert Tong } 250ab2eb2bfSHubert Tong 251ab2eb2bfSHubert Tong StringRef XCOFFObjectFile::getFileFormatName() const { 252a93a33cbSSean Fertile assert(getFileHeaderSize() == XCOFF32FileHeaderSize); 253a93a33cbSSean Fertile return "aixcoff-rs6000"; 254ab2eb2bfSHubert Tong } 255ab2eb2bfSHubert Tong 256ab2eb2bfSHubert Tong Triple::ArchType XCOFFObjectFile::getArch() const { 257a93a33cbSSean Fertile assert(getFileHeaderSize() == XCOFF32FileHeaderSize); 258a93a33cbSSean Fertile return Triple::ppc; 259ab2eb2bfSHubert Tong } 260ab2eb2bfSHubert Tong 261ab2eb2bfSHubert Tong SubtargetFeatures XCOFFObjectFile::getFeatures() const { 262ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 263ab2eb2bfSHubert Tong return SubtargetFeatures(); 264ab2eb2bfSHubert Tong } 265ab2eb2bfSHubert Tong 266ab2eb2bfSHubert Tong bool XCOFFObjectFile::isRelocatableObject() const { 267ab2eb2bfSHubert Tong bool Result = false; 268ab2eb2bfSHubert Tong llvm_unreachable("Not yet implemented!"); 269ab2eb2bfSHubert Tong return Result; 270ab2eb2bfSHubert Tong } 271ab2eb2bfSHubert Tong 272a93a33cbSSean Fertile Expected<uint64_t> XCOFFObjectFile::getStartAddress() const { 273a93a33cbSSean Fertile // TODO FIXME Should get from auxiliary_header->o_entry when support for the 274a93a33cbSSean Fertile // auxiliary_header is added. 275a93a33cbSSean Fertile return 0; 276a93a33cbSSean Fertile } 277a93a33cbSSean Fertile 278ab2eb2bfSHubert Tong XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC) 279ab2eb2bfSHubert Tong : ObjectFile(Binary::ID_XCOFF32, Object) { 280ab2eb2bfSHubert Tong 281ab2eb2bfSHubert Tong // Current location within the file. 282ab2eb2bfSHubert Tong uint64_t CurPtr = 0; 283ab2eb2bfSHubert Tong 284ab2eb2bfSHubert Tong if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr))) 285ab2eb2bfSHubert Tong return; 286a93a33cbSSean Fertile 287a93a33cbSSean Fertile CurPtr += getFileHeaderSize(); 288a93a33cbSSean Fertile // TODO FIXME we don't have support for an optional header yet, so just skip 289a93a33cbSSean Fertile // past it. 290a93a33cbSSean Fertile CurPtr += FileHdrPtr->AuxHeaderSize; 291a93a33cbSSean Fertile 292a93a33cbSSean Fertile if (getNumberOfSections() != 0) { 293a93a33cbSSean Fertile if ((EC = getObject(SectionHdrTablePtr, Data, base() + CurPtr, 294a93a33cbSSean Fertile getNumberOfSections() * getSectionHeaderSize()))) 295a93a33cbSSean Fertile return; 296a93a33cbSSean Fertile } 297ab2eb2bfSHubert Tong } 298ab2eb2bfSHubert Tong 299*fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getMagic() const { 300*fd75ee91SSean Fertile return FileHdrPtr->Magic; 301*fd75ee91SSean Fertile } 302*fd75ee91SSean Fertile 303*fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getNumberOfSections() const { 304*fd75ee91SSean Fertile return FileHdrPtr->NumberOfSections; 305*fd75ee91SSean Fertile } 306*fd75ee91SSean Fertile 307*fd75ee91SSean Fertile int32_t XCOFFObjectFile::getTimeStamp() const { 308*fd75ee91SSean Fertile return FileHdrPtr->TimeStamp; 309*fd75ee91SSean Fertile } 310*fd75ee91SSean Fertile 311*fd75ee91SSean Fertile uint32_t XCOFFObjectFile::getSymbolTableOffset() const { 312*fd75ee91SSean Fertile return FileHdrPtr->SymbolTableOffset; 313*fd75ee91SSean Fertile } 314*fd75ee91SSean Fertile 315*fd75ee91SSean Fertile int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const { 316*fd75ee91SSean Fertile // As far as symbol table size is concerned, if this field is negative it is 317*fd75ee91SSean Fertile // to be treated as a 0. However since this field is also used for printing we 318*fd75ee91SSean Fertile // don't want to truncate any negative values. 319*fd75ee91SSean Fertile return FileHdrPtr->NumberOfSymTableEntries; 320*fd75ee91SSean Fertile } 321*fd75ee91SSean Fertile 322*fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getOptionalHeaderSize() const { 323*fd75ee91SSean Fertile return FileHdrPtr->AuxHeaderSize; 324*fd75ee91SSean Fertile } 325*fd75ee91SSean Fertile 326*fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getFlags() const { 327*fd75ee91SSean Fertile return FileHdrPtr->Flags; 328*fd75ee91SSean Fertile } 329*fd75ee91SSean Fertile 330ab2eb2bfSHubert Tong Expected<std::unique_ptr<ObjectFile>> 331ab2eb2bfSHubert Tong ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object) { 332ab2eb2bfSHubert Tong StringRef Data = Object.getBuffer(); 333ab2eb2bfSHubert Tong file_magic Type = identify_magic(Data); 334ab2eb2bfSHubert Tong std::error_code EC; 335ab2eb2bfSHubert Tong std::unique_ptr<ObjectFile> Ret; 336ab2eb2bfSHubert Tong 337ab2eb2bfSHubert Tong if (Type == file_magic::xcoff_object_32) { 338ab2eb2bfSHubert Tong Ret.reset(new XCOFFObjectFile(Object, EC)); 339ab2eb2bfSHubert Tong } else { 340ab2eb2bfSHubert Tong llvm_unreachable("Encountered an unexpected binary file type!"); 341ab2eb2bfSHubert Tong } 342ab2eb2bfSHubert Tong 343ab2eb2bfSHubert Tong if (EC) 344ab2eb2bfSHubert Tong return errorCodeToError(EC); 345ab2eb2bfSHubert Tong return std::move(Ret); 346ab2eb2bfSHubert Tong } 347ab2eb2bfSHubert Tong 348ab2eb2bfSHubert Tong } // namespace object 349ab2eb2bfSHubert Tong } // namespace llvm 350