Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/lib/ReaderWriter/MachO/ArchHandler.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- lib/FileFormat/MachO/ArchHandler.cpp -------------------------------===//
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
10
#include "ArchHandler.h"
11
#include "Atoms.h"
12
#include "MachONormalizedFileBinaryUtils.h"
13
#include "llvm/ADT/StringRef.h"
14
#include "llvm/ADT/StringSwitch.h"
15
#include "llvm/ADT/Triple.h"
16
#include "llvm/Support/ErrorHandling.h"
17
18
using namespace llvm::MachO;
19
using namespace lld::mach_o::normalized;
20
21
namespace lld {
22
namespace mach_o {
23
24
25
403
ArchHandler::ArchHandler() {
26
403
}
27
28
403
ArchHandler::~ArchHandler() {
29
403
}
30
31
std::unique_ptr<mach_o::ArchHandler> ArchHandler::create(
32
403
                                               MachOLinkingContext::Arch arch) {
33
403
  switch (arch) {
34
403
  case MachOLinkingContext::arch_x86_64:
35
283
    return create_x86_64();
36
403
  case MachOLinkingContext::arch_x86:
37
52
    return create_x86();
38
403
  case MachOLinkingContext::arch_armv6:
39
33
  case MachOLinkingContext::arch_armv7:
40
33
  case MachOLinkingContext::arch_armv7s:
41
33
    return create_arm();
42
35
  case MachOLinkingContext::arch_arm64:
43
35
    return create_arm64();
44
33
  default:
45
0
    llvm_unreachable("Unknown arch");
46
403
  }
47
403
}
48
49
50
440
bool ArchHandler::isLazyPointer(const Reference &ref) {
51
440
  // A lazy bind entry is needed for a lazy pointer.
52
440
  const StubInfo &info = stubInfo();
53
440
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
54
0
    return false;
55
440
  if (ref.kindArch() != info.lazyPointerReferenceToFinal.arch)
56
0
    return false;
57
440
  return (ref.kindValue() == info.lazyPointerReferenceToFinal.kind);
58
440
}
59
60
61
632
ArchHandler::RelocPattern ArchHandler::relocPattern(const Relocation &reloc) {
62
632
  assert((reloc.type & 0xFFF0) == 0);
63
632
  uint16_t result = reloc.type;
64
632
  if (reloc.scattered)
65
154
    result |= rScattered;
66
632
  if (reloc.pcRel)
67
181
    result |= rPcRel;
68
632
  if (reloc.isExtern)
69
306
    result |= rExtern;
70
632
  switch(reloc.length) {
71
632
  case 0:
72
40
    break;
73
632
  case 1:
74
46
    result |= rLength2;
75
46
    break;
76
632
  case 2:
77
375
    result |= rLength4;
78
375
    break;
79
632
  case 3:
80
171
    result |= rLength8;
81
171
    break;
82
632
  default:
83
0
    llvm_unreachable("bad r_length");
84
632
  }
85
632
  return result;
86
632
}
87
88
normalized::Relocation
89
453
ArchHandler::relocFromPattern(ArchHandler::RelocPattern pattern) {
90
453
  normalized::Relocation result;
91
453
  result.offset    = 0;
92
453
  result.scattered = (pattern & rScattered);
93
453
  result.type     = (RelocationInfoType)(pattern & 0xF);
94
453
  result.pcRel    = (pattern & rPcRel);
95
453
  result.isExtern = (pattern & rExtern);
96
453
  result.value    = 0;
97
453
  result.symbol    = 0;
98
453
  switch (pattern & 0x300) {
99
453
  case rLength1:
100
32
    result.length = 0;
101
32
    break;
102
453
  case rLength2:
103
38
    result.length = 1;
104
38
    break;
105
453
  case rLength4:
106
262
    result.length = 2;
107
262
    break;
108
453
  case rLength8:
109
121
    result.length = 3;
110
121
    break;
111
453
  }
112
453
  return result;
113
453
}
114
115
void ArchHandler::appendReloc(normalized::Relocations &relocs, uint32_t offset,
116
                              uint32_t symbol, uint32_t value,
117
453
                              RelocPattern pattern) {
118
453
  normalized::Relocation reloc = relocFromPattern(pattern);
119
453
  reloc.offset = offset;
120
453
  reloc.symbol = symbol;
121
453
  reloc.value  = value;
122
453
  relocs.push_back(reloc);
123
453
}
124
125
126
0
int16_t ArchHandler::readS16(const uint8_t *addr, bool isBig) {
127
0
    return read16(addr, isBig);
128
0
}
129
130
0
int32_t ArchHandler::readS32(const uint8_t *addr, bool isBig) {
131
0
  return read32(addr, isBig);
132
0
}
133
134
0
uint32_t ArchHandler::readU32(const uint8_t *addr, bool isBig) {
135
0
  return read32(addr, isBig);
136
0
}
137
138
0
  int64_t ArchHandler::readS64(const uint8_t *addr, bool isBig) {
139
0
  return read64(addr, isBig);
140
0
}
141
142
70
bool ArchHandler::isDwarfCIE(bool isBig, const DefinedAtom *atom) {
143
70
  assert(atom->contentType() == DefinedAtom::typeCFI);
144
70
  if (atom->rawContent().size() < sizeof(uint32_t))
145
0
    return false;
146
70
  uint32_t size = read32(atom->rawContent().data(), isBig);
147
70
148
70
  uint32_t idOffset = sizeof(uint32_t);
149
70
  if (size == 0xffffffffU)
150
0
    idOffset += sizeof(uint64_t);
151
70
152
70
  return read32(atom->rawContent().data() + idOffset, isBig) == 0;
153
70
}
154
155
12
const Atom *ArchHandler::fdeTargetFunction(const DefinedAtom *fde) {
156
20
  for (auto ref : *fde) {
157
20
    if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
158
20
        ref->kindValue() == unwindRefToFunctionKind()) {
159
12
      assert(ref->kindArch() == kindArch() && "unexpected Reference arch");
160
12
      return ref->target();
161
12
    }
162
20
  }
163
12
164
12
  
return nullptr0
;
165
12
}
166
167
} // namespace mach_o
168
} // namespace lld
169
170
171