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