Coverage Report

Created: 2018-07-19 03:59

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCFixup.h
Line
Count
Source (jump to first uncovered line)
1
//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef LLVM_MC_MCFIXUP_H
11
#define LLVM_MC_MCFIXUP_H
12
13
#include "llvm/MC/MCExpr.h"
14
#include "llvm/Support/DataTypes.h"
15
#include "llvm/Support/ErrorHandling.h"
16
#include "llvm/Support/SMLoc.h"
17
#include <cassert>
18
19
namespace llvm {
20
class MCExpr;
21
22
/// Extensible enumeration to represent the type of a fixup.
23
enum MCFixupKind {
24
  FK_Data_1 = 0, ///< A one-byte fixup.
25
  FK_Data_2,     ///< A two-byte fixup.
26
  FK_Data_4,     ///< A four-byte fixup.
27
  FK_Data_8,     ///< A eight-byte fixup.
28
  FK_PCRel_1,    ///< A one-byte pc relative fixup.
29
  FK_PCRel_2,    ///< A two-byte pc relative fixup.
30
  FK_PCRel_4,    ///< A four-byte pc relative fixup.
31
  FK_PCRel_8,    ///< A eight-byte pc relative fixup.
32
  FK_GPRel_1,    ///< A one-byte gp relative fixup.
33
  FK_GPRel_2,    ///< A two-byte gp relative fixup.
34
  FK_GPRel_4,    ///< A four-byte gp relative fixup.
35
  FK_GPRel_8,    ///< A eight-byte gp relative fixup.
36
  FK_DTPRel_4,   ///< A four-byte dtp relative fixup.
37
  FK_DTPRel_8,   ///< A eight-byte dtp relative fixup.
38
  FK_TPRel_4,    ///< A four-byte tp relative fixup.
39
  FK_TPRel_8,    ///< A eight-byte tp relative fixup.
40
  FK_SecRel_1,   ///< A one-byte section relative fixup.
41
  FK_SecRel_2,   ///< A two-byte section relative fixup.
42
  FK_SecRel_4,   ///< A four-byte section relative fixup.
43
  FK_SecRel_8,   ///< A eight-byte section relative fixup.
44
  FK_Data_Add_1, ///< A one-byte add fixup.
45
  FK_Data_Add_2, ///< A two-byte add fixup.
46
  FK_Data_Add_4, ///< A four-byte add fixup.
47
  FK_Data_Add_8, ///< A eight-byte add fixup.
48
  FK_Data_Sub_1, ///< A one-byte sub fixup.
49
  FK_Data_Sub_2, ///< A two-byte sub fixup.
50
  FK_Data_Sub_4, ///< A four-byte sub fixup.
51
  FK_Data_Sub_8, ///< A eight-byte sub fixup.
52
53
  FirstTargetFixupKind = 128,
54
55
  // Limit range of target fixups, in case we want to pack more efficiently
56
  // later.
57
  MaxTargetFixupKind = (1 << 8)
58
};
59
60
/// Encode information on a single operation to perform on a byte
61
/// sequence (e.g., an encoded instruction) which requires assemble- or run-
62
/// time patching.
63
///
64
/// Fixups are used any time the target instruction encoder needs to represent
65
/// some value in an instruction which is not yet concrete. The encoder will
66
/// encode the instruction assuming the value is 0, and emit a fixup which
67
/// communicates to the assembler backend how it should rewrite the encoded
68
/// value.
69
///
70
/// During the process of relaxation, the assembler will apply fixups as
71
/// symbolic values become concrete. When relaxation is complete, any remaining
72
/// fixups become relocations in the object file (or errors, if the fixup cannot
73
/// be encoded on the target).
74
class MCFixup {
75
  /// The value to put into the fixup location. The exact interpretation of the
76
  /// expression is target dependent, usually it will be one of the operands to
77
  /// an instruction or an assembler directive.
78
  const MCExpr *Value;
79
80
  /// The byte index of start of the relocation inside the MCFragment.
81
  uint32_t Offset;
82
83
  /// The target dependent kind of fixup item this is. The kind is used to
84
  /// determine how the operand value should be encoded into the instruction.
85
  unsigned Kind;
86
87
  /// The source location which gave rise to the fixup, if any.
88
  SMLoc Loc;
89
public:
90
  static MCFixup create(uint32_t Offset, const MCExpr *Value,
91
5.97M
                        MCFixupKind Kind, SMLoc Loc = SMLoc()) {
92
5.97M
    assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
93
5.97M
    MCFixup FI;
94
5.97M
    FI.Value = Value;
95
5.97M
    FI.Offset = Offset;
96
5.97M
    FI.Kind = unsigned(Kind);
97
5.97M
    FI.Loc = Loc;
98
5.97M
    return FI;
99
5.97M
  }
100
101
  /// Return a fixup corresponding to the add half of a add/sub fixup pair for
102
  /// the given Fixup.
103
0
  static MCFixup createAddFor(const MCFixup &Fixup) {
104
0
    MCFixup FI;
105
0
    FI.Value = Fixup.getValue();
106
0
    FI.Offset = Fixup.getOffset();
107
0
    FI.Kind = (unsigned)getAddKindForKind(Fixup.getKind());
108
0
    FI.Loc = Fixup.getLoc();
109
0
    return FI;
110
0
  }
111
112
  /// Return a fixup corresponding to the sub half of a add/sub fixup pair for
113
  /// the given Fixup.
114
0
  static MCFixup createSubFor(const MCFixup &Fixup) {
115
0
    MCFixup FI;
116
0
    FI.Value = Fixup.getValue();
117
0
    FI.Offset = Fixup.getOffset();
118
0
    FI.Kind = (unsigned)getSubKindForKind(Fixup.getKind());
119
0
    FI.Loc = Fixup.getLoc();
120
0
    return FI;
121
0
  }
122
123
37.7M
  MCFixupKind getKind() const { return MCFixupKind(Kind); }
124
125
21.3M
  uint32_t getOffset() const { return Offset; }
126
4.23M
  void setOffset(uint32_t Value) { Offset = Value; }
127
128
6.58M
  const MCExpr *getValue() const { return Value; }
129
130
  /// Return the generic fixup kind for a value with the given size. It
131
  /// is an error to pass an unsupported size.
132
2.16M
  static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
133
2.16M
    switch (Size) {
134
2.16M
    
default: 0
llvm_unreachable0
("Invalid generic fixup size!");
135
2.16M
    
case 1: return isPCRel 459k
?
FK_PCRel_1201k
:
FK_Data_1258k
;
136
2.16M
    
case 2: return isPCRel 3.58k
?
FK_PCRel_26
:
FK_Data_23.57k
;
137
2.16M
    
case 4: return isPCRel 911k
?
FK_PCRel_4218k
:
FK_Data_4693k
;
138
2.16M
    
case 8: return isPCRel 791k
?
FK_PCRel_80
:
FK_Data_8791k
;
139
2.16M
    }
140
2.16M
  }
141
142
  /// Return the generic fixup kind for an addition with a given size. It
143
  /// is an error to pass an unsupported size.
144
0
  static MCFixupKind getAddKindForKind(unsigned Kind) {
145
0
    switch (Kind) {
146
0
    default: llvm_unreachable("Unknown type to convert!");
147
0
    case FK_Data_1: return FK_Data_Add_1;
148
0
    case FK_Data_2: return FK_Data_Add_2;
149
0
    case FK_Data_4: return FK_Data_Add_4;
150
0
    case FK_Data_8: return FK_Data_Add_8;
151
0
    }
152
0
  }
153
154
  /// Return the generic fixup kind for an subtraction with a given size. It
155
  /// is an error to pass an unsupported size.
156
0
  static MCFixupKind getSubKindForKind(unsigned Kind) {
157
0
    switch (Kind) {
158
0
    default: llvm_unreachable("Unknown type to convert!");
159
0
    case FK_Data_1: return FK_Data_Sub_1;
160
0
    case FK_Data_2: return FK_Data_Sub_2;
161
0
    case FK_Data_4: return FK_Data_Sub_4;
162
0
    case FK_Data_8: return FK_Data_Sub_8;
163
0
    }
164
0
  }
165
166
27.4k
  SMLoc getLoc() const { return Loc; }
167
};
168
169
} // End llvm namespace
170
171
#endif