Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SparcELFObjectWriter.cpp - Sparc 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/SparcFixupKinds.h"
10
#include "MCTargetDesc/SparcMCExpr.h"
11
#include "MCTargetDesc/SparcMCTargetDesc.h"
12
#include "llvm/ADT/STLExtras.h"
13
#include "llvm/MC/MCELFObjectWriter.h"
14
#include "llvm/MC/MCExpr.h"
15
#include "llvm/MC/MCObjectWriter.h"
16
#include "llvm/MC/MCValue.h"
17
#include "llvm/Support/ErrorHandling.h"
18
19
using namespace llvm;
20
21
namespace {
22
  class SparcELFObjectWriter : public MCELFObjectTargetWriter {
23
  public:
24
    SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
25
      : MCELFObjectTargetWriter(Is64Bit, OSABI,
26
                                Is64Bit ?  ELF::EM_SPARCV9 : ELF::EM_SPARC,
27
260
                                /*HasRelocationAddend*/ true) {}
28
29
257
    ~SparcELFObjectWriter() override {}
30
31
  protected:
32
    unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
33
                          const MCFixup &Fixup, bool IsPCRel) const override;
34
35
    bool needsRelocateWithSymbol(const MCSymbol &Sym,
36
                                 unsigned Type) const override;
37
38
  };
39
}
40
41
unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
42
                                            const MCValue &Target,
43
                                            const MCFixup &Fixup,
44
234
                                            bool IsPCRel) const {
45
234
46
234
  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
47
192
    if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
48
14
      return ELF::R_SPARC_DISP32;
49
220
  }
50
220
51
220
  if (IsPCRel) {
52
24
    switch((unsigned)Fixup.getKind()) {
53
24
    default:
54
0
      llvm_unreachable("Unimplemented fixup -> relocation");
55
24
    
case FK_Data_1: return ELF::R_SPARC_DISP80
;
56
24
    
case FK_Data_2: return ELF::R_SPARC_DISP160
;
57
24
    
case FK_Data_4: return ELF::R_SPARC_DISP320
;
58
24
    
case FK_Data_8: return ELF::R_SPARC_DISP640
;
59
24
    
case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP306
;
60
24
    
case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP220
;
61
24
    
case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP190
;
62
24
    
case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC228
;
63
24
    
case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC108
;
64
24
    
case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT302
;
65
196
    }
66
196
  }
67
196
68
196
  switch((unsigned)Fixup.getKind()) {
69
196
  default:
70
0
    llvm_unreachable("Unimplemented fixup -> relocation");
71
196
  
case FK_Data_1: return ELF::R_SPARC_80
;
72
196
  case FK_Data_2:                return ((Fixup.getOffset() % 2)
73
0
                                         ? ELF::R_SPARC_UA16
74
0
                                         : ELF::R_SPARC_16);
75
196
  case FK_Data_4:                return ((Fixup.getOffset() % 4)
76
35
                                         ? 
ELF::R_SPARC_UA3223
77
35
                                         : 
ELF::R_SPARC_3212
);
78
196
  case FK_Data_8:                return ((Fixup.getOffset() % 8)
79
7
                                         ? 
ELF::R_SPARC_UA646
80
7
                                         : 
ELF::R_SPARC_641
);
81
196
  
case Sparc::fixup_sparc_13: return ELF::R_SPARC_132
;
82
196
  
case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI229
;
83
196
  
case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO109
;
84
196
  
case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H445
;
85
196
  
case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M445
;
86
196
  
case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L445
;
87
196
  
case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH221
;
88
196
  
case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM101
;
89
196
  
case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT225
;
90
196
  
case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT105
;
91
196
  
case Sparc::fixup_sparc_got13: return ELF::R_SPARC_GOT131
;
92
196
  
case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI226
;
93
196
  
case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO106
;
94
196
  
case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD6
;
95
196
  
case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL6
;
96
196
  
case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI226
;
97
196
  
case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO106
;
98
196
  
case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD6
;
99
196
  
case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL6
;
100
196
  
case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX226
;
101
196
  
case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX106
;
102
196
  
case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD6
;
103
196
  
case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI226
;
104
196
  
case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO106
;
105
196
  
case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD5
;
106
196
  
case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX5
;
107
196
  
case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD6
;
108
196
  
case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX226
;
109
196
  
case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX106
;
110
0
  }
111
0
112
0
  return ELF::R_SPARC_NONE;
113
0
}
114
115
bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
116
70
                                                 unsigned Type) const {
117
70
  switch (Type) {
118
70
    default:
119
66
      return false;
120
70
121
70
    // All relocations that use a GOT need a symbol, not an offset, as
122
70
    // the offset of the symbol within the section is irrelevant to
123
70
    // where the GOT entry is. Don't need to list all the TLS entries,
124
70
    // as they're all marked as requiring a symbol anyways.
125
70
    case ELF::R_SPARC_GOT10:
126
4
    case ELF::R_SPARC_GOT13:
127
4
    case ELF::R_SPARC_GOT22:
128
4
    case ELF::R_SPARC_GOTDATA_HIX22:
129
4
    case ELF::R_SPARC_GOTDATA_LOX10:
130
4
    case ELF::R_SPARC_GOTDATA_OP_HIX22:
131
4
    case ELF::R_SPARC_GOTDATA_OP_LOX10:
132
4
      return true;
133
70
  }
134
70
}
135
136
std::unique_ptr<MCObjectTargetWriter>
137
260
llvm::createSparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) {
138
260
  return llvm::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI);
139
260
}