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("vfp2", false);
198  Features.AddFeature("vfp3", false);
199  Features.AddFeature("vfp4", 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::DIV_use)) {
234  switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
235  default:
236  break;
238  Features.AddFeature("hwdiv", false);
239  Features.AddFeature("hwdiv-arm", false);
240  break;
242  Features.AddFeature("hwdiv");
243  Features.AddFeature("hwdiv-arm");
244  break;
245  }
246  }
247 
248  return Features;
249 }
250 
252  SubtargetFeatures Features;
253  unsigned PlatformFlags = getPlatformFlags();
254 
255  if (PlatformFlags & ELF::EF_RISCV_RVC) {
256  Features.AddFeature("c");
257  }
258 
259  return Features;
260 }
261 
263  switch (getEMachine()) {
264  case ELF::EM_MIPS:
265  return getMIPSFeatures();
266  case ELF::EM_ARM:
267  return getARMFeatures();
268  case ELF::EM_RISCV:
269  return getRISCVFeatures();
270  default:
271  return SubtargetFeatures();
272  }
273 }
274 
275 // FIXME Encode from a tablegen description or target parser.
276 void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
277  if (TheTriple.getSubArch() != Triple::NoSubArch)
278  return;
279 
280  ARMAttributeParser Attributes;
281  if (Error E = getBuildAttributes(Attributes))
282  return;
283 
284  std::string Triple;
285  // Default to ARM, but use the triple if it's been set.
286  if (TheTriple.isThumb())
287  Triple = "thumb";
288  else
289  Triple = "arm";
290 
291  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
292  switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
293  case ARMBuildAttrs::v4:
294  Triple += "v4";
295  break;
296  case ARMBuildAttrs::v4T:
297  Triple += "v4t";
298  break;
299  case ARMBuildAttrs::v5T:
300  Triple += "v5t";
301  break;
302  case ARMBuildAttrs::v5TE:
303  Triple += "v5te";
304  break;
306  Triple += "v5tej";
307  break;
308  case ARMBuildAttrs::v6:
309  Triple += "v6";
310  break;
311  case ARMBuildAttrs::v6KZ:
312  Triple += "v6kz";
313  break;
314  case ARMBuildAttrs::v6T2:
315  Triple += "v6t2";
316  break;
317  case ARMBuildAttrs::v6K:
318  Triple += "v6k";
319  break;
320  case ARMBuildAttrs::v7:
321  Triple += "v7";
322  break;
323  case ARMBuildAttrs::v6_M:
324  Triple += "v6m";
325  break;
327  Triple += "v6sm";
328  break;
330  Triple += "v7em";
331  break;
332  }
333  }
334  if (!isLittleEndian())
335  Triple += "eb";
336 
337  TheTriple.setArchName(Triple);
338 }
339 
340 std::vector<std::pair<DataRefImpl, uint64_t>>
342  std::string Err;
343  const auto Triple = makeTriple();
344  const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);
345  if (!T)
346  return {};
347  uint64_t JumpSlotReloc = 0;
348  switch (Triple.getArch()) {
349  case Triple::x86:
350  JumpSlotReloc = ELF::R_386_JUMP_SLOT;
351  break;
352  case Triple::x86_64:
353  JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
354  break;
355  case Triple::aarch64:
356  JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
357  break;
358  default:
359  return {};
360  }
361  std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
362  std::unique_ptr<const MCInstrAnalysis> MIA(
363  T->createMCInstrAnalysis(MII.get()));
364  if (!MIA)
365  return {};
366  Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None;
367  for (const SectionRef &Section : sections()) {
368  StringRef Name;
369  if (Section.getName(Name))
370  continue;
371  if (Name == ".plt")
372  Plt = Section;
373  else if (Name == ".rela.plt" || Name == ".rel.plt")
374  RelaPlt = Section;
375  else if (Name == ".got.plt")
376  GotPlt = Section;
377  }
378  if (!Plt || !RelaPlt || !GotPlt)
379  return {};
380  Expected<StringRef> PltContents = Plt->getContents();
381  if (!PltContents) {
382  consumeError(PltContents.takeError());
383  return {};
384  }
385  auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
386  arrayRefFromStringRef(*PltContents),
387  GotPlt->getAddress(), Triple);
388  // Build a map from GOT entry virtual address to PLT entry virtual address.
390  for (const auto &Entry : PltEntries)
391  GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
392  // Find the relocations in the dynamic relocation table that point to
393  // locations in the GOT for which we know the corresponding PLT entry.
394  std::vector<std::pair<DataRefImpl, uint64_t>> Result;
395  for (const auto &Relocation : RelaPlt->relocations()) {
396  if (Relocation.getType() != JumpSlotReloc)
397  continue;
398  auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
399  if (PltEntryIter != GotToPlt.end())
400  Result.push_back(std::make_pair(
401  Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
402  }
403  return Result;
404 }
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
static Error createError(StringRef Err)
Definition: ELF.h:47
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
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:297
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:294
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:363
std::vector< std::pair< DataRefImpl, uint64_t > > getPltAddresses() const
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:119
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:1192
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:138
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:688
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