Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
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
#include "MCTargetDesc/ARMFixupKinds.h"
10
#include "MCTargetDesc/ARMMCTargetDesc.h"
11
#include "llvm/BinaryFormat/ELF.h"
12
#include "llvm/MC/MCContext.h"
13
#include "llvm/MC/MCELFObjectWriter.h"
14
#include "llvm/MC/MCExpr.h"
15
#include "llvm/MC/MCFixup.h"
16
#include "llvm/MC/MCObjectFileInfo.h"
17
#include "llvm/MC/MCObjectWriter.h"
18
#include "llvm/MC/MCValue.h"
19
#include "llvm/Support/ErrorHandling.h"
20
#include "llvm/Support/raw_ostream.h"
21
#include <cstdint>
22
23
using namespace llvm;
24
25
namespace {
26
27
  class ARMELFObjectWriter : public MCELFObjectTargetWriter {
28
    enum { DefaultEABIVersion = 0x05000000U };
29
30
    unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup,
31
                               bool IsPCRel, MCContext &Ctx) const;
32
33
  public:
34
    ARMELFObjectWriter(uint8_t OSABI);
35
36
3.38k
    ~ARMELFObjectWriter() override = default;
37
38
    unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39
                          const MCFixup &Fixup, bool IsPCRel) const override;
40
41
    bool needsRelocateWithSymbol(const MCSymbol &Sym,
42
                                 unsigned Type) const override;
43
44
    void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
45
  };
46
47
} // end anonymous namespace
48
49
ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
50
  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
51
                            ELF::EM_ARM,
52
3.40k
                            /*HasRelocationAddend*/ false) {}
53
54
bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
55
1.06k
                                                 unsigned Type) const {
56
1.06k
  // FIXME: This is extremely conservative. This really needs to use a
57
1.06k
  // whitelist with a clear explanation for why each realocation needs to
58
1.06k
  // point to the symbol, not to the section.
59
1.06k
  switch (Type) {
60
1.06k
  default:
61
89
    return true;
62
1.06k
63
1.06k
  case ELF::R_ARM_PREL31:
64
972
  case ELF::R_ARM_ABS32:
65
972
    return false;
66
1.06k
  }
67
1.06k
}
68
69
// Need to examine the Fixup when determining whether to
70
// emit the relocation as an explicit symbol or as a section relative
71
// offset
72
unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
73
                                          const MCFixup &Fixup,
74
2.57k
                                          bool IsPCRel) const {
75
2.57k
  return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx);
76
2.57k
}
77
78
unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
79
                                               const MCFixup &Fixup,
80
                                               bool IsPCRel,
81
2.57k
                                               MCContext &Ctx) const {
82
2.57k
  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
83
2.57k
84
2.57k
  if (IsPCRel) {
85
733
    switch ((unsigned)Fixup.getKind()) {
86
733
    default:
87
2
      Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
88
2
      return ELF::R_ARM_NONE;
89
733
    case FK_Data_4:
90
9
      switch (Modifier) {
91
9
      default:
92
0
        llvm_unreachable("Unsupported Modifier");
93
9
      case MCSymbolRefExpr::VK_None:
94
5
        return ELF::R_ARM_REL32;
95
9
      case MCSymbolRefExpr::VK_GOTTPOFF:
96
0
        return ELF::R_ARM_TLS_IE32;
97
9
      case MCSymbolRefExpr::VK_ARM_GOT_PREL:
98
0
        return ELF::R_ARM_GOT_PREL;
99
9
      case MCSymbolRefExpr::VK_ARM_PREL31:
100
4
        return ELF::R_ARM_PREL31;
101
0
      }
102
239
    case ARM::fixup_arm_blx:
103
239
    case ARM::fixup_arm_uncondbl:
104
239
      switch (Modifier) {
105
239
      case MCSymbolRefExpr::VK_PLT:
106
2
        return ELF::R_ARM_CALL;
107
239
      case MCSymbolRefExpr::VK_TLSCALL:
108
0
        return ELF::R_ARM_TLS_CALL;
109
239
      default:
110
237
        return ELF::R_ARM_CALL;
111
0
      }
112
38
    case ARM::fixup_arm_condbl:
113
38
    case ARM::fixup_arm_condbranch:
114
38
    case ARM::fixup_arm_uncondbranch:
115
38
      return ELF::R_ARM_JUMP24;
116
38
    case ARM::fixup_t2_condbranch:
117
21
      return ELF::R_ARM_THM_JUMP19;
118
40
    case ARM::fixup_t2_uncondbranch:
119
40
      return ELF::R_ARM_THM_JUMP24;
120
38
    case ARM::fixup_arm_movt_hi16:
121
8
      return ELF::R_ARM_MOVT_PREL;
122
38
    case ARM::fixup_arm_movw_lo16:
123
7
      return ELF::R_ARM_MOVW_PREL_NC;
124
38
    case ARM::fixup_t2_movt_hi16:
125
8
      return ELF::R_ARM_THM_MOVT_PREL;
126
38
    case ARM::fixup_t2_movw_lo16:
127
7
      return ELF::R_ARM_THM_MOVW_PREL_NC;
128
38
    case ARM::fixup_arm_thumb_br:
129
1
      return ELF::R_ARM_THM_JUMP11;
130
38
    case ARM::fixup_arm_thumb_bcc:
131
1
      return ELF::R_ARM_THM_JUMP8;
132
352
    case ARM::fixup_arm_thumb_bl:
133
352
    case ARM::fixup_arm_thumb_blx:
134
352
      switch (Modifier) {
135
352
      case MCSymbolRefExpr::VK_TLSCALL:
136
0
        return ELF::R_ARM_THM_TLS_CALL;
137
352
      default:
138
352
        return ELF::R_ARM_THM_CALL;
139
0
      }
140
0
    case ARM::fixup_bf_target:
141
0
      return ELF::R_ARM_THM_BF16;
142
0
    case ARM::fixup_bfc_target:
143
0
      return ELF::R_ARM_THM_BF12;
144
0
    case ARM::fixup_bfl_target:
145
0
      return ELF::R_ARM_THM_BF18;
146
1.84k
    }
147
1.84k
  }
148
1.84k
  switch ((unsigned)Fixup.getKind()) {
149
1.84k
  default:
150
2
    Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
151
2
    return ELF::R_ARM_NONE;
152
1.84k
  case FK_NONE:
153
7
    return ELF::R_ARM_NONE;
154
1.84k
  case FK_Data_1:
155
4
    switch (Modifier) {
156
4
    default:
157
0
      llvm_unreachable("unsupported Modifier");
158
4
    case MCSymbolRefExpr::VK_None:
159
4
      return ELF::R_ARM_ABS8;
160
0
    }
161
4
  case FK_Data_2:
162
4
    switch (Modifier) {
163
4
    default:
164
0
      llvm_unreachable("unsupported modifier");
165
4
    case MCSymbolRefExpr::VK_None:
166
4
      return ELF::R_ARM_ABS16;
167
0
    }
168
1.75k
  case FK_Data_4:
169
1.75k
    switch (Modifier) {
170
1.75k
    default:
171
0
      llvm_unreachable("Unsupported Modifier");
172
1.75k
    case MCSymbolRefExpr::VK_ARM_NONE:
173
460
      return ELF::R_ARM_NONE;
174
1.75k
    case MCSymbolRefExpr::VK_GOT:
175
11
      return ELF::R_ARM_GOT_BREL;
176
1.75k
    case MCSymbolRefExpr::VK_TLSGD:
177
17
      return ELF::R_ARM_TLS_GD32;
178
1.75k
    case MCSymbolRefExpr::VK_TPOFF:
179
8
      return ELF::R_ARM_TLS_LE32;
180
1.75k
    case MCSymbolRefExpr::VK_GOTTPOFF:
181
8
      return ELF::R_ARM_TLS_IE32;
182
1.75k
    case MCSymbolRefExpr::VK_None:
183
304
      return ELF::R_ARM_ABS32;
184
1.75k
    case MCSymbolRefExpr::VK_GOTOFF:
185
7
      return ELF::R_ARM_GOTOFF32;
186
1.75k
    case MCSymbolRefExpr::VK_ARM_GOT_PREL:
187
5
      return ELF::R_ARM_GOT_PREL;
188
1.75k
    case MCSymbolRefExpr::VK_ARM_TARGET1:
189
7
      return ELF::R_ARM_TARGET1;
190
1.75k
    case MCSymbolRefExpr::VK_ARM_TARGET2:
191
5
      return ELF::R_ARM_TARGET2;
192
1.75k
    case MCSymbolRefExpr::VK_ARM_PREL31:
193
892
      return ELF::R_ARM_PREL31;
194
1.75k
    case MCSymbolRefExpr::VK_ARM_SBREL:
195
8
      return ELF::R_ARM_SBREL32;
196
1.75k
    case MCSymbolRefExpr::VK_ARM_TLSLDO:
197
8
      return ELF::R_ARM_TLS_LDO32;
198
1.75k
    case MCSymbolRefExpr::VK_TLSCALL:
199
4
      return ELF::R_ARM_TLS_CALL;
200
1.75k
    case MCSymbolRefExpr::VK_TLSDESC:
201
5
      return ELF::R_ARM_TLS_GOTDESC;
202
1.75k
    case MCSymbolRefExpr::VK_TLSLDM:
203
6
      return ELF::R_ARM_TLS_LDM32;
204
1.75k
    case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
205
3
      return ELF::R_ARM_TLS_DESCSEQ;
206
0
    }
207
0
  case ARM::fixup_arm_condbranch:
208
0
  case ARM::fixup_arm_uncondbranch:
209
0
    return ELF::R_ARM_JUMP24;
210
19
  case ARM::fixup_arm_movt_hi16:
211
19
    switch (Modifier) {
212
19
    default:
213
0
      llvm_unreachable("Unsupported Modifier");
214
19
    case MCSymbolRefExpr::VK_None:
215
19
      return ELF::R_ARM_MOVT_ABS;
216
19
    case MCSymbolRefExpr::VK_ARM_SBREL:
217
0
      return ELF::R_ARM_MOVT_BREL;
218
0
    }
219
22
  case ARM::fixup_arm_movw_lo16:
220
22
    switch (Modifier) {
221
22
    default:
222
0
      llvm_unreachable("Unsupported Modifier");
223
22
    case MCSymbolRefExpr::VK_None:
224
22
      return ELF::R_ARM_MOVW_ABS_NC;
225
22
    case MCSymbolRefExpr::VK_ARM_SBREL:
226
0
      return ELF::R_ARM_MOVW_BREL_NC;
227
0
    }
228
12
  case ARM::fixup_t2_movt_hi16:
229
12
    switch (Modifier) {
230
12
    default:
231
0
      llvm_unreachable("Unsupported Modifier");
232
12
    case MCSymbolRefExpr::VK_None:
233
12
      return ELF::R_ARM_THM_MOVT_ABS;
234
12
    case MCSymbolRefExpr::VK_ARM_SBREL:
235
0
      return ELF::R_ARM_THM_MOVT_BREL;
236
0
    }
237
13
  case ARM::fixup_t2_movw_lo16:
238
13
    switch (Modifier) {
239
13
    default:
240
0
      llvm_unreachable("Unsupported Modifier");
241
13
    case MCSymbolRefExpr::VK_None:
242
13
      return ELF::R_ARM_THM_MOVW_ABS_NC;
243
13
    case MCSymbolRefExpr::VK_ARM_SBREL:
244
0
      return ELF::R_ARM_THM_MOVW_BREL_NC;
245
13
    }
246
1.84k
  }
247
1.84k
}
248
249
void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
250
1.76k
                                               MCSectionELF &Sec) {
251
1.76k
  // The mix of execute-only and non-execute-only at link time is
252
1.76k
  // non-execute-only. To avoid the empty implicitly created .text
253
1.76k
  // section from making the whole .text section non-execute-only, we
254
1.76k
  // mark it execute-only if it is empty and there is at least one
255
1.76k
  // execute-only section in the object.
256
1.76k
  MCSectionELF *TextSection =
257
1.76k
      static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
258
1.76k
  if (Sec.getKind().isExecuteOnly() && 
!TextSection->hasInstructions()7
&&
259
1.76k
      
!TextSection->hasData()2
) {
260
1
    TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
261
1
  }
262
1.76k
}
263
264
std::unique_ptr<MCObjectTargetWriter>
265
3.40k
llvm::createARMELFObjectWriter(uint8_t OSABI) {
266
3.40k
  return llvm::make_unique<ARMELFObjectWriter>(OSABI);
267
3.40k
}