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