1218885Sdim//===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2218885Sdim//
3218885Sdim//                     The LLVM Compiler Infrastructure
4218885Sdim//
5218885Sdim// This file is distributed under the University of Illinois Open Source
6218885Sdim// License. See LICENSE.TXT for details.
7218885Sdim//
8218885Sdim//===----------------------------------------------------------------------===//
9218885Sdim//
10234353Sdim// Part of the ELFObjectFile class implementation.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14261991Sdim#include "llvm/Object/ELFObjectFile.h"
15249423Sdim#include "llvm/Support/MathExtras.h"
16218885Sdim
17234353Sdimnamespace llvm {
18218885Sdimusing namespace object;
19218885Sdim
20280031SdimELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
21280031Sdim    : ObjectFile(Type, Source) {}
22280031Sdim
23280031SdimErrorOr<std::unique_ptr<ObjectFile>>
24280031SdimObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
25276479Sdim  std::pair<unsigned char, unsigned char> Ident =
26280031Sdim      getElfArchType(Obj.getBuffer());
27249423Sdim  std::size_t MaxAlignment =
28280031Sdim      1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
29249423Sdim
30288943Sdim  if (MaxAlignment < 2)
31288943Sdim    return object_error::parse_failed;
32288943Sdim
33276479Sdim  std::error_code EC;
34276479Sdim  std::unique_ptr<ObjectFile> R;
35288943Sdim  if (Ident.first == ELF::ELFCLASS32) {
36288943Sdim    if (Ident.second == ELF::ELFDATA2LSB)
37288943Sdim      R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
38288943Sdim    else if (Ident.second == ELF::ELFDATA2MSB)
39288943Sdim      R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
40249423Sdim    else
41276479Sdim      return object_error::parse_failed;
42288943Sdim  } else if (Ident.first == ELF::ELFCLASS64) {
43288943Sdim    if (Ident.second == ELF::ELFDATA2LSB)
44288943Sdim      R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
45288943Sdim    else if (Ident.second == ELF::ELFDATA2MSB)
46288943Sdim      R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
47249423Sdim    else
48276479Sdim      return object_error::parse_failed;
49288943Sdim  } else {
50288943Sdim    return object_error::parse_failed;
51218885Sdim  }
52218885Sdim
53276479Sdim  if (EC)
54276479Sdim    return EC;
55280031Sdim  return std::move(R);
56226633Sdim}
57226633Sdim
58218885Sdim} // end namespace llvm
59