LLVM  6.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;
80  getPlatformFlags(PlatformFlags);
81 
82  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
84  break;
86  Features.AddFeature("mips2");
87  break;
89  Features.AddFeature("mips3");
90  break;
92  Features.AddFeature("mips4");
93  break;
95  Features.AddFeature("mips5");
96  break;
98  Features.AddFeature("mips32");
99  break;
101  Features.AddFeature("mips64");
102  break;
104  Features.AddFeature("mips32r2");
105  break;
107  Features.AddFeature("mips64r2");
108  break;
110  Features.AddFeature("mips32r6");
111  break;
113  Features.AddFeature("mips64r6");
114  break;
115  default:
116  llvm_unreachable("Unknown EF_MIPS_ARCH value");
117  }
118 
119  switch (PlatformFlags & ELF::EF_MIPS_MACH) {
121  // No feature associated with this value.
122  break;
124  Features.AddFeature("cnmips");
125  break;
126  default:
127  llvm_unreachable("Unknown EF_MIPS_ARCH value");
128  }
129 
130  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
131  Features.AddFeature("mips16");
132  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
133  Features.AddFeature("micromips");
134 
135  return Features;
136 }
137 
140  ARMAttributeParser Attributes;
141  std::error_code EC = getBuildAttributes(Attributes);
142  if (EC)
143  return SubtargetFeatures();
144 
145  // both ARMv7-M and R have to support thumb hardware div
146  bool isV7 = false;
147  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
148  isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
150 
154  Features.AddFeature("aclass");
155  break;
157  Features.AddFeature("rclass");
158  if (isV7)
159  Features.AddFeature("hwdiv");
160  break;
162  Features.AddFeature("mclass");
163  if (isV7)
164  Features.AddFeature("hwdiv");
165  break;
166  }
167  }
168 
169  if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
170  switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
171  default:
172  break;
174  Features.AddFeature("thumb", false);
175  Features.AddFeature("thumb2", false);
176  break;
178  Features.AddFeature("thumb2");
179  break;
180  }
181  }
182 
183  if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
184  switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
185  default:
186  break;
188  Features.AddFeature("vfp2", false);
189  Features.AddFeature("vfp3", false);
190  Features.AddFeature("vfp4", false);
191  break;
193  Features.AddFeature("vfp2");
194  break;
197  Features.AddFeature("vfp3");
198  break;
201  Features.AddFeature("vfp4");
202  break;
203  }
204  }
205 
208  default:
209  break;
211  Features.AddFeature("neon", false);
212  Features.AddFeature("fp16", false);
213  break;
215  Features.AddFeature("neon");
216  break;
218  Features.AddFeature("neon");
219  Features.AddFeature("fp16");
220  break;
221  }
222  }
223 
224  if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
225  switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
226  default:
227  break;
229  Features.AddFeature("hwdiv", false);
230  Features.AddFeature("hwdiv-arm", false);
231  break;
233  Features.AddFeature("hwdiv");
234  Features.AddFeature("hwdiv-arm");
235  break;
236  }
237  }
238 
239  return Features;
240 }
241 
243  switch (getEMachine()) {
244  case ELF::EM_MIPS:
245  return getMIPSFeatures();
246  case ELF::EM_ARM:
247  return getARMFeatures();
248  default:
249  return SubtargetFeatures();
250  }
251 }
252 
253 // FIXME Encode from a tablegen description or target parser.
254 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
255  if (TheTriple.getSubArch() != Triple::NoSubArch)
256  return;
257 
258  ARMAttributeParser Attributes;
259  std::error_code EC = getBuildAttributes(Attributes);
260  if (EC)
261  return;
262 
263  std::string Triple;
264  // Default to ARM, but use the triple if it's been set.
265  if (TheTriple.isThumb())
266  Triple = "thumb";
267  else
268  Triple = "arm";
269 
270  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
271  switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
272  case ARMBuildAttrs::v4:
273  Triple += "v4";
274  break;
275  case ARMBuildAttrs::v4T:
276  Triple += "v4t";
277  break;
278  case ARMBuildAttrs::v5T:
279  Triple += "v5t";
280  break;
281  case ARMBuildAttrs::v5TE:
282  Triple += "v5te";
283  break;
285  Triple += "v5tej";
286  break;
287  case ARMBuildAttrs::v6:
288  Triple += "v6";
289  break;
290  case ARMBuildAttrs::v6KZ:
291  Triple += "v6kz";
292  break;
293  case ARMBuildAttrs::v6T2:
294  Triple += "v6t2";
295  break;
296  case ARMBuildAttrs::v6K:
297  Triple += "v6k";
298  break;
299  case ARMBuildAttrs::v7:
300  Triple += "v7";
301  break;
302  case ARMBuildAttrs::v6_M:
303  Triple += "v6m";
304  break;
306  Triple += "v6sm";
307  break;
309  Triple += "v7em";
310  break;
311  }
312  }
313  if (!isLittleEndian())
314  Triple += "eb";
315 
316  TheTriple.setArchName(Triple);
317 }
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:189
static Error createError(StringRef Err)
Definition: ELF.h:47
unsigned getAttributeValue(unsigned Tag) const
virtual std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const
Definition: ObjectFile.h:296
void setARMSubArch(Triple &TheTriple) const override
StringRef getBuffer() const
Definition: MemoryBuffer.h:170
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:39
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:112
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:1147
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 std::error_code getPlatformFlags(unsigned &Result) const
Returns platform-specific object flags, if any.
Definition: ObjectFile.h:290
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:174
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
const FeatureBitset Features
SubtargetFeatures getARMFeatures() const