Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
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
#include "MCTargetDesc/PPCFixupKinds.h"
11
#include "MCTargetDesc/PPCMCExpr.h"
12
#include "MCTargetDesc/PPCMCTargetDesc.h"
13
#include "llvm/ADT/STLExtras.h"
14
#include "llvm/MC/MCELFObjectWriter.h"
15
#include "llvm/MC/MCExpr.h"
16
#include "llvm/MC/MCSymbolELF.h"
17
#include "llvm/MC/MCValue.h"
18
#include "llvm/Support/ErrorHandling.h"
19
20
using namespace llvm;
21
22
namespace {
23
  class PPCELFObjectWriter : public MCELFObjectTargetWriter {
24
  public:
25
    PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
26
27
  protected:
28
    unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29
                          const MCFixup &Fixup, bool IsPCRel) const override;
30
31
    bool needsRelocateWithSymbol(const MCSymbol &Sym,
32
                                 unsigned Type) const override;
33
  };
34
}
35
36
PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
37
  : MCELFObjectTargetWriter(Is64Bit, OSABI,
38
                            Is64Bit ?  ELF::EM_PPC64 : ELF::EM_PPC,
39
70
                            /*HasRelocationAddend*/ true) {}
40
41
static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
42
491
                                                     const MCFixup &Fixup) {
43
491
  const MCExpr *Expr = Fixup.getValue();
44
491
45
491
  if (Expr->getKind() != MCExpr::Target)
46
433
    return Target.getAccessVariant();
47
58
48
58
  switch (cast<PPCMCExpr>(Expr)->getKind()) {
49
0
  case PPCMCExpr::VK_PPC_None:
50
0
    return MCSymbolRefExpr::VK_None;
51
21
  case PPCMCExpr::VK_PPC_LO:
52
21
    return MCSymbolRefExpr::VK_PPC_LO;
53
9
  case PPCMCExpr::VK_PPC_HI:
54
9
    return MCSymbolRefExpr::VK_PPC_HI;
55
16
  case PPCMCExpr::VK_PPC_HA:
56
16
    return MCSymbolRefExpr::VK_PPC_HA;
57
3
  case PPCMCExpr::VK_PPC_HIGHERA:
58
3
    return MCSymbolRefExpr::VK_PPC_HIGHERA;
59
3
  case PPCMCExpr::VK_PPC_HIGHER:
60
3
    return MCSymbolRefExpr::VK_PPC_HIGHER;
61
3
  case PPCMCExpr::VK_PPC_HIGHEST:
62
3
    return MCSymbolRefExpr::VK_PPC_HIGHEST;
63
3
  case PPCMCExpr::VK_PPC_HIGHESTA:
64
3
    return MCSymbolRefExpr::VK_PPC_HIGHESTA;
65
0
  }
66
0
  
llvm_unreachable0
("unknown PPCMCExpr kind");
67
0
}
68
69
unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
70
                                          const MCFixup &Fixup,
71
491
                                          bool IsPCRel) const {
72
491
  MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
73
491
74
491
  // determine the type of the relocation
75
491
  unsigned Type;
76
491
  if (
IsPCRel491
) {
77
82
    switch ((unsigned)Fixup.getKind()) {
78
0
    default:
79
0
      llvm_unreachable("Unimplemented");
80
30
    case PPC::fixup_ppc_br24:
81
30
    case PPC::fixup_ppc_br24abs:
82
30
      switch (Modifier) {
83
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
84
28
      case MCSymbolRefExpr::VK_None:
85
28
        Type = ELF::R_PPC_REL24;
86
28
        break;
87
1
      case MCSymbolRefExpr::VK_PLT:
88
1
        Type = ELF::R_PPC_PLTREL24;
89
1
        break;
90
1
      case MCSymbolRefExpr::VK_PPC_LOCAL:
91
1
        Type = ELF::R_PPC_LOCAL24PC;
92
1
        break;
93
30
      }
94
30
      break;
95
2
    case PPC::fixup_ppc_brcond14:
96
2
    case PPC::fixup_ppc_brcond14abs:
97
2
      Type = ELF::R_PPC_REL14;
98
2
      break;
99
17
    case PPC::fixup_ppc_half16:
100
17
      switch (Modifier) {
101
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
102
2
      case MCSymbolRefExpr::VK_None:
103
2
        Type = ELF::R_PPC_REL16;
104
2
        break;
105
6
      case MCSymbolRefExpr::VK_PPC_LO:
106
6
        Type = ELF::R_PPC_REL16_LO;
107
6
        break;
108
2
      case MCSymbolRefExpr::VK_PPC_HI:
109
2
        Type = ELF::R_PPC_REL16_HI;
110
2
        break;
111
7
      case MCSymbolRefExpr::VK_PPC_HA:
112
7
        Type = ELF::R_PPC_REL16_HA;
113
7
        break;
114
17
      }
115
17
      break;
116
1
    case PPC::fixup_ppc_half16ds:
117
1
      Target.print(errs());
118
1
      errs() << '\n';
119
1
      report_fatal_error("Invalid PC-relative half16ds relocation");
120
32
    case FK_Data_4:
121
32
    case FK_PCRel_4:
122
32
      Type = ELF::R_PPC_REL32;
123
32
      break;
124
0
    case FK_Data_8:
125
0
    case FK_PCRel_8:
126
0
      Type = ELF::R_PPC64_REL64;
127
0
      break;
128
491
    }
129
409
  } else {
130
409
    switch ((unsigned)Fixup.getKind()) {
131
0
      
default: 0
llvm_unreachable0
("invalid fixup kind!");
132
2
    case PPC::fixup_ppc_br24abs:
133
2
      Type = ELF::R_PPC_ADDR24;
134
2
      break;
135
2
    case PPC::fixup_ppc_brcond14abs:
136
2
      Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
137
2
      break;
138
196
    case PPC::fixup_ppc_half16:
139
196
      switch (Modifier) {
140
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
141
2
      case MCSymbolRefExpr::VK_None:
142
2
        Type = ELF::R_PPC_ADDR16;
143
2
        break;
144
13
      case MCSymbolRefExpr::VK_PPC_LO:
145
13
        Type = ELF::R_PPC_ADDR16_LO;
146
13
        break;
147
7
      case MCSymbolRefExpr::VK_PPC_HI:
148
7
        Type = ELF::R_PPC_ADDR16_HI;
149
7
        break;
150
9
      case MCSymbolRefExpr::VK_PPC_HA:
151
9
        Type = ELF::R_PPC_ADDR16_HA;
152
9
        break;
153
3
      case MCSymbolRefExpr::VK_PPC_HIGHER:
154
3
        Type = ELF::R_PPC64_ADDR16_HIGHER;
155
3
        break;
156
3
      case MCSymbolRefExpr::VK_PPC_HIGHERA:
157
3
        Type = ELF::R_PPC64_ADDR16_HIGHERA;
158
3
        break;
159
3
      case MCSymbolRefExpr::VK_PPC_HIGHEST:
160
3
        Type = ELF::R_PPC64_ADDR16_HIGHEST;
161
3
        break;
162
3
      case MCSymbolRefExpr::VK_PPC_HIGHESTA:
163
3
        Type = ELF::R_PPC64_ADDR16_HIGHESTA;
164
3
        break;
165
4
      case MCSymbolRefExpr::VK_GOT:
166
4
        Type = ELF::R_PPC_GOT16;
167
4
        break;
168
8
      case MCSymbolRefExpr::VK_PPC_GOT_LO:
169
8
        Type = ELF::R_PPC_GOT16_LO;
170
8
        break;
171
4
      case MCSymbolRefExpr::VK_PPC_GOT_HI:
172
4
        Type = ELF::R_PPC_GOT16_HI;
173
4
        break;
174
4
      case MCSymbolRefExpr::VK_PPC_GOT_HA:
175
4
        Type = ELF::R_PPC_GOT16_HA;
176
4
        break;
177
0
      case MCSymbolRefExpr::VK_PPC_TOC:
178
0
        Type = ELF::R_PPC64_TOC16;
179
0
        break;
180
16
      case MCSymbolRefExpr::VK_PPC_TOC_LO:
181
16
        Type = ELF::R_PPC64_TOC16_LO;
182
16
        break;
183
3
      case MCSymbolRefExpr::VK_PPC_TOC_HI:
184
3
        Type = ELF::R_PPC64_TOC16_HI;
185
3
        break;
186
39
      case MCSymbolRefExpr::VK_PPC_TOC_HA:
187
39
        Type = ELF::R_PPC64_TOC16_HA;
188
39
        break;
189
2
      case MCSymbolRefExpr::VK_TPREL:
190
2
        Type = ELF::R_PPC_TPREL16;
191
2
        break;
192
3
      case MCSymbolRefExpr::VK_PPC_TPREL_LO:
193
3
        Type = ELF::R_PPC_TPREL16_LO;
194
3
        break;
195
2
      case MCSymbolRefExpr::VK_PPC_TPREL_HI:
196
2
        Type = ELF::R_PPC_TPREL16_HI;
197
2
        break;
198
3
      case MCSymbolRefExpr::VK_PPC_TPREL_HA:
199
3
        Type = ELF::R_PPC_TPREL16_HA;
200
3
        break;
201
2
      case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
202
2
        Type = ELF::R_PPC64_TPREL16_HIGHER;
203
2
        break;
204
2
      case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
205
2
        Type = ELF::R_PPC64_TPREL16_HIGHERA;
206
2
        break;
207
2
      case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
208
2
        Type = ELF::R_PPC64_TPREL16_HIGHEST;
209
2
        break;
210
2
      case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
211
2
        Type = ELF::R_PPC64_TPREL16_HIGHESTA;
212
2
        break;
213
2
      case MCSymbolRefExpr::VK_DTPREL:
214
2
        Type = ELF::R_PPC64_DTPREL16;
215
2
        break;
216
3
      case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
217
3
        Type = ELF::R_PPC64_DTPREL16_LO;
218
3
        break;
219
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
220
2
        Type = ELF::R_PPC64_DTPREL16_HI;
221
2
        break;
222
3
      case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
223
3
        Type = ELF::R_PPC64_DTPREL16_HA;
224
3
        break;
225
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
226
2
        Type = ELF::R_PPC64_DTPREL16_HIGHER;
227
2
        break;
228
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
229
2
        Type = ELF::R_PPC64_DTPREL16_HIGHERA;
230
2
        break;
231
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
232
2
        Type = ELF::R_PPC64_DTPREL16_HIGHEST;
233
2
        break;
234
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
235
2
        Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
236
2
        break;
237
2
      case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
238
2
        if (is64Bit())
239
2
          Type = ELF::R_PPC64_GOT_TLSGD16;
240
2
        else
241
0
          Type = ELF::R_PPC_GOT_TLSGD16;
242
2
        break;
243
4
      case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
244
4
        Type = ELF::R_PPC64_GOT_TLSGD16_LO;
245
4
        break;
246
2
      case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
247
2
        Type = ELF::R_PPC64_GOT_TLSGD16_HI;
248
2
        break;
249
4
      case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
250
4
        Type = ELF::R_PPC64_GOT_TLSGD16_HA;
251
4
        break;
252
2
      case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
253
2
        if (is64Bit())
254
2
          Type = ELF::R_PPC64_GOT_TLSLD16;
255
2
        else
256
0
          Type = ELF::R_PPC_GOT_TLSLD16;
257
2
        break;
258
3
      case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
259
3
        Type = ELF::R_PPC64_GOT_TLSLD16_LO;
260
3
        break;
261
2
      case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
262
2
        Type = ELF::R_PPC64_GOT_TLSLD16_HI;
263
2
        break;
264
3
      case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
265
3
        Type = ELF::R_PPC64_GOT_TLSLD16_HA;
266
3
        break;
267
2
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
268
2
        /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
269
2
           are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS.  */
270
2
        Type = ELF::R_PPC64_GOT_TPREL16_DS;
271
2
        break;
272
2
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
273
2
        /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
274
2
           are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS.  */
275
2
        Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
276
2
        break;
277
2
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
278
2
        Type = ELF::R_PPC64_GOT_TPREL16_HI;
279
2
        break;
280
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
281
2
        /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
282
2
           are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS.  */
283
2
        Type = ELF::R_PPC64_GOT_DTPREL16_DS;
284
2
        break;
285
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
286
2
        /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
287
2
           are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS.  */
288
2
        Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
289
2
        break;
290
3
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
291
3
        Type = ELF::R_PPC64_GOT_TPREL16_HA;
292
3
        break;
293
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
294
2
        Type = ELF::R_PPC64_GOT_DTPREL16_HI;
295
2
        break;
296
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
297
2
        Type = ELF::R_PPC64_GOT_DTPREL16_HA;
298
2
        break;
299
196
      }
300
196
      break;
301
65
    case PPC::fixup_ppc_half16ds:
302
65
      switch (Modifier) {
303
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
304
2
      case MCSymbolRefExpr::VK_None:
305
2
        Type = ELF::R_PPC64_ADDR16_DS;
306
2
        break;
307
2
      case MCSymbolRefExpr::VK_PPC_LO:
308
2
        Type = ELF::R_PPC64_ADDR16_LO_DS;
309
2
        break;
310
4
      case MCSymbolRefExpr::VK_GOT:
311
4
        Type = ELF::R_PPC64_GOT16_DS;
312
4
        break;
313
4
      case MCSymbolRefExpr::VK_PPC_GOT_LO:
314
4
        Type = ELF::R_PPC64_GOT16_LO_DS;
315
4
        break;
316
3
      case MCSymbolRefExpr::VK_PPC_TOC:
317
3
        Type = ELF::R_PPC64_TOC16_DS;
318
3
        break;
319
33
      case MCSymbolRefExpr::VK_PPC_TOC_LO:
320
33
        Type = ELF::R_PPC64_TOC16_LO_DS;
321
33
        break;
322
2
      case MCSymbolRefExpr::VK_TPREL:
323
2
        Type = ELF::R_PPC64_TPREL16_DS;
324
2
        break;
325
2
      case MCSymbolRefExpr::VK_PPC_TPREL_LO:
326
2
        Type = ELF::R_PPC64_TPREL16_LO_DS;
327
2
        break;
328
2
      case MCSymbolRefExpr::VK_DTPREL:
329
2
        Type = ELF::R_PPC64_DTPREL16_DS;
330
2
        break;
331
2
      case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
332
2
        Type = ELF::R_PPC64_DTPREL16_LO_DS;
333
2
        break;
334
2
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
335
2
        Type = ELF::R_PPC64_GOT_TPREL16_DS;
336
2
        break;
337
3
      case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
338
3
        Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
339
3
        break;
340
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
341
2
        Type = ELF::R_PPC64_GOT_DTPREL16_DS;
342
2
        break;
343
2
      case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
344
2
        Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
345
2
        break;
346
65
      }
347
65
      break;
348
10
    case PPC::fixup_ppc_nofixup:
349
10
      switch (Modifier) {
350
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
351
4
      case MCSymbolRefExpr::VK_PPC_TLSGD:
352
4
        if (is64Bit())
353
4
          Type = ELF::R_PPC64_TLSGD;
354
4
        else
355
0
          Type = ELF::R_PPC_TLSGD;
356
4
        break;
357
3
      case MCSymbolRefExpr::VK_PPC_TLSLD:
358
3
        if (is64Bit())
359
3
          Type = ELF::R_PPC64_TLSLD;
360
3
        else
361
0
          Type = ELF::R_PPC_TLSLD;
362
3
        break;
363
3
      case MCSymbolRefExpr::VK_PPC_TLS:
364
3
        if (is64Bit())
365
3
          Type = ELF::R_PPC64_TLS;
366
3
        else
367
0
          Type = ELF::R_PPC_TLS;
368
3
        break;
369
10
      }
370
10
      break;
371
130
    case FK_Data_8:
372
130
      switch (Modifier) {
373
0
      
default: 0
llvm_unreachable0
("Unsupported Modifier");
374
46
      case MCSymbolRefExpr::VK_PPC_TOCBASE:
375
46
        Type = ELF::R_PPC64_TOC;
376
46
        break;
377
78
      case MCSymbolRefExpr::VK_None:
378
78
        Type = ELF::R_PPC64_ADDR64;
379
78
        break;
380
2
      case MCSymbolRefExpr::VK_PPC_DTPMOD:
381
2
        Type = ELF::R_PPC64_DTPMOD64;
382
2
        break;
383
2
      case MCSymbolRefExpr::VK_TPREL:
384
2
        Type = ELF::R_PPC64_TPREL64;
385
2
        break;
386
2
      case MCSymbolRefExpr::VK_DTPREL:
387
2
        Type = ELF::R_PPC64_DTPREL64;
388
2
        break;
389
130
      }
390
130
      break;
391
3
    case FK_Data_4:
392
3
      Type = ELF::R_PPC_ADDR32;
393
3
      break;
394
1
    case FK_Data_2:
395
1
      Type = ELF::R_PPC_ADDR16;
396
1
      break;
397
490
    }
398
490
  }
399
490
  return Type;
400
490
}
401
402
bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
403
175
                                                 unsigned Type) const {
404
175
  switch (Type) {
405
167
    default:
406
167
      return false;
407
175
408
8
    case ELF::R_PPC_REL24:
409
8
      // If the target symbol has a local entry point, we must keep the
410
8
      // target symbol to preserve that information for the linker.
411
8
      // The "other" values are stored in the last 6 bits of the second byte.
412
8
      // The traditional defines for STO values assume the full byte and thus
413
8
      // the shift to pack it.
414
8
      unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
415
8
      return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
416
0
  }
417
0
}
418
419
MCObjectWriter *llvm::createPPCELFObjectWriter(raw_pwrite_stream &OS,
420
                                               bool Is64Bit,
421
                                               bool IsLittleEndian,
422
70
                                               uint8_t OSABI) {
423
70
  MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI);
424
70
  return createELFObjectWriter(MOTW, OS, IsLittleEndian);
425
70
}