LLVM  9.0.0svn
ELFObjectFile.cpp
Go to the documentation of this file.
1 //===- ELFObjectFile.cpp - ELF object file implementation -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Part of the ELFObjectFile class implementation.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/Triple.h"
15 #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"
27 #include <algorithm>
28 #include <cstddef>
29 #include <cstdint>
30 #include <memory>
31 #include <string>
32 #include <system_error>
33 #include <utility>
34 
35 using namespace llvm;
36 using namespace object;
37 
39  {"None", "NOTYPE", ELF::STT_NOTYPE},
40  {"Object", "OBJECT", ELF::STT_OBJECT},
41  {"Function", "FUNC", ELF::STT_FUNC},
42  {"Section", "SECTION", ELF::STT_SECTION},
43  {"File", "FILE", ELF::STT_FILE},
44  {"Common", "COMMON", ELF::STT_COMMON},
45  {"TLS", "TLS", ELF::STT_TLS},
46  {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}};
47 
49  : ObjectFile(Type, Source) {}
50 
51 template <class ELFT>
54  auto Ret = ELFObjectFile<ELFT>::create(Object);
55  if (Error E = Ret.takeError())
56  return std::move(E);
57  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58 }
59 
62  std::pair<unsigned char, unsigned char> Ident =
64  std::size_t MaxAlignment =
65  1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
66 
67  if (MaxAlignment < 2)
68  return createError("Insufficient alignment");
69 
70  if (Ident.first == ELF::ELFCLASS32) {
71  if (Ident.second == ELF::ELFDATA2LSB)
72  return createPtr<ELF32LE>(Obj);
73  else if (Ident.second == ELF::ELFDATA2MSB)
74  return createPtr<ELF32BE>(Obj);
75  else
76  return createError("Invalid ELF data");
77  } else if (Ident.first == ELF::ELFCLASS64) {
78  if (Ident.second == ELF::ELFDATA2LSB)
79  return createPtr<ELF64LE>(Obj);
80  else if (Ident.second == ELF::ELFDATA2MSB)
81  return createPtr<ELF64BE>(Obj);
82  else
83  return createError("Invalid ELF data");
84  }
85  return createError("Invalid ELF class");
86 }
87 
89  SubtargetFeatures Features;
90  unsigned PlatformFlags = getPlatformFlags();
91 
92  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
94  break;
96  Features.AddFeature("mips2");
97  break;
99  Features.AddFeature("mips3");
100  break;
101  case ELF::EF_MIPS_ARCH_4:
102  Features.AddFeature("mips4");
103  break;
104  case ELF::EF_MIPS_ARCH_5:
105  Features.AddFeature("mips5");
106  break;
108  Features.AddFeature("mips32");
109  break;
111  Features.AddFeature("mips64");
112  break;
114  Features.AddFeature("mips32r2");
115  break;
117  Features.AddFeature("mips64r2");
118  break;
120  Features.AddFeature("mips32r6");
121  break;
123  Features.AddFeature("mips64r6");
124  break;
125  default:
126  llvm_unreachable("Unknown EF_MIPS_ARCH value");
127  }
128 
129  switch (PlatformFlags & ELF::EF_MIPS_MACH) {
131  // No feature associated with this value.
132  break;
134  Features.AddFeature("cnmips");
135  break;
136  default:
137  llvm_unreachable("Unknown EF_MIPS_ARCH value");
138  }
139 
140  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
141  Features.AddFeature("mips16");
142  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
143  Features.AddFeature("micromips");
144 
145  return Features;
146 }
147 
149  SubtargetFeatures Features;
150  ARMAttributeParser Attributes;
151  if (Error E = getBuildAttributes(Attributes))
152  return SubtargetFeatures();
153 
154  // both ARMv7-M and R have to support thumb hardware div
155  bool isV7 = false;
156  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
157  isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
159 
163  Features.AddFeature("aclass");
164  break;
166  Features.AddFeature("rclass");
167  if (isV7)
168  Features.AddFeature("hwdiv");
169  break;
171  Features.AddFeature("mclass");
172  if (isV7)
173  Features.AddFeature("hwdiv");
174  break;
175  }
176  }
177 
178  if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
179  switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
180  default:
181  break;
183  Features.AddFeature("thumb", false);
184  Features.AddFeature("thumb2", false);
185  break;
187  Features.AddFeature("thumb2");
188  break;
189  }
190  }
191 
192  if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
193  switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
194  default:
195  break;
197  Features.AddFeature("vfp2d16sp", false);
198  Features.AddFeature("vfp3d16sp", false);
199  Features.AddFeature("vfp4d16sp", false);
200  break;
202  Features.AddFeature("vfp2");
203  break;
206  Features.AddFeature("vfp3");
207  break;
210  Features.AddFeature("vfp4");
211  break;
212  }
213  }
214 
217  default:
218  break;
220  Features.AddFeature("neon", false);
221  Features.AddFeature("fp16", false);
222  break;
224  Features.AddFeature("neon");
225  break;
227  Features.AddFeature("neon");
228  Features.AddFeature("fp16");
229  break;
230  }
231  }
232 
233  if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
234  switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
235  default:
236  break;
238  Features.AddFeature("mve", false);
239  Features.AddFeature("mve.fp", false);
240  break;
242  Features.AddFeature("mve.fp", false);
243  Features.AddFeature("mve");
244  break;
246  Features.AddFeature("mve.fp");
247  break;
248  }
249  }
250 
251  if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
252  switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
253  default:
254  break;
256  Features.AddFeature("hwdiv", false);
257  Features.AddFeature("hwdiv-arm", false);
258  break;
260  Features.AddFeature("hwdiv");
261  Features.AddFeature("hwdiv-arm");
262  break;
263  }
264  }
265 
266  return Features;
267 }
268 
270  SubtargetFeatures Features;
271  unsigned PlatformFlags = getPlatformFlags();
272 
273  if (PlatformFlags & ELF::EF_RISCV_RVC) {
274  Features.AddFeature("c");
275  }
276 
277  return Features;
278 }
279 
281  switch (getEMachine()) {
282  case ELF::EM_MIPS:
283  return getMIPSFeatures();
284  case ELF::EM_ARM:
285  return getARMFeatures();
286  case ELF::EM_RISCV:
287  return getRISCVFeatures();
288  default:
289  return SubtargetFeatures();
290  }
291 }
292 
293 // FIXME Encode from a tablegen description or target parser.
294 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
295  if (TheTriple.getSubArch() != Triple::NoSubArch)
296  return;
297 
298  ARMAttributeParser Attributes;
299  if (Error E = getBuildAttributes(Attributes))
300  return;
301 
302  std::string Triple;
303  // Default to ARM, but use the triple if it's been set.
304  if (TheTriple.isThumb())
305  Triple = "thumb";
306  else
307  Triple = "arm";
308 
309  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
310  switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
311  case ARMBuildAttrs::v4:
312  Triple += "v4";
313  break;
314  case ARMBuildAttrs::v4T:
315  Triple += "v4t";
316  break;
317  case ARMBuildAttrs::v5T:
318  Triple += "v5t";
319  break;
320  case ARMBuildAttrs::v5TE:
321  Triple += "v5te";
322  break;
324  Triple += "v5tej";
325  break;
326  case ARMBuildAttrs::v6:
327  Triple += "v6";
328  break;
329  case ARMBuildAttrs::v6KZ:
330  Triple += "v6kz";
331  break;
332  case ARMBuildAttrs::v6T2:
333  Triple += "v6t2";
334  break;
335  case ARMBuildAttrs::v6K:
336  Triple += "v6k";
337  break;
338  case ARMBuildAttrs::v7:
339  Triple += "v7";
340  break;
341  case ARMBuildAttrs::v6_M:
342  Triple += "v6m";
343  break;
345  Triple += "v6sm";
346  break;
348  Triple += "v7em";
349  break;
350  }
351  }
352  if (!isLittleEndian())
353  Triple += "eb";
354 
355  TheTriple.setArchName(Triple);
356 }
357 
358 std::vector<std::pair<DataRefImpl, uint64_t>>
360  std::string Err;
361  const auto Triple = makeTriple();
362  const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);
363  if (!T)
364  return {};
365  uint64_t JumpSlotReloc = 0;
366  switch (Triple.getArch()) {
367  case Triple::x86:
368  JumpSlotReloc = ELF::R_386_JUMP_SLOT;
369  break;
370  case Triple::x86_64:
371  JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
372  break;
373  case Triple::aarch64:
374  JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
375  break;
376  default:
377  return {};
378  }
379  std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
380  std::unique_ptr<const MCInstrAnalysis> MIA(
381  T->createMCInstrAnalysis(MII.get()));
382  if (!MIA)
383  return {};
384  Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None;
385  for (const SectionRef &Section : sections()) {
386  StringRef Name;
387  if (Section.getName(Name))
388  continue;
389  if (Name == ".plt")
390  Plt = Section;
391  else if (Name == ".rela.plt" || Name == ".rel.plt")
392  RelaPlt = Section;
393  else if (Name == ".got.plt")
394  GotPlt = Section;
395  }
396  if (!Plt || !RelaPlt || !GotPlt)
397  return {};
398  Expected<StringRef> PltContents = Plt->getContents();
399  if (!PltContents) {
400  consumeError(PltContents.takeError());
401  return {};
402  }
403  auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
404  arrayRefFromStringRef(*PltContents),
405  GotPlt->getAddress(), Triple);
406  // Build a map from GOT entry virtual address to PLT entry virtual address.
408  for (const auto &Entry : PltEntries)
409  GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
410  // Find the relocations in the dynamic relocation table that point to
411  // locations in the GOT for which we know the corresponding PLT entry.
412  std::vector<std::pair<DataRefImpl, uint64_t>> Result;
413  for (const auto &Relocation : RelaPlt->relocations()) {
414  if (Relocation.getType() != JumpSlotReloc)
415  continue;
416  auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
417  if (PltEntryIter != GotToPlt.end())
418  Result.push_back(std::make_pair(
419  Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
420  }
421  return Result;
422 }
const NoneType None
Definition: None.h:23
bool hasAttribute(unsigned Tag) const
virtual uint16_t getEMachine() const =0
This class represents lattice values for constants.
Definition: AllocatorList.h:23
SubtargetFeatures getFeatures() const override
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
Triple makeTriple() const
Create a triple from the data in this object file.
Definition: ObjectFile.cpp:89
This class is the base class for all object file types.
Definition: ObjectFile.h:226
ArrayRef< uint8_t > arrayRefFromStringRef(StringRef Input)
Construct a string ref from an array ref of unsigned chars.
Definition: StringExtras.h:60
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
unsigned getAttributeValue(unsigned Tag) const
unsigned 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:119
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:221
void setARMSubArch(Triple &TheTriple) const override
StringRef getBuffer() const
Definition: MemoryBuffer.h:272
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
SubArchType getSubArch() const
getSubArch - get the parsed subarchitecture type for this triple.
Definition: Triple.h:299
static Error createError(const Twine &Err)
Definition: ELF.h:47
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:296
virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const =0
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
Definition: ELF.h:39
section_iterator_range sections() const
Definition: ObjectFile.h:315
const llvm::EnumEntry< unsigned > ElfSymbolTypes[NumElfSymbolTypes]
constexpr int NumElfSymbolTypes
Definition: ELFObjectFile.h:44
const std::string & str() const
Definition: Triple.h:365
std::vector< std::pair< DataRefImpl, uint64_t > > getPltAddresses() const
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
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:1196
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object)
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isLittleEndian() const
Definition: Binary.h:140
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
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:694
const char * getBufferStart() const
Definition: MemoryBuffer.h:276
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
SubtargetFeatures getARMFeatures() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
SubtargetFeatures getRISCVFeatures() const
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81