Coverage Report

Created: 2025-07-15 06:22

/src/keystone/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMELFObjectWriter.cpp - ARM 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/ARMMCTargetDesc.h"
11
#include "MCTargetDesc/ARMFixupKinds.h"
12
#include "llvm/ADT/StringSwitch.h"
13
#include "llvm/MC/MCELFObjectWriter.h"
14
#include "llvm/MC/MCExpr.h"
15
#include "llvm/MC/MCSectionELF.h"
16
#include "llvm/MC/MCValue.h"
17
#include "llvm/Support/Debug.h"
18
#include "llvm/Support/ErrorHandling.h"
19
#include "llvm/Support/raw_ostream.h"
20
21
using namespace llvm_ks;
22
23
namespace {
24
  class ARMELFObjectWriter : public MCELFObjectTargetWriter {
25
    enum { DefaultEABIVersion = 0x05000000U };
26
    unsigned GetRelocTypeInner(const MCValue &Target,
27
                               const MCFixup &Fixup,
28
                               bool IsPCRel) const;
29
30
31
  public:
32
    ARMELFObjectWriter(uint8_t OSABI);
33
34
    ~ARMELFObjectWriter() override;
35
36
    unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
37
                          const MCFixup &Fixup, bool IsPCRel) const override;
38
39
    bool needsRelocateWithSymbol(const MCSymbol &Sym,
40
                                 unsigned Type) const override;
41
  };
42
}
43
44
ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
45
61.7k
  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
46
61.7k
                            ELF::EM_ARM,
47
61.7k
                            /*HasRelocationAddend*/ false) {}
48
49
ARMELFObjectWriter::~ARMELFObjectWriter() {}
50
51
bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
52
55.2k
                                                 unsigned Type) const {
53
  // FIXME: This is extremely conservative. This really needs to use a
54
  // whitelist with a clear explanation for why each realocation needs to
55
  // point to the symbol, not to the section.
56
55.2k
  switch (Type) {
57
1.21k
  default:
58
1.21k
    return true;
59
60
0
  case ELF::R_ARM_PREL31:
61
54.0k
  case ELF::R_ARM_ABS32:
62
54.0k
    return false;
63
55.2k
  }
64
55.2k
}
65
66
// Need to examine the Fixup when determining whether to 
67
// emit the relocation as an explicit symbol or as a section relative
68
// offset
69
unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
70
                                          const MCFixup &Fixup,
71
59.2k
                                          bool IsPCRel) const {
72
59.2k
  return GetRelocTypeInner(Target, Fixup, IsPCRel);
73
59.2k
}
74
75
unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
76
                                               const MCFixup &Fixup,
77
59.2k
                                               bool IsPCRel) const  {
78
59.2k
  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
79
80
59.2k
  unsigned Type = 0;
81
59.2k
  if (IsPCRel) {
82
4.58k
    switch ((unsigned)Fixup.getKind()) {
83
0
    default:
84
0
      report_fatal_error("unsupported relocation on symbol");
85
0
      return ELF::R_ARM_NONE;
86
2.34k
    case FK_Data_4:
87
2.34k
      switch (Modifier) {
88
0
      default: llvm_unreachable("Unsupported Modifier");
89
2.34k
      case MCSymbolRefExpr::VK_None:
90
2.34k
        Type = ELF::R_ARM_REL32;
91
2.34k
        break;
92
0
      case MCSymbolRefExpr::VK_TLSGD:
93
0
        llvm_unreachable("unimplemented");
94
0
      case MCSymbolRefExpr::VK_GOTTPOFF:
95
0
        Type = ELF::R_ARM_TLS_IE32;
96
0
        break;
97
0
      case MCSymbolRefExpr::VK_ARM_GOT_PREL:
98
0
        Type = ELF::R_ARM_GOT_PREL;
99
0
        break;
100
2.34k
      }
101
2.34k
      break;
102
2.34k
    case ARM::fixup_arm_blx:
103
403
    case ARM::fixup_arm_uncondbl:
104
403
      switch (Modifier) {
105
0
      case MCSymbolRefExpr::VK_PLT:
106
0
        Type = ELF::R_ARM_CALL;
107
0
        break;
108
0
      case MCSymbolRefExpr::VK_ARM_TLSCALL:
109
0
        Type = ELF::R_ARM_TLS_CALL;
110
0
        break;
111
403
      default:
112
403
        Type = ELF::R_ARM_CALL;
113
403
        break;
114
403
      }
115
403
      break;
116
403
    case ARM::fixup_arm_condbl:
117
419
    case ARM::fixup_arm_condbranch:
118
804
    case ARM::fixup_arm_uncondbranch:
119
804
      Type = ELF::R_ARM_JUMP24;
120
804
      break;
121
63
    case ARM::fixup_t2_condbranch:
122
228
    case ARM::fixup_t2_uncondbranch:
123
228
      Type = ELF::R_ARM_THM_JUMP24;
124
228
      break;
125
0
    case ARM::fixup_arm_movt_hi16:
126
0
      Type = ELF::R_ARM_MOVT_PREL;
127
0
      break;
128
0
    case ARM::fixup_arm_movw_lo16:
129
0
      Type = ELF::R_ARM_MOVW_PREL_NC;
130
0
      break;
131
0
    case ARM::fixup_t2_movt_hi16:
132
0
      Type = ELF::R_ARM_THM_MOVT_PREL;
133
0
      break;
134
0
    case ARM::fixup_t2_movw_lo16:
135
0
      Type = ELF::R_ARM_THM_MOVW_PREL_NC;
136
0
      break;
137
692
    case ARM::fixup_arm_thumb_bl:
138
803
    case ARM::fixup_arm_thumb_blx:
139
803
      switch (Modifier) {
140
0
      case MCSymbolRefExpr::VK_ARM_TLSCALL:
141
0
        Type = ELF::R_ARM_THM_TLS_CALL;
142
0
        break;
143
803
      default:
144
803
        Type = ELF::R_ARM_THM_CALL;
145
803
        break;
146
803
      }
147
803
      break;
148
4.58k
    }
149
54.6k
  } else {
150
54.6k
    switch ((unsigned)Fixup.getKind()) {
151
0
    default:
152
0
      report_fatal_error("unsupported relocation on symbol");
153
0
      return ELF::R_ARM_NONE;
154
413
    case FK_Data_1:
155
413
      switch (Modifier) {
156
0
      default: llvm_unreachable("unsupported Modifier");
157
413
      case MCSymbolRefExpr::VK_None:
158
413
        Type = ELF::R_ARM_ABS8;
159
413
        break;
160
413
      }
161
413
      break;
162
413
    case FK_Data_2:
163
259
      switch (Modifier) {
164
0
      default: llvm_unreachable("unsupported modifier");
165
259
      case MCSymbolRefExpr::VK_None:
166
259
        Type = ELF::R_ARM_ABS16;
167
259
        break;
168
259
      }
169
259
      break;
170
54.0k
    case FK_Data_4:
171
54.0k
      switch (Modifier) {
172
0
      default: llvm_unreachable("Unsupported Modifier");
173
0
      case MCSymbolRefExpr::VK_ARM_NONE:
174
0
        Type = ELF::R_ARM_NONE;
175
0
        break;
176
0
      case MCSymbolRefExpr::VK_GOT:
177
0
        Type = ELF::R_ARM_GOT_BREL;
178
0
        break;
179
0
      case MCSymbolRefExpr::VK_TLSGD:
180
0
        Type = ELF::R_ARM_TLS_GD32;
181
0
        break;
182
0
      case MCSymbolRefExpr::VK_TPOFF:
183
0
        Type = ELF::R_ARM_TLS_LE32;
184
0
        break;
185
0
      case MCSymbolRefExpr::VK_GOTTPOFF:
186
0
        Type = ELF::R_ARM_TLS_IE32;
187
0
        break;
188
54.0k
      case MCSymbolRefExpr::VK_None:
189
54.0k
        Type = ELF::R_ARM_ABS32;
190
54.0k
        break;
191
0
      case MCSymbolRefExpr::VK_GOTOFF:
192
0
        Type = ELF::R_ARM_GOTOFF32;
193
0
        break;
194
0
      case MCSymbolRefExpr::VK_ARM_GOT_PREL:
195
0
        Type = ELF::R_ARM_GOT_PREL;
196
0
        break;
197
0
      case MCSymbolRefExpr::VK_ARM_TARGET1:
198
0
        Type = ELF::R_ARM_TARGET1;
199
0
        break;
200
0
      case MCSymbolRefExpr::VK_ARM_TARGET2:
201
0
        Type = ELF::R_ARM_TARGET2;
202
0
        break;
203
0
      case MCSymbolRefExpr::VK_ARM_PREL31:
204
0
        Type = ELF::R_ARM_PREL31;
205
0
        break;
206
0
      case MCSymbolRefExpr::VK_ARM_SBREL:
207
0
        Type = ELF::R_ARM_SBREL32;
208
0
        break;
209
0
      case MCSymbolRefExpr::VK_ARM_TLSLDO:
210
0
        Type = ELF::R_ARM_TLS_LDO32;
211
0
        break;
212
0
      case MCSymbolRefExpr::VK_ARM_TLSCALL:
213
0
        Type = ELF::R_ARM_TLS_CALL;
214
0
        break;
215
0
      case MCSymbolRefExpr::VK_ARM_TLSDESC:
216
0
        Type = ELF::R_ARM_TLS_GOTDESC;
217
0
        break;
218
0
      case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
219
0
        Type = ELF::R_ARM_TLS_DESCSEQ;
220
0
        break;
221
54.0k
      }
222
54.0k
      break;
223
54.0k
    case ARM::fixup_arm_ldst_pcrel_12:
224
0
    case ARM::fixup_arm_pcrel_10:
225
0
    case ARM::fixup_arm_adr_pcrel_12:
226
0
    case ARM::fixup_arm_thumb_bl:
227
0
    case ARM::fixup_arm_thumb_cb:
228
0
    case ARM::fixup_arm_thumb_cp:
229
0
    case ARM::fixup_arm_thumb_br:
230
0
      llvm_unreachable("Unimplemented");
231
0
    case ARM::fixup_arm_condbranch:
232
0
    case ARM::fixup_arm_uncondbranch:
233
0
      Type = ELF::R_ARM_JUMP24;
234
0
      break;
235
0
    case ARM::fixup_arm_movt_hi16:
236
0
      Type = ELF::R_ARM_MOVT_ABS;
237
0
      break;
238
0
    case ARM::fixup_arm_movw_lo16:
239
0
      Type = ELF::R_ARM_MOVW_ABS_NC;
240
0
      break;
241
0
    case ARM::fixup_t2_movt_hi16:
242
0
      Type = ELF::R_ARM_THM_MOVT_ABS;
243
0
      break;
244
0
    case ARM::fixup_t2_movw_lo16:
245
0
      Type = ELF::R_ARM_THM_MOVW_ABS_NC;
246
0
      break;
247
54.6k
    }
248
54.6k
  }
249
250
59.2k
  return Type;
251
59.2k
}
252
253
MCObjectWriter *llvm_ks::createARMELFObjectWriter(raw_pwrite_stream &OS,
254
                                               uint8_t OSABI,
255
61.7k
                                               bool IsLittleEndian) {
256
61.7k
  MCELFObjectTargetWriter *MOTW = new ARMELFObjectWriter(OSABI);
257
61.7k
  return createELFObjectWriter(MOTW, OS, IsLittleEndian);
258
61.7k
}