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/ELFObjectFile.h"
15 #include "llvm/Support/MathExtras.h"
16
17 namespace llvm {
18 using namespace object;
19
ELFObjectFileBase(unsigned int Type,MemoryBufferRef Source)20 ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
21 : ObjectFile(Type, Source) {}
22
23 ErrorOr<std::unique_ptr<ObjectFile>>
createELFObjectFile(MemoryBufferRef Obj)24 ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
25 std::pair<unsigned char, unsigned char> Ident =
26 getElfArchType(Obj.getBuffer());
27 std::size_t MaxAlignment =
28 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
29
30 if (MaxAlignment < 2)
31 return object_error::parse_failed;
32
33 std::error_code EC;
34 std::unique_ptr<ObjectFile> R;
35 if (Ident.first == ELF::ELFCLASS32) {
36 if (Ident.second == ELF::ELFDATA2LSB)
37 R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
38 else if (Ident.second == ELF::ELFDATA2MSB)
39 R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
40 else
41 return object_error::parse_failed;
42 } else if (Ident.first == ELF::ELFCLASS64) {
43 if (Ident.second == ELF::ELFDATA2LSB)
44 R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
45 else if (Ident.second == ELF::ELFDATA2MSB)
46 R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
47 else
48 return object_error::parse_failed;
49 } else {
50 return object_error::parse_failed;
51 }
52
53 if (EC)
54 return EC;
55 return std::move(R);
56 }
57
getFeatures() const58 SubtargetFeatures ELFObjectFileBase::getFeatures() const {
59 switch (getEMachine()) {
60 case ELF::EM_MIPS: {
61 SubtargetFeatures Features;
62 unsigned PlatformFlags;
63 getPlatformFlags(PlatformFlags);
64
65 switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
66 case ELF::EF_MIPS_ARCH_1:
67 break;
68 case ELF::EF_MIPS_ARCH_2:
69 Features.AddFeature("mips2");
70 break;
71 case ELF::EF_MIPS_ARCH_3:
72 Features.AddFeature("mips3");
73 break;
74 case ELF::EF_MIPS_ARCH_4:
75 Features.AddFeature("mips4");
76 break;
77 case ELF::EF_MIPS_ARCH_5:
78 Features.AddFeature("mips5");
79 break;
80 case ELF::EF_MIPS_ARCH_32:
81 Features.AddFeature("mips32");
82 break;
83 case ELF::EF_MIPS_ARCH_64:
84 Features.AddFeature("mips64");
85 break;
86 case ELF::EF_MIPS_ARCH_32R2:
87 Features.AddFeature("mips32r2");
88 break;
89 case ELF::EF_MIPS_ARCH_64R2:
90 Features.AddFeature("mips64r2");
91 break;
92 case ELF::EF_MIPS_ARCH_32R6:
93 Features.AddFeature("mips32r6");
94 break;
95 case ELF::EF_MIPS_ARCH_64R6:
96 Features.AddFeature("mips64r6");
97 break;
98 default:
99 llvm_unreachable("Unknown EF_MIPS_ARCH value");
100 }
101
102 switch (PlatformFlags & ELF::EF_MIPS_MACH) {
103 case ELF::EF_MIPS_MACH_NONE:
104 // No feature associated with this value.
105 break;
106 case ELF::EF_MIPS_MACH_OCTEON:
107 Features.AddFeature("cnmips");
108 break;
109 default:
110 llvm_unreachable("Unknown EF_MIPS_ARCH value");
111 }
112
113 if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
114 Features.AddFeature("mips16");
115 if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
116 Features.AddFeature("micromips");
117
118 return Features;
119 }
120 default:
121 return SubtargetFeatures();
122 }
123 }
124
125 } // end namespace llvm
126