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