Coverage Report

Created: 2018-06-18 20:01

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/Arch/Hexagon.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Hexagon.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
#include "InputFiles.h"
11
#include "Symbols.h"
12
#include "Target.h"
13
#include "lld/Common/ErrorHandler.h"
14
#include "llvm/BinaryFormat/ELF.h"
15
#include "llvm/Object/ELF.h"
16
#include "llvm/Support/Endian.h"
17
18
using namespace llvm;
19
using namespace llvm::object;
20
using namespace llvm::support::endian;
21
using namespace llvm::ELF;
22
using namespace lld;
23
using namespace lld::elf;
24
25
namespace {
26
class Hexagon final : public TargetInfo {
27
public:
28
  uint32_t calcEFlags() const override;
29
  RelExpr getRelExpr(RelType Type, const Symbol &S,
30
                     const uint8_t *Loc) const override;
31
  void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
32
};
33
} // namespace
34
35
// Support V60 only at the moment.
36
1
uint32_t Hexagon::calcEFlags() const { return 0x60; }
37
38
1
static uint32_t applyMask(uint32_t Mask, uint32_t Data) {
39
1
  uint32_t Result = 0;
40
1
  size_t Off = 0;
41
1
42
33
  for (size_t Bit = 0; Bit != 32; 
++Bit32
) {
43
32
    uint32_t ValBit = (Data >> Off) & 1;
44
32
    uint32_t MaskBit = (Mask >> Bit) & 1;
45
32
    if (MaskBit) {
46
22
      Result |= (ValBit << Bit);
47
22
      ++Off;
48
22
    }
49
32
  }
50
1
  return Result;
51
1
}
52
53
RelExpr Hexagon::getRelExpr(RelType Type, const Symbol &S,
54
1
                            const uint8_t *Loc) const {
55
1
  switch (Type) {
56
1
  case R_HEX_B22_PCREL:
57
1
    return R_PC;
58
1
  default:
59
0
    return R_ABS;
60
1
  }
61
1
}
62
63
1
static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
64
65
1
void Hexagon::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
66
1
  switch (Type) {
67
1
  case R_HEX_NONE:
68
0
    break;
69
1
  case R_HEX_B22_PCREL:
70
1
    or32le(Loc, applyMask(0x1ff3ffe, Val >> 2));
71
1
    break;
72
1
  default:
73
0
    error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
74
0
    break;
75
1
  }
76
1
}
77
78
1
TargetInfo *elf::getHexagonTargetInfo() {
79
1
  static Hexagon Target;
80
1
  return &Target;
81
1
}