1b60a18deSMichael J. Spencer //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2b60a18deSMichael J. Spencer //
3b60a18deSMichael J. Spencer //                     The LLVM Compiler Infrastructure
4b60a18deSMichael J. Spencer //
5b60a18deSMichael J. Spencer // This file is distributed under the University of Illinois Open Source
6b60a18deSMichael J. Spencer // License. See LICENSE.TXT for details.
7b60a18deSMichael J. Spencer //
8b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===//
9b60a18deSMichael J. Spencer //
10c7d23ddbSEli Bendersky // Part of the ELFObjectFile class implementation.
11b60a18deSMichael J. Spencer //
12b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===//
13b60a18deSMichael J. Spencer 
14126973baSMichael J. Spencer #include "llvm/Object/ELFObjectFile.h"
15bae14cefSMichael J. Spencer #include "llvm/Support/MathExtras.h"
16b60a18deSMichael J. Spencer 
17c7d23ddbSEli Bendersky namespace llvm {
18b60a18deSMichael J. Spencer using namespace object;
19b60a18deSMichael J. Spencer 
2048af1c2aSRafael Espindola ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
2148af1c2aSRafael Espindola     : ObjectFile(Type, Source) {}
22ab73774cSRafael Espindola 
23437b0d58SRafael Espindola ErrorOr<std::unique_ptr<ObjectFile>>
2448af1c2aSRafael Espindola ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
25d5a8efe7SRafael Espindola   std::pair<unsigned char, unsigned char> Ident =
2648af1c2aSRafael Espindola       getElfArchType(Obj.getBuffer());
27bae14cefSMichael J. Spencer   std::size_t MaxAlignment =
2848af1c2aSRafael Espindola       1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
29bae14cefSMichael J. Spencer 
30ac729b46SRafael Espindola   if (MaxAlignment < 2)
31ac729b46SRafael Espindola     return object_error::parse_failed;
32ac729b46SRafael Espindola 
33db4ed0bdSRafael Espindola   std::error_code EC;
3456440fd8SAhmed Charles   std::unique_ptr<ObjectFile> R;
35ac729b46SRafael Espindola   if (Ident.first == ELF::ELFCLASS32) {
36ac729b46SRafael Espindola     if (Ident.second == ELF::ELFDATA2LSB)
37ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
38ac729b46SRafael Espindola     else if (Ident.second == ELF::ELFDATA2MSB)
39ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
40692410efSRafael Espindola     else
41*18ad2e54SAlexey Samsonov       return object_error::parse_failed;
42ac729b46SRafael Espindola   } else {
43ac729b46SRafael Espindola     assert(Ident.first == ELF::ELFCLASS64);
44ac729b46SRafael Espindola     if (Ident.second == ELF::ELFDATA2LSB)
45ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
46ac729b46SRafael Espindola     else if (Ident.second == ELF::ELFDATA2MSB)
47ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
48ac729b46SRafael Espindola     else
49*18ad2e54SAlexey Samsonov       return object_error::parse_failed;
50ac729b46SRafael Espindola   }
51692410efSRafael Espindola 
52692410efSRafael Espindola   if (EC)
53692410efSRafael Espindola     return EC;
54437b0d58SRafael Espindola   return std::move(R);
55b60a18deSMichael J. Spencer }
56b60a18deSMichael J. Spencer 
57b60a18deSMichael J. Spencer } // end namespace llvm
58