Coverage Report

Created: 2025-08-30 07:19

/src/keystone/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- RISCVELFObjectWriter.cpp - RISCV 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/RISCVFixupKinds.h"
10
#include "MCTargetDesc/RISCVMCTargetDesc.h"
11
#include "llvm/MC/MCELFObjectWriter.h"
12
#include "llvm/MC/MCFixup.h"
13
#include "llvm/MC/MCObjectWriter.h"
14
#include "llvm/Support/ErrorHandling.h"
15
#include "llvm/ADT/STLExtras.h"
16
17
using namespace llvm_ks;
18
19
namespace {
20
class RISCVELFObjectWriter : public MCELFObjectTargetWriter {
21
public:
22
  RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit);
23
24
  ~RISCVELFObjectWriter() override;
25
26
  // Return true if the given relocation must be with a symbol rather than
27
  // section plus offset.
28
  bool needsRelocateWithSymbol(const MCSymbol &Sym,
29
8.32k
                               unsigned Type) const override {
30
    // TODO: this is very conservative, update once RISC-V psABI requirements
31
    //       are clarified.
32
8.32k
    return true;
33
8.32k
  }
34
35
protected:
36
  unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
37
                        const MCFixup &Fixup, bool IsPCRel) const override;
38
};
39
}
40
41
RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
42
25.8k
    : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,
43
25.8k
                              /*HasRelocationAddend*/ true) {}
44
45
RISCVELFObjectWriter::~RISCVELFObjectWriter() {}
46
47
unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
48
                                            const MCValue &Target,
49
                                            const MCFixup &Fixup,
50
10.2k
                                            bool IsPCRel) const {
51
  // Determine the type of the relocation
52
10.2k
  unsigned Kind = Fixup.getKind();
53
10.2k
  if (IsPCRel) {
54
1.92k
    switch (Kind) {
55
0
    default:
56
0
      llvm_unreachable("invalid fixup kind!");
57
1.92k
    case FK_Data_4:
58
1.92k
    case FK_PCRel_4:
59
1.92k
      return ELF::R_RISCV_32_PCREL;
60
0
    case RISCV::fixup_riscv_pcrel_hi20:
61
0
      return ELF::R_RISCV_PCREL_HI20;
62
0
    case RISCV::fixup_riscv_pcrel_lo12_i:
63
0
      return ELF::R_RISCV_PCREL_LO12_I;
64
0
    case RISCV::fixup_riscv_pcrel_lo12_s:
65
0
      return ELF::R_RISCV_PCREL_LO12_S;
66
0
    case RISCV::fixup_riscv_got_hi20:
67
0
      return ELF::R_RISCV_GOT_HI20;
68
0
    case RISCV::fixup_riscv_tls_got_hi20:
69
0
      return ELF::R_RISCV_TLS_GOT_HI20;
70
0
    case RISCV::fixup_riscv_tls_gd_hi20:
71
0
      return ELF::R_RISCV_TLS_GD_HI20;
72
0
    case RISCV::fixup_riscv_jal:
73
0
      return ELF::R_RISCV_JAL;
74
0
    case RISCV::fixup_riscv_branch:
75
0
      return ELF::R_RISCV_BRANCH;
76
0
    case RISCV::fixup_riscv_rvc_jump:
77
0
      return ELF::R_RISCV_RVC_JUMP;
78
0
    case RISCV::fixup_riscv_rvc_branch:
79
0
      return ELF::R_RISCV_RVC_BRANCH;
80
0
    case RISCV::fixup_riscv_call:
81
0
      return ELF::R_RISCV_CALL;
82
0
    case RISCV::fixup_riscv_call_plt:
83
0
      return ELF::R_RISCV_CALL_PLT;
84
1.92k
    }
85
1.92k
  }
86
87
8.36k
  switch (Kind) {
88
0
  default:
89
0
    llvm_unreachable("invalid fixup kind!");
90
8.15k
  case FK_Data_4:
91
8.15k
    return ELF::R_RISCV_32;
92
208
  case FK_Data_8:
93
208
    return ELF::R_RISCV_64;
94
0
  case FK_Data_Add_1:
95
0
    return ELF::R_RISCV_ADD8;
96
0
  case FK_Data_Add_2:
97
0
    return ELF::R_RISCV_ADD16;
98
0
  case FK_Data_Add_4:
99
0
    return ELF::R_RISCV_ADD32;
100
0
  case FK_Data_Add_8:
101
0
    return ELF::R_RISCV_ADD64;
102
0
  case FK_Data_Sub_1:
103
0
    return ELF::R_RISCV_SUB8;
104
0
  case FK_Data_Sub_2:
105
0
    return ELF::R_RISCV_SUB16;
106
0
  case FK_Data_Sub_4:
107
0
    return ELF::R_RISCV_SUB32;
108
0
  case FK_Data_Sub_8:
109
0
    return ELF::R_RISCV_SUB64;
110
0
  case RISCV::fixup_riscv_hi20:
111
0
    return ELF::R_RISCV_HI20;
112
0
  case RISCV::fixup_riscv_lo12_i:
113
0
    return ELF::R_RISCV_LO12_I;
114
0
  case RISCV::fixup_riscv_lo12_s:
115
0
    return ELF::R_RISCV_LO12_S;
116
0
  case RISCV::fixup_riscv_tprel_hi20:
117
0
    return ELF::R_RISCV_TPREL_HI20;
118
0
  case RISCV::fixup_riscv_tprel_lo12_i:
119
0
    return ELF::R_RISCV_TPREL_LO12_I;
120
0
  case RISCV::fixup_riscv_tprel_lo12_s:
121
0
    return ELF::R_RISCV_TPREL_LO12_S;
122
0
  case RISCV::fixup_riscv_tprel_add:
123
0
    return ELF::R_RISCV_TPREL_ADD;
124
0
  case RISCV::fixup_riscv_relax:
125
0
    return ELF::R_RISCV_RELAX;
126
0
  case RISCV::fixup_riscv_align:
127
0
    return ELF::R_RISCV_ALIGN;
128
8.36k
  }
129
8.36k
}
130
131
25.8k
MCObjectWriter *llvm_ks::createRISCVELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool Is64Bit) {
132
25.8k
  MCELFObjectTargetWriter *MOTW = new RISCVELFObjectWriter(OSABI, Is64Bit);
133
25.8k
  return createELFObjectWriter(MOTW, OS, /*isLittleEndian*/ true);
134
25.8k
}