Coverage Report

Created: 2017-09-21 03:39

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