Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Object/ELFObjectFile.cpp
Line
Count
Source (jump to first uncovered line)
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
13
#include "llvm/Object/ELFObjectFile.h"
14
#include "llvm/ADT/Triple.h"
15
#include "llvm/BinaryFormat/ELF.h"
16
#include "llvm/MC/MCInstrAnalysis.h"
17
#include "llvm/MC/SubtargetFeature.h"
18
#include "llvm/Object/ELF.h"
19
#include "llvm/Object/ELFTypes.h"
20
#include "llvm/Object/Error.h"
21
#include "llvm/Support/ARMAttributeParser.h"
22
#include "llvm/Support/ARMBuildAttributes.h"
23
#include "llvm/Support/Endian.h"
24
#include "llvm/Support/ErrorHandling.h"
25
#include "llvm/Support/MathExtras.h"
26
#include "llvm/Support/TargetRegistry.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
38
const EnumEntry<unsigned> llvm::object::ElfSymbolTypes[NumElfSymbolTypes] = {
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
48
ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
49
24.1k
    : ObjectFile(Type, Source) {}
50
51
template <class ELFT>
52
static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
53
8.06k
createPtr(MemoryBufferRef Object) {
54
8.06k
  auto Ret = ELFObjectFile<ELFT>::create(Object);
55
8.06k
  if (Error E = Ret.takeError())
56
7
    return std::move(E);
57
8.06k
  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58
8.06k
}
ELFObjectFile.cpp:llvm::Expected<std::__1::unique_ptr<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)1, false> >, std::__1::default_delete<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)1, false> > > > > createPtr<llvm::object::ELFType<(llvm::support::endianness)1, false> >(llvm::MemoryBufferRef)
Line
Count
Source
53
1.47k
createPtr(MemoryBufferRef Object) {
54
1.47k
  auto Ret = ELFObjectFile<ELFT>::create(Object);
55
1.47k
  if (Error E = Ret.takeError())
56
0
    return std::move(E);
57
1.47k
  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58
1.47k
}
ELFObjectFile.cpp:llvm::Expected<std::__1::unique_ptr<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)0, false> >, std::__1::default_delete<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)0, false> > > > > createPtr<llvm::object::ELFType<(llvm::support::endianness)0, false> >(llvm::MemoryBufferRef)
Line
Count
Source
53
367
createPtr(MemoryBufferRef Object) {
54
367
  auto Ret = ELFObjectFile<ELFT>::create(Object);
55
367
  if (Error E = Ret.takeError())
56
0
    return std::move(E);
57
367
  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58
367
}
ELFObjectFile.cpp:llvm::Expected<std::__1::unique_ptr<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)1, true> >, std::__1::default_delete<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)1, true> > > > > createPtr<llvm::object::ELFType<(llvm::support::endianness)1, true> >(llvm::MemoryBufferRef)
Line
Count
Source
53
5.97k
createPtr(MemoryBufferRef Object) {
54
5.97k
  auto Ret = ELFObjectFile<ELFT>::create(Object);
55
5.97k
  if (Error E = Ret.takeError())
56
7
    return std::move(E);
57
5.96k
  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58
5.96k
}
ELFObjectFile.cpp:llvm::Expected<std::__1::unique_ptr<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)0, true> >, std::__1::default_delete<llvm::object::ELFObjectFile<llvm::object::ELFType<(llvm::support::endianness)0, true> > > > > createPtr<llvm::object::ELFType<(llvm::support::endianness)0, true> >(llvm::MemoryBufferRef)
Line
Count
Source
53
253
createPtr(MemoryBufferRef Object) {
54
253
  auto Ret = ELFObjectFile<ELFT>::create(Object);
55
253
  if (Error E = Ret.takeError())
56
0
    return std::move(E);
57
253
  return make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
58
253
}
59
60
Expected<std::unique_ptr<ObjectFile>>
61
8.07k
ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
62
8.07k
  std::pair<unsigned char, unsigned char> Ident =
63
8.07k
      getElfArchType(Obj.getBuffer());
64
8.07k
  std::size_t MaxAlignment =
65
8.07k
      1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
66
8.07k
67
8.07k
  if (MaxAlignment < 2)
68
1
    return createError("Insufficient alignment");
69
8.07k
70
8.07k
  if (Ident.first == ELF::ELFCLASS32) {
71
1.83k
    if (Ident.second == ELF::ELFDATA2LSB)
72
1.47k
      return createPtr<ELF32LE>(Obj);
73
367
    else if (Ident.second == ELF::ELFDATA2MSB)
74
367
      return createPtr<ELF32BE>(Obj);
75
0
    else
76
0
      return createError("Invalid ELF data");
77
6.23k
  } else if (Ident.first == ELF::ELFCLASS64) {
78
6.23k
    if (Ident.second == ELF::ELFDATA2LSB)
79
5.97k
      return createPtr<ELF64LE>(Obj);
80
256
    else if (Ident.second == ELF::ELFDATA2MSB)
81
253
      return createPtr<ELF64BE>(Obj);
82
3
    else
83
3
      return createError("Invalid ELF data");
84
2
  }
85
2
  return createError("Invalid ELF class");
86
2
}
87
88
126
SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
89
126
  SubtargetFeatures Features;
90
126
  unsigned PlatformFlags = getPlatformFlags();
91
126
92
126
  switch (PlatformFlags & ELF::EF_MIPS_ARCH) {
93
126
  case ELF::EF_MIPS_ARCH_1:
94
3
    break;
95
126
  case ELF::EF_MIPS_ARCH_2:
96
0
    Features.AddFeature("mips2");
97
0
    break;
98
126
  case ELF::EF_MIPS_ARCH_3:
99
0
    Features.AddFeature("mips3");
100
0
    break;
101
126
  case ELF::EF_MIPS_ARCH_4:
102
0
    Features.AddFeature("mips4");
103
0
    break;
104
126
  case ELF::EF_MIPS_ARCH_5:
105
0
    Features.AddFeature("mips5");
106
0
    break;
107
126
  case ELF::EF_MIPS_ARCH_32:
108
56
    Features.AddFeature("mips32");
109
56
    break;
110
126
  case ELF::EF_MIPS_ARCH_64:
111
24
    Features.AddFeature("mips64");
112
24
    break;
113
126
  case ELF::EF_MIPS_ARCH_32R2:
114
13
    Features.AddFeature("mips32r2");
115
13
    break;
116
126
  case ELF::EF_MIPS_ARCH_64R2:
117
8
    Features.AddFeature("mips64r2");
118
8
    break;
119
126
  case ELF::EF_MIPS_ARCH_32R6:
120
19
    Features.AddFeature("mips32r6");
121
19
    break;
122
126
  case ELF::EF_MIPS_ARCH_64R6:
123
3
    Features.AddFeature("mips64r6");
124
3
    break;
125
126
  default:
126
0
    llvm_unreachable("Unknown EF_MIPS_ARCH value");
127
126
  }
128
126
129
126
  switch (PlatformFlags & ELF::EF_MIPS_MACH) {
130
126
  case ELF::EF_MIPS_MACH_NONE:
131
126
    // No feature associated with this value.
132
126
    break;
133
126
  case ELF::EF_MIPS_MACH_OCTEON:
134
0
    Features.AddFeature("cnmips");
135
0
    break;
136
126
  default:
137
0
    llvm_unreachable("Unknown EF_MIPS_ARCH value");
138
126
  }
139
126
140
126
  if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16)
141
0
    Features.AddFeature("mips16");
142
126
  if (PlatformFlags & ELF::EF_MIPS_MICROMIPS)
143
29
    Features.AddFeature("micromips");
144
126
145
126
  return Features;
146
126
}
147
148
204
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
149
204
  SubtargetFeatures Features;
150
204
  ARMAttributeParser Attributes;
151
204
  if (Error E = getBuildAttributes(Attributes))
152
0
    return SubtargetFeatures();
153
204
154
204
  // both ARMv7-M and R have to support thumb hardware div
155
204
  bool isV7 = false;
156
204
  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch))
157
127
    isV7 = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)
158
127
      == ARMBuildAttrs::v7;
159
204
160
204
  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch_profile)) {
161
104
    switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile)) {
162
104
    case ARMBuildAttrs::ApplicationProfile:
163
98
      Features.AddFeature("aclass");
164
98
      break;
165
104
    case ARMBuildAttrs::RealTimeProfile:
166
1
      Features.AddFeature("rclass");
167
1
      if (isV7)
168
1
        Features.AddFeature("hwdiv");
169
1
      break;
170
104
    case ARMBuildAttrs::MicroControllerProfile:
171
5
      Features.AddFeature("mclass");
172
5
      if (isV7)
173
2
        Features.AddFeature("hwdiv");
174
5
      break;
175
204
    }
176
204
  }
177
204
178
204
  if (Attributes.hasAttribute(ARMBuildAttrs::THUMB_ISA_use)) {
179
123
    switch(Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use)) {
180
123
    default:
181
23
      break;
182
123
    case ARMBuildAttrs::Not_Allowed:
183
0
      Features.AddFeature("thumb", false);
184
0
      Features.AddFeature("thumb2", false);
185
0
      break;
186
123
    case ARMBuildAttrs::AllowThumb32:
187
100
      Features.AddFeature("thumb2");
188
100
      break;
189
204
    }
190
204
  }
191
204
192
204
  if (Attributes.hasAttribute(ARMBuildAttrs::FP_arch)) {
193
103
    switch(Attributes.getAttributeValue(ARMBuildAttrs::FP_arch)) {
194
103
    default:
195
1
      break;
196
103
    case ARMBuildAttrs::Not_Allowed:
197
3
      Features.AddFeature("vfp2d16sp", false);
198
3
      Features.AddFeature("vfp3d16sp", false);
199
3
      Features.AddFeature("vfp4d16sp", false);
200
3
      break;
201
103
    case ARMBuildAttrs::AllowFPv2:
202
1
      Features.AddFeature("vfp2");
203
1
      break;
204
103
    case ARMBuildAttrs::AllowFPv3A:
205
95
    case ARMBuildAttrs::AllowFPv3B:
206
95
      Features.AddFeature("vfp3");
207
95
      break;
208
95
    case ARMBuildAttrs::AllowFPv4A:
209
3
    case ARMBuildAttrs::AllowFPv4B:
210
3
      Features.AddFeature("vfp4");
211
3
      break;
212
204
    }
213
204
  }
214
204
215
204
  if (Attributes.hasAttribute(ARMBuildAttrs::Advanced_SIMD_arch)) {
216
96
    switch(Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch)) {
217
96
    default:
218
0
      break;
219
96
    case ARMBuildAttrs::Not_Allowed:
220
0
      Features.AddFeature("neon", false);
221
0
      Features.AddFeature("fp16", false);
222
0
      break;
223
96
    case ARMBuildAttrs::AllowNeon:
224
93
      Features.AddFeature("neon");
225
93
      break;
226
96
    case ARMBuildAttrs::AllowNeon2:
227
3
      Features.AddFeature("neon");
228
3
      Features.AddFeature("fp16");
229
3
      break;
230
204
    }
231
204
  }
232
204
233
204
  if (Attributes.hasAttribute(ARMBuildAttrs::MVE_arch)) {
234
0
    switch(Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch)) {
235
0
    default:
236
0
      break;
237
0
    case ARMBuildAttrs::Not_Allowed:
238
0
      Features.AddFeature("mve", false);
239
0
      Features.AddFeature("mve.fp", false);
240
0
      break;
241
0
    case ARMBuildAttrs::AllowMVEInteger:
242
0
      Features.AddFeature("mve.fp", false);
243
0
      Features.AddFeature("mve");
244
0
      break;
245
0
    case ARMBuildAttrs::AllowMVEIntegerAndFloat:
246
0
      Features.AddFeature("mve.fp");
247
0
      break;
248
204
    }
249
204
  }
250
204
251
204
  if (Attributes.hasAttribute(ARMBuildAttrs::DIV_use)) {
252
3
    switch(Attributes.getAttributeValue(ARMBuildAttrs::DIV_use)) {
253
3
    default:
254
0
      break;
255
3
    case ARMBuildAttrs::DisallowDIV:
256
0
      Features.AddFeature("hwdiv", false);
257
0
      Features.AddFeature("hwdiv-arm", false);
258
0
      break;
259
3
    case ARMBuildAttrs::AllowDIVExt:
260
3
      Features.AddFeature("hwdiv");
261
3
      Features.AddFeature("hwdiv-arm");
262
3
      break;
263
204
    }
264
204
  }
265
204
266
204
  return Features;
267
204
}
268
269
166
SubtargetFeatures ELFObjectFileBase::getRISCVFeatures() const {
270
166
  SubtargetFeatures Features;
271
166
  unsigned PlatformFlags = getPlatformFlags();
272
166
273
166
  if (PlatformFlags & ELF::EF_RISCV_RVC) {
274
39
    Features.AddFeature("c");
275
39
  }
276
166
277
166
  return Features;
278
166
}
279
280
2.21k
SubtargetFeatures ELFObjectFileBase::getFeatures() const {
281
2.21k
  switch (getEMachine()) {
282
2.21k
  case ELF::EM_MIPS:
283
126
    return getMIPSFeatures();
284
2.21k
  case ELF::EM_ARM:
285
204
    return getARMFeatures();
286
2.21k
  case ELF::EM_RISCV:
287
166
    return getRISCVFeatures();
288
2.21k
  default:
289
1.72k
    return SubtargetFeatures();
290
2.21k
  }
291
2.21k
}
292
293
// FIXME Encode from a tablegen description or target parser.
294
227
void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
295
227
  if (TheTriple.getSubArch() != Triple::NoSubArch)
296
161
    return;
297
66
298
66
  ARMAttributeParser Attributes;
299
66
  if (Error E = getBuildAttributes(Attributes))
300
0
    return;
301
66
302
66
  std::string Triple;
303
66
  // Default to ARM, but use the triple if it's been set.
304
66
  if (TheTriple.isThumb())
305
6
    Triple = "thumb";
306
60
  else
307
60
    Triple = "arm";
308
66
309
66
  if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) {
310
28
    switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
311
28
    case ARMBuildAttrs::v4:
312
1
      Triple += "v4";
313
1
      break;
314
28
    case ARMBuildAttrs::v4T:
315
0
      Triple += "v4t";
316
0
      break;
317
28
    case ARMBuildAttrs::v5T:
318
4
      Triple += "v5t";
319
4
      break;
320
28
    case ARMBuildAttrs::v5TE:
321
1
      Triple += "v5te";
322
1
      break;
323
28
    case ARMBuildAttrs::v5TEJ:
324
0
      Triple += "v5tej";
325
0
      break;
326
28
    case ARMBuildAttrs::v6:
327
1
      Triple += "v6";
328
1
      break;
329
28
    case ARMBuildAttrs::v6KZ:
330
0
      Triple += "v6kz";
331
0
      break;
332
28
    case ARMBuildAttrs::v6T2:
333
1
      Triple += "v6t2";
334
1
      break;
335
28
    case ARMBuildAttrs::v6K:
336
1
      Triple += "v6k";
337
1
      break;
338
28
    case ARMBuildAttrs::v7:
339
18
      Triple += "v7";
340
18
      break;
341
28
    case ARMBuildAttrs::v6_M:
342
1
      Triple += "v6m";
343
1
      break;
344
28
    case ARMBuildAttrs::v6S_M:
345
0
      Triple += "v6sm";
346
0
      break;
347
28
    case ARMBuildAttrs::v7E_M:
348
0
      Triple += "v7em";
349
0
      break;
350
66
    }
351
66
  }
352
66
  if (!isLittleEndian())
353
0
    Triple += "eb";
354
66
355
66
  TheTriple.setArchName(Triple);
356
66
}
357
358
std::vector<std::pair<DataRefImpl, uint64_t>>
359
140
ELFObjectFileBase::getPltAddresses() const {
360
140
  std::string Err;
361
140
  const auto Triple = makeTriple();
362
140
  const auto *T = TargetRegistry::lookupTarget(Triple.str(), Err);
363
140
  if (!T)
364
0
    return {};
365
140
  uint64_t JumpSlotReloc = 0;
366
140
  switch (Triple.getArch()) {
367
140
    case Triple::x86:
368
15
      JumpSlotReloc = ELF::R_386_JUMP_SLOT;
369
15
      break;
370
140
    case Triple::x86_64:
371
29
      JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
372
29
      break;
373
140
    case Triple::aarch64:
374
29
      JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
375
29
      break;
376
140
    default:
377
67
      return {};
378
73
  }
379
73
  std::unique_ptr<const MCInstrInfo> MII(T->createMCInstrInfo());
380
73
  std::unique_ptr<const MCInstrAnalysis> MIA(
381
73
      T->createMCInstrAnalysis(MII.get()));
382
73
  if (!MIA)
383
0
    return {};
384
73
  Optional<SectionRef> Plt = None, RelaPlt = None, GotPlt = None;
385
1.12k
  for (const SectionRef &Section : sections()) {
386
1.12k
    StringRef Name;
387
1.12k
    if (Section.getName(Name))
388
0
      continue;
389
1.12k
    if (Name == ".plt")
390
64
      Plt = Section;
391
1.06k
    else if (Name == ".rela.plt" || 
Name == ".rel.plt"1.01k
)
392
64
      RelaPlt = Section;
393
998
    else if (Name == ".got.plt")
394
64
      GotPlt = Section;
395
1.12k
  }
396
73
  if (!Plt || 
!RelaPlt64
||
!GotPlt64
)
397
9
    return {};
398
64
  Expected<StringRef> PltContents = Plt->getContents();
399
64
  if (!PltContents) {
400
0
    consumeError(PltContents.takeError());
401
0
    return {};
402
0
  }
403
64
  auto PltEntries = MIA->findPltEntries(Plt->getAddress(),
404
64
                                        arrayRefFromStringRef(*PltContents),
405
64
                                        GotPlt->getAddress(), Triple);
406
64
  // Build a map from GOT entry virtual address to PLT entry virtual address.
407
64
  DenseMap<uint64_t, uint64_t> GotToPlt;
408
64
  for (const auto &Entry : PltEntries)
409
141
    GotToPlt.insert(std::make_pair(Entry.second, Entry.first));
410
64
  // Find the relocations in the dynamic relocation table that point to
411
64
  // locations in the GOT for which we know the corresponding PLT entry.
412
64
  std::vector<std::pair<DataRefImpl, uint64_t>> Result;
413
110
  for (const auto &Relocation : RelaPlt->relocations()) {
414
110
    if (Relocation.getType() != JumpSlotReloc)
415
19
      continue;
416
91
    auto PltEntryIter = GotToPlt.find(Relocation.getOffset());
417
91
    if (PltEntryIter != GotToPlt.end())
418
75
      Result.push_back(std::make_pair(
419
75
          Relocation.getSymbol()->getRawDataRefImpl(), PltEntryIter->second));
420
91
  }
421
64
  return Result;
422
64
}