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 
140*e1cb2c0fSFangrui Song Expected<ArrayRef<uint8_t>>
141*e1cb2c0fSFangrui Song XCOFFObjectFile::getSectionContents(DataRefImpl Sec) const {
142ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
143ab2eb2bfSHubert Tong }
144ab2eb2bfSHubert Tong 
145ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getSectionAlignment(DataRefImpl Sec) const {
146ab2eb2bfSHubert Tong   uint64_t Result = 0;
147ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
148ab2eb2bfSHubert Tong   return Result;
149ab2eb2bfSHubert Tong }
150ab2eb2bfSHubert Tong 
151ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionCompressed(DataRefImpl Sec) const {
152ab2eb2bfSHubert Tong   bool Result = false;
153ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
154ab2eb2bfSHubert Tong   return Result;
155ab2eb2bfSHubert Tong }
156ab2eb2bfSHubert Tong 
157ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionText(DataRefImpl Sec) const {
158a93a33cbSSean Fertile   return toSection(Sec)->Flags & XCOFF::STYP_TEXT;
159ab2eb2bfSHubert Tong }
160ab2eb2bfSHubert Tong 
161ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionData(DataRefImpl Sec) const {
162a93a33cbSSean Fertile   unsigned Flags = toSection(Sec)->Flags;
163a93a33cbSSean Fertile   return Flags & (XCOFF::STYP_DATA | XCOFF::STYP_TDATA);
164ab2eb2bfSHubert Tong }
165ab2eb2bfSHubert Tong 
166ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionBSS(DataRefImpl Sec) const {
167a93a33cbSSean Fertile   unsigned Flags = toSection(Sec)->Flags;
168a93a33cbSSean Fertile   return Flags & (XCOFF::STYP_BSS | XCOFF::STYP_TBSS);
169ab2eb2bfSHubert Tong }
170ab2eb2bfSHubert Tong 
171ab2eb2bfSHubert Tong bool XCOFFObjectFile::isSectionVirtual(DataRefImpl Sec) const {
172ab2eb2bfSHubert Tong   bool Result = false;
173ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
174ab2eb2bfSHubert Tong   return Result;
175ab2eb2bfSHubert Tong }
176ab2eb2bfSHubert Tong 
177ab2eb2bfSHubert Tong relocation_iterator XCOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
178ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
179ab2eb2bfSHubert Tong   return relocation_iterator(RelocationRef());
180ab2eb2bfSHubert Tong }
181ab2eb2bfSHubert Tong 
182ab2eb2bfSHubert Tong relocation_iterator XCOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
183ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
184ab2eb2bfSHubert Tong   return relocation_iterator(RelocationRef());
185ab2eb2bfSHubert Tong }
186ab2eb2bfSHubert Tong 
187ab2eb2bfSHubert Tong void XCOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
188ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
189ab2eb2bfSHubert Tong   return;
190ab2eb2bfSHubert Tong }
191ab2eb2bfSHubert Tong 
192ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
193ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
194ab2eb2bfSHubert Tong   uint64_t Result = 0;
195ab2eb2bfSHubert Tong   return Result;
196ab2eb2bfSHubert Tong }
197ab2eb2bfSHubert Tong 
198ab2eb2bfSHubert Tong symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
199ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
200ab2eb2bfSHubert Tong   return symbol_iterator(SymbolRef());
201ab2eb2bfSHubert Tong }
202ab2eb2bfSHubert Tong 
203ab2eb2bfSHubert Tong uint64_t XCOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
204ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
205ab2eb2bfSHubert Tong   uint64_t Result = 0;
206ab2eb2bfSHubert Tong   return Result;
207ab2eb2bfSHubert Tong }
208ab2eb2bfSHubert Tong 
209ab2eb2bfSHubert Tong void XCOFFObjectFile::getRelocationTypeName(
210ab2eb2bfSHubert Tong     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
211ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
212ab2eb2bfSHubert Tong   return;
213ab2eb2bfSHubert Tong }
214ab2eb2bfSHubert Tong 
215ab2eb2bfSHubert Tong uint32_t XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
216ab2eb2bfSHubert Tong   uint32_t Result = 0;
217ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
218ab2eb2bfSHubert Tong   return Result;
219ab2eb2bfSHubert Tong }
220ab2eb2bfSHubert Tong 
221ab2eb2bfSHubert Tong basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
222ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
223ab2eb2bfSHubert Tong   return basic_symbol_iterator(SymbolRef());
224ab2eb2bfSHubert Tong }
225ab2eb2bfSHubert Tong 
226ab2eb2bfSHubert Tong basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
227ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
228ab2eb2bfSHubert Tong   return basic_symbol_iterator(SymbolRef());
229ab2eb2bfSHubert Tong }
230ab2eb2bfSHubert Tong 
231ab2eb2bfSHubert Tong section_iterator XCOFFObjectFile::section_begin() const {
232a93a33cbSSean Fertile   DataRefImpl DRI;
233a93a33cbSSean Fertile   DRI.p = reinterpret_cast<uintptr_t>(SectionHdrTablePtr);
234a93a33cbSSean Fertile   return section_iterator(SectionRef(DRI, this));
235ab2eb2bfSHubert Tong }
236ab2eb2bfSHubert Tong 
237ab2eb2bfSHubert Tong section_iterator XCOFFObjectFile::section_end() const {
238a93a33cbSSean Fertile   DataRefImpl DRI;
239a93a33cbSSean Fertile   DRI.p =
240a93a33cbSSean Fertile       reinterpret_cast<uintptr_t>(SectionHdrTablePtr + getNumberOfSections());
241a93a33cbSSean Fertile   return section_iterator(SectionRef(DRI, this));
242ab2eb2bfSHubert Tong }
243ab2eb2bfSHubert Tong 
244ab2eb2bfSHubert Tong uint8_t XCOFFObjectFile::getBytesInAddress() const {
245fd75ee91SSean Fertile   // Only support 32-bit object files for now ...
246fd75ee91SSean Fertile   assert(getFileHeaderSize() ==  XCOFF32FileHeaderSize);
247fd75ee91SSean Fertile   return 4;
248ab2eb2bfSHubert Tong }
249ab2eb2bfSHubert Tong 
250ab2eb2bfSHubert Tong StringRef XCOFFObjectFile::getFileFormatName() const {
251a93a33cbSSean Fertile   assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
252a93a33cbSSean Fertile   return "aixcoff-rs6000";
253ab2eb2bfSHubert Tong }
254ab2eb2bfSHubert Tong 
255ab2eb2bfSHubert Tong Triple::ArchType XCOFFObjectFile::getArch() const {
256a93a33cbSSean Fertile   assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
257a93a33cbSSean Fertile   return Triple::ppc;
258ab2eb2bfSHubert Tong }
259ab2eb2bfSHubert Tong 
260ab2eb2bfSHubert Tong SubtargetFeatures XCOFFObjectFile::getFeatures() const {
261ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
262ab2eb2bfSHubert Tong   return SubtargetFeatures();
263ab2eb2bfSHubert Tong }
264ab2eb2bfSHubert Tong 
265ab2eb2bfSHubert Tong bool XCOFFObjectFile::isRelocatableObject() const {
266ab2eb2bfSHubert Tong   bool Result = false;
267ab2eb2bfSHubert Tong   llvm_unreachable("Not yet implemented!");
268ab2eb2bfSHubert Tong   return Result;
269ab2eb2bfSHubert Tong }
270ab2eb2bfSHubert Tong 
271a93a33cbSSean Fertile Expected<uint64_t> XCOFFObjectFile::getStartAddress() const {
272a93a33cbSSean Fertile   // TODO FIXME Should get from auxiliary_header->o_entry when support for the
273a93a33cbSSean Fertile   // auxiliary_header is added.
274a93a33cbSSean Fertile   return 0;
275a93a33cbSSean Fertile }
276a93a33cbSSean Fertile 
277ab2eb2bfSHubert Tong XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
278ab2eb2bfSHubert Tong     : ObjectFile(Binary::ID_XCOFF32, Object) {
279ab2eb2bfSHubert Tong 
280ab2eb2bfSHubert Tong   // Current location within the file.
281ab2eb2bfSHubert Tong   uint64_t CurPtr = 0;
282ab2eb2bfSHubert Tong 
283ab2eb2bfSHubert Tong   if ((EC = getObject(FileHdrPtr, Data, base() + CurPtr)))
284ab2eb2bfSHubert Tong     return;
285a93a33cbSSean Fertile 
286a93a33cbSSean Fertile   CurPtr += getFileHeaderSize();
287a93a33cbSSean Fertile   // TODO FIXME we don't have support for an optional header yet, so just skip
288a93a33cbSSean Fertile   // past it.
289a93a33cbSSean Fertile   CurPtr += FileHdrPtr->AuxHeaderSize;
290a93a33cbSSean Fertile 
291a93a33cbSSean Fertile   if (getNumberOfSections() != 0) {
292a93a33cbSSean Fertile     if ((EC = getObject(SectionHdrTablePtr, Data, base() + CurPtr,
293a93a33cbSSean Fertile                         getNumberOfSections() * getSectionHeaderSize())))
294a93a33cbSSean Fertile       return;
295a93a33cbSSean Fertile   }
296ab2eb2bfSHubert Tong }
297ab2eb2bfSHubert Tong 
298fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getMagic() const {
299fd75ee91SSean Fertile   return FileHdrPtr->Magic;
300fd75ee91SSean Fertile }
301fd75ee91SSean Fertile 
302fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getNumberOfSections() const {
303fd75ee91SSean Fertile   return FileHdrPtr->NumberOfSections;
304fd75ee91SSean Fertile }
305fd75ee91SSean Fertile 
306fd75ee91SSean Fertile int32_t XCOFFObjectFile::getTimeStamp() const {
307fd75ee91SSean Fertile   return FileHdrPtr->TimeStamp;
308fd75ee91SSean Fertile }
309fd75ee91SSean Fertile 
310fd75ee91SSean Fertile uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
311fd75ee91SSean Fertile   return FileHdrPtr->SymbolTableOffset;
312fd75ee91SSean Fertile }
313fd75ee91SSean Fertile 
314fd75ee91SSean Fertile int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
315fd75ee91SSean Fertile   // As far as symbol table size is concerned, if this field is negative it is
316fd75ee91SSean Fertile   // to be treated as a 0. However since this field is also used for printing we
317fd75ee91SSean Fertile   // don't want to truncate any negative values.
318fd75ee91SSean Fertile   return FileHdrPtr->NumberOfSymTableEntries;
319fd75ee91SSean Fertile }
320fd75ee91SSean Fertile 
321fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
322fd75ee91SSean Fertile   return FileHdrPtr->AuxHeaderSize;
323fd75ee91SSean Fertile }
324fd75ee91SSean Fertile 
325fd75ee91SSean Fertile uint16_t XCOFFObjectFile::getFlags() const {
326fd75ee91SSean Fertile   return FileHdrPtr->Flags;
327fd75ee91SSean Fertile }
328fd75ee91SSean Fertile 
329ab2eb2bfSHubert Tong Expected<std::unique_ptr<ObjectFile>>
330ab2eb2bfSHubert Tong ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object) {
331ab2eb2bfSHubert Tong   StringRef Data = Object.getBuffer();
332ab2eb2bfSHubert Tong   file_magic Type = identify_magic(Data);
333ab2eb2bfSHubert Tong   std::error_code EC;
334ab2eb2bfSHubert Tong   std::unique_ptr<ObjectFile> Ret;
335ab2eb2bfSHubert Tong 
336ab2eb2bfSHubert Tong   if (Type == file_magic::xcoff_object_32) {
337ab2eb2bfSHubert Tong     Ret.reset(new XCOFFObjectFile(Object, EC));
338ab2eb2bfSHubert Tong   } else {
339ab2eb2bfSHubert Tong     llvm_unreachable("Encountered an unexpected binary file type!");
340ab2eb2bfSHubert Tong   }
341ab2eb2bfSHubert Tong 
342ab2eb2bfSHubert Tong   if (EC)
343ab2eb2bfSHubert Tong     return errorCodeToError(EC);
344ab2eb2bfSHubert Tong   return std::move(Ret);
345ab2eb2bfSHubert Tong }
346ab2eb2bfSHubert Tong 
347ab2eb2bfSHubert Tong } // namespace object
348ab2eb2bfSHubert Tong } // namespace llvm
349