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
4118ad2e54SAlexey Samsonov       return object_error::parse_failed;
4249179ddbSAlexey Samsonov   } else if (Ident.first == ELF::ELFCLASS64) {
43ac729b46SRafael Espindola     if (Ident.second == ELF::ELFDATA2LSB)
44ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
45ac729b46SRafael Espindola     else if (Ident.second == ELF::ELFDATA2MSB)
46ac729b46SRafael Espindola       R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
47ac729b46SRafael Espindola     else
4818ad2e54SAlexey Samsonov       return object_error::parse_failed;
4949179ddbSAlexey Samsonov   } else {
5049179ddbSAlexey Samsonov     return object_error::parse_failed;
51ac729b46SRafael Espindola   }
52692410efSRafael Espindola 
53692410efSRafael Espindola   if (EC)
54692410efSRafael Espindola     return EC;
55437b0d58SRafael Espindola   return std::move(R);
56b60a18deSMichael J. Spencer }
57b60a18deSMichael J. Spencer 
58*1d14864bSDaniel Sanders SubtargetFeatures ELFObjectFileBase::getFeatures() const {
59*1d14864bSDaniel Sanders   switch (getEMachine()) {
60*1d14864bSDaniel Sanders   case ELF::EM_MIPS: {
61*1d14864bSDaniel Sanders     SubtargetFeatures Features;
62*1d14864bSDaniel Sanders     unsigned PlatformFlags;
63*1d14864bSDaniel Sanders     getPlatformFlags(PlatformFlags);
64*1d14864bSDaniel Sanders 
65*1d14864bSDaniel Sanders     switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
66*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_1:
67*1d14864bSDaniel Sanders       break;
68*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_2:
69*1d14864bSDaniel Sanders       Features.AddFeature("mips2");
70*1d14864bSDaniel Sanders       break;
71*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_3:
72*1d14864bSDaniel Sanders       Features.AddFeature("mips3");
73*1d14864bSDaniel Sanders       break;
74*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_4:
75*1d14864bSDaniel Sanders       Features.AddFeature("mips4");
76*1d14864bSDaniel Sanders       break;
77*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_5:
78*1d14864bSDaniel Sanders       Features.AddFeature("mips5");
79*1d14864bSDaniel Sanders       break;
80*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_32:
81*1d14864bSDaniel Sanders       Features.AddFeature("mips32");
82*1d14864bSDaniel Sanders       break;
83*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_64:
84*1d14864bSDaniel Sanders       Features.AddFeature("mips64");
85*1d14864bSDaniel Sanders       break;
86*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_32R2:
87*1d14864bSDaniel Sanders       Features.AddFeature("mips32r2");
88*1d14864bSDaniel Sanders       break;
89*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_64R2:
90*1d14864bSDaniel Sanders       Features.AddFeature("mips64r2");
91*1d14864bSDaniel Sanders       break;
92*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_32R6:
93*1d14864bSDaniel Sanders       Features.AddFeature("mips32r6");
94*1d14864bSDaniel Sanders       break;
95*1d14864bSDaniel Sanders     case ELF::EF_MIPS_ARCH_64R6:
96*1d14864bSDaniel Sanders       Features.AddFeature("mips64r6");
97*1d14864bSDaniel Sanders       break;
98*1d14864bSDaniel Sanders     default:
99*1d14864bSDaniel Sanders       llvm_unreachable("Unknown EF_MIPS_ARCH value");
100*1d14864bSDaniel Sanders     }
101*1d14864bSDaniel Sanders 
102*1d14864bSDaniel Sanders     switch (PlatformFlags & ELF::EF_MIPS_MACH) {
103*1d14864bSDaniel Sanders     case ELF::EF_MIPS_MACH_NONE:
104*1d14864bSDaniel Sanders       // No feature associated with this value.
105*1d14864bSDaniel Sanders       break;
106*1d14864bSDaniel Sanders     case ELF::EF_MIPS_MACH_OCTEON:
107*1d14864bSDaniel Sanders       Features.AddFeature("cnmips");
108*1d14864bSDaniel Sanders       break;
109*1d14864bSDaniel Sanders     default:
110*1d14864bSDaniel Sanders       llvm_unreachable("Unknown EF_MIPS_ARCH value");
111*1d14864bSDaniel Sanders     }
112*1d14864bSDaniel Sanders 
113*1d14864bSDaniel Sanders     if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
114*1d14864bSDaniel Sanders       Features.AddFeature("mips16");
115*1d14864bSDaniel Sanders     if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
116*1d14864bSDaniel Sanders       Features.AddFeature("micromips");
117*1d14864bSDaniel Sanders 
118*1d14864bSDaniel Sanders     return Features;
119*1d14864bSDaniel Sanders   }
120*1d14864bSDaniel Sanders   default:
121*1d14864bSDaniel Sanders     return SubtargetFeatures();
122*1d14864bSDaniel Sanders   }
123*1d14864bSDaniel Sanders }
124*1d14864bSDaniel Sanders 
125b60a18deSMichael J. Spencer } // end namespace llvm
126