LLVM  7.0.0svn
ELFObjectFile.cpp
Go to the documentation of this file.
1 //===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
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 
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/Object/ELF.h"
19 #include "llvm/Object/ELFTypes.h"
20 #include "llvm/Object/Error.h"
23 #include "llvm/Support/Endian.h"
26 #include <algorithm>
27 #include <cstddef>
28 #include <cstdint>
29 #include <memory>
30 #include <string>
31 #include <system_error>
32 #include <utility>
33 
34 using namespace llvm;
35 using namespace object;
36 
38  : ObjectFile(Type, Source) {}
39 
40 template <class ELFT>
43  auto Ret = ELFObjectFile<ELFT>::create(Object);
44  if (Error E = Ret.takeError())
45  return std::move(E);
46  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
47 }
48 
51  std::pair<unsigned char, unsigned char> Ident =
53  std::size_t MaxAlignment =
54  1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
55 
56  if (MaxAlignment < 2)
57  return createError("Insufficient alignment");
58 
59  if (Ident.first == ELF::ELFCLASS32) {
60  if (Ident.second == ELF::ELFDATA2LSB)
61  return createPtr<ELF32LE>(Obj);
62  else if (Ident.second == ELF::ELFDATA2MSB)
63  return createPtr<ELF32BE>(Obj);
64  else
65  return createError("Invalid ELF data");
66  } else if (Ident.first == ELF::ELFCLASS64) {
67  if (Ident.second == ELF::ELFDATA2LSB)
68  return createPtr<ELF64LE>(Obj);
69  else if (Ident.second == ELF::ELFDATA2MSB)
70  return createPtr<ELF64BE>(Obj);
71  else
72  return createError("Invalid ELF data");
73  }
74  return createError("Invalid ELF class");
75 }
76 
79  unsigned PlatformFlags = getPlatformFlags();
80 
81  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
83  break;
85  Features.AddFeature("mips2");
86  break;
88  Features.AddFeature("mips3");
89  break;
91  Features.AddFeature("mips4");
92  break;
94  Features.AddFeature("mips5");
95  break;
97  Features.AddFeature("mips32");
98  break;
100  Features.AddFeature("mips64");
101  break;
103  Features.AddFeature("mips32r2");
104  break;
106  Features.AddFeature("mips64r2");
107  break;
109  Features.AddFeature("mips32r6");
110  break;
112  Features.AddFeature("mips64r6");
113  break;
114  default:
115  llvm_unreachable("Unknown EF_MIPS_ARCH value");
116  }
117 
118  switch (PlatformFlags & ELF::EF_MIPS_MACH) {
120  // No feature associated with this value.
121  break;
123  Features.AddFeature("cnmips");
124  break;
125  default:
126  llvm_unreachable("Unknown EF_MIPS_ARCH value");
127  }
128 
129  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
130  Features.AddFeature("mips16");
131  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
132  Features.AddFeature("micromips");
133 
134  return Features;
135 }
136 
139  ARMAttributeParser Attributes;
140  std::error_code EC = getBuildAttributes(Attributes);
141  if (EC)
142  return SubtargetFeatures();
143 
144  // both ARMv7-M and R have to support thumb hardware div
145  bool isV7 = false;
146  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
147  isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
149 
153  Features.AddFeature("aclass");
154  break;
156  Features.AddFeature("rclass");
157  if (isV7)
158  Features.AddFeature("hwdiv");
159  break;
161  Features.AddFeature("mclass");
162  if (isV7)
163  Features.AddFeature("hwdiv");
164  break;
165  }
166  }
167 
168  if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
169  switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
170  default:
171  break;
173  Features.AddFeature("thumb", false);
174  Features.AddFeature("thumb2", false);
175  break;
177  Features.AddFeature("thumb2");
178  break;
179  }
180  }
181 
182  if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
183  switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
184  default:
185  break;
187  Features.AddFeature("vfp2", false);
188  Features.AddFeature("vfp3", false);
189  Features.AddFeature("vfp4", false);
190  break;
192  Features.AddFeature("vfp2");
193  break;
196  Features.AddFeature("vfp3");
197  break;
200  Features.AddFeature("vfp4");
201  break;
202  }
203  }
204 
207  default:
208  break;
210  Features.AddFeature("neon", false);
211  Features.AddFeature("fp16", false);
212  break;
214  Features.AddFeature("neon");
215  break;
217  Features.AddFeature("neon");
218  Features.AddFeature("fp16");
219  break;
220  }
221  }
222 
223  if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
224  switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
225  default:
226  break;
228  Features.AddFeature("hwdiv", false);
229  Features.AddFeature("hwdiv-arm", false);
230  break;
232  Features.AddFeature("hwdiv");
233  Features.AddFeature("hwdiv-arm");
234  break;
235  }
236  }
237 
238  return Features;
239 }
240 
243  unsigned PlatformFlags = getPlatformFlags();
244 
245  if (PlatformFlags & ELF::EF_RISCV_RVC) {
246  Features.AddFeature("c");
247  }
248 
249  return Features;
250 }
251 
253  switch (getEMachine()) {
254  case ELF::EM_MIPS:
255  return getMIPSFeatures();
256  case ELF::EM_ARM:
257  return getARMFeatures();
258  case ELF::EM_RISCV:
259  return getRISCVFeatures();
260  default:
261  return SubtargetFeatures();
262  }
263 }
264 
265 // FIXME Encode from a tablegen description or target parser.
266 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
267  if (TheTriple.getSubArch() != Triple::NoSubArch)
268  return;
269 
270  ARMAttributeParser Attributes;
271  std::error_code EC = getBuildAttributes(Attributes);
272  if (EC)
273  return;
274 
275  std::string Triple;
276  // Default to ARM, but use the triple if it's been set.
277  if (TheTriple.isThumb())
278  Triple = "thumb";
279  else
280  Triple = "arm";
281 
282  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
283  switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
284  case ARMBuildAttrs::v4:
285  Triple += "v4";
286  break;
287  case ARMBuildAttrs::v4T:
288  Triple += "v4t";
289  break;
290  case ARMBuildAttrs::v5T:
291  Triple += "v5t";
292  break;
293  case ARMBuildAttrs::v5TE:
294  Triple += "v5te";
295  break;
297  Triple += "v5tej";
298  break;
299  case ARMBuildAttrs::v6:
300  Triple += "v6";
301  break;
302  case ARMBuildAttrs::v6KZ:
303  Triple += "v6kz";
304  break;
305  case ARMBuildAttrs::v6T2:
306  Triple += "v6t2";
307  break;
308  case ARMBuildAttrs::v6K:
309  Triple += "v6k";
310  break;
311  case ARMBuildAttrs::v7:
312  Triple += "v7";
313  break;
314  case ARMBuildAttrs::v6_M:
315  Triple += "v6m";
316  break;
318  Triple += "v6sm";
319  break;
321  Triple += "v7em";
322  break;
323  }
324  }
325  if (!isLittleEndian())
326  Triple += "eb";
327 
328  TheTriple.setArchName(Triple);
329 }
bool hasAttribute(unsigned Tag) const
virtual uint16_t getEMachine() const =0
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
SubtargetFeatures getFeatures() const override
This class is the base class for all object file types.
Definition: ObjectFile.h:190
static Error createError(StringRef Err)
Definition: ELF.h:48
unsigned getAttributeValue(unsigned Tag) const
virtual std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const
Definition: ObjectFile.h:298
void setARMSubArch(Triple &TheTriple) const override
StringRef getBuffer() const
Definition: MemoryBuffer.h:277
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
SubArchType getSubArch() const
getSubArch - get the parsed subarchitecture type for this triple.
Definition: Triple.h:288
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
Definition: ELF.h:40
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0&#39;s from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:120
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object)
void setArchName(StringRef Str)
setArchName - Set the architecture (first) component of the triple by name.
Definition: Triple.cpp:1149
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isLittleEndian() const
Definition: Binary.h:131
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
virtual unsigned getPlatformFlags() const =0
Returns platform-specific object flags, if any.
Manages the enabling and disabling of subtarget specific features.
SubtargetFeatures getMIPSFeatures() const
static Expected< std::unique_ptr< ELFObjectFile< ELFT > > > createPtr(MemoryBufferRef Object)
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
Definition: Triple.h:649
const char * getBufferStart() const
Definition: MemoryBuffer.h:281
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
const FeatureBitset Features
SubtargetFeatures getARMFeatures() const
SubtargetFeatures getRISCVFeatures() const