Coverage Report

Created: 2019-05-22 02:55

/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
185
ArchHandler::ArchHandler() {
26
185
}
27
28
185
ArchHandler::~ArchHandler() {
29
185
}
30
31
std::unique_ptr<mach_o::ArchHandler> ArchHandler::create(
32
185
                                               MachOLinkingContext::Arch arch) {
33
185
  switch (arch) {
34
185
  case MachOLinkingContext::arch_x86_64:
35
128
    return create_x86_64();
36
185
  case MachOLinkingContext::arch_x86:
37
23
    return create_x86();
38
185
  case MachOLinkingContext::arch_armv6:
39
23
  case MachOLinkingContext::arch_armv7:
40
23
  case MachOLinkingContext::arch_armv7s:
41
23
    return create_arm();
42
23
  case MachOLinkingContext::arch_arm64:
43
11
    return create_arm64();
44
23
  default:
45
0
    llvm_unreachable("Unknown arch");
46
185
  }
47
185
}
48
49
50
190
bool ArchHandler::isLazyPointer(const Reference &ref) {
51
190
  // A lazy bind entry is needed for a lazy pointer.
52
190
  const StubInfo &info = stubInfo();
53
190
  if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
54
0
    return false;
55
190
  if (ref.kindArch() != info.lazyPointerReferenceToFinal.arch)
56
0
    return false;
57
190
  return (ref.kindValue() == info.lazyPointerReferenceToFinal.kind);
58
190
}
59
60
61
387
ArchHandler::RelocPattern ArchHandler::relocPattern(const Relocation &reloc) {
62
387
  assert((reloc.type & 0xFFF0) == 0);
63
387
  uint16_t result = reloc.type;
64
387
  if (reloc.scattered)
65
132
    result |= rScattered;
66
387
  if (reloc.pcRel)
67
97
    result |= rPcRel;
68
387
  if (reloc.isExtern)
69
136
    result |= rExtern;
70
387
  switch(reloc.length) {
71
387
  case 0:
72
40
    break;
73
387
  case 1:
74
43
    result |= rLength2;
75
43
    break;
76
387
  case 2:
77
219
    result |= rLength4;
78
219
    break;
79
387
  case 3:
80
85
    result |= rLength8;
81
85
    break;
82
387
  default:
83
0
    llvm_unreachable("bad r_length");
84
387
  }
85
387
  return result;
86
387
}
87
88
normalized::Relocation
89
289
ArchHandler::relocFromPattern(ArchHandler::RelocPattern pattern) {
90
289
  normalized::Relocation result;
91
289
  result.offset    = 0;
92
289
  result.scattered = (pattern & rScattered);
93
289
  result.type     = (RelocationInfoType)(pattern & 0xF);
94
289
  result.pcRel    = (pattern & rPcRel);
95
289
  result.isExtern = (pattern & rExtern);
96
289
  result.value    = 0;
97
289
  result.symbol    = 0;
98
289
  switch (pattern & 0x300) {
99
289
  case rLength1:
100
32
    result.length = 0;
101
32
    break;
102
289
  case rLength2:
103
35
    result.length = 1;
104
35
    break;
105
289
  case rLength4:
106
156
    result.length = 2;
107
156
    break;
108
289
  case rLength8:
109
66
    result.length = 3;
110
66
    break;
111
289
  }
112
289
  return result;
113
289
}
114
115
void ArchHandler::appendReloc(normalized::Relocations &relocs, uint32_t offset,
116
                              uint32_t symbol, uint32_t value,
117
289
                              RelocPattern pattern) {
118
289
  normalized::Relocation reloc = relocFromPattern(pattern);
119
289
  reloc.offset = offset;
120
289
  reloc.symbol = symbol;
121
289
  reloc.value  = value;
122
289
  relocs.push_back(reloc);
123
289
}
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
28
bool ArchHandler::isDwarfCIE(bool isBig, const DefinedAtom *atom) {
143
28
  assert(atom->contentType() == DefinedAtom::typeCFI);
144
28
  if (atom->rawContent().size() < sizeof(uint32_t))
145
0
    return false;
146
28
  uint32_t size = read32(atom->rawContent().data(), isBig);
147
28
148
28
  uint32_t idOffset = sizeof(uint32_t);
149
28
  if (size == 0xffffffffU)
150
0
    idOffset += sizeof(uint64_t);
151
28
152
28
  return read32(atom->rawContent().data() + idOffset, isBig) == 0;
153
28
}
154
155
6
const Atom *ArchHandler::fdeTargetFunction(const DefinedAtom *fde) {
156
8
  for (auto ref : *fde) {
157
8
    if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
158
8
        ref->kindValue() == unwindRefToFunctionKind()) {
159
6
      assert(ref->kindArch() == kindArch() && "unexpected Reference arch");
160
6
      return ref->target();
161
6
    }
162
8
  }
163
6
164
6
  
return nullptr0
;
165
6
}
166
167
} // namespace mach_o
168
} // namespace lld
169
170
171