1//===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Part of the ELFObjectFile class implementation.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Object/ELF.h"
15#include "llvm/Support/MathExtras.h"
16
17namespace llvm {
18
19using namespace object;
20
21// Creates an in-memory object-file by default: createELFObjectFile(Buffer)
22ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
23  std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
24  error_code ec;
25
26  std::size_t MaxAlignment =
27    1ULL << CountTrailingZeros_64(uintptr_t(Object->getBufferStart()));
28
29  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
30#if !LLVM_IS_UNALIGNED_ACCESS_FAST
31    if (MaxAlignment >= 4)
32      return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
33    else
34#endif
35    if (MaxAlignment >= 2)
36      return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
37    else
38      llvm_unreachable("Invalid alignment for ELF file!");
39  else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
40#if !LLVM_IS_UNALIGNED_ACCESS_FAST
41    if (MaxAlignment >= 4)
42      return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
43    else
44#endif
45    if (MaxAlignment >= 2)
46      return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
47    else
48      llvm_unreachable("Invalid alignment for ELF file!");
49  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
50#if !LLVM_IS_UNALIGNED_ACCESS_FAST
51    if (MaxAlignment >= 8)
52      return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
53    else
54#endif
55    if (MaxAlignment >= 2)
56      return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
57    else
58      llvm_unreachable("Invalid alignment for ELF file!");
59  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
60#if !LLVM_IS_UNALIGNED_ACCESS_FAST
61    if (MaxAlignment >= 8)
62      return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
63    else
64#endif
65    if (MaxAlignment >= 2)
66      return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
67    else
68      llvm_unreachable("Invalid alignment for ELF file!");
69  }
70
71  report_fatal_error("Buffer is not an ELF object file!");
72}
73
74} // end namespace llvm
75