Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
35293 views
1
//===-- RISCVELFObjectWriter.cpp - RISC-V 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/RISCVMCExpr.h"
11
#include "MCTargetDesc/RISCVMCTargetDesc.h"
12
#include "llvm/MC/MCContext.h"
13
#include "llvm/MC/MCELFObjectWriter.h"
14
#include "llvm/MC/MCFixup.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 RISCVELFObjectWriter : public MCELFObjectTargetWriter {
23
public:
24
RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit);
25
26
~RISCVELFObjectWriter() override;
27
28
// Return true if the given relocation must be with a symbol rather than
29
// section plus offset.
30
bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
31
unsigned Type) const override {
32
// TODO: this is very conservative, update once RISC-V psABI requirements
33
// are clarified.
34
return true;
35
}
36
37
protected:
38
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39
const MCFixup &Fixup, bool IsPCRel) const override;
40
};
41
}
42
43
RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
44
: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,
45
/*HasRelocationAddend*/ true) {}
46
47
RISCVELFObjectWriter::~RISCVELFObjectWriter() = default;
48
49
unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
50
const MCValue &Target,
51
const MCFixup &Fixup,
52
bool IsPCRel) const {
53
const MCExpr *Expr = Fixup.getValue();
54
// Determine the type of the relocation
55
unsigned Kind = Fixup.getTargetKind();
56
if (Kind >= FirstLiteralRelocationKind)
57
return Kind - FirstLiteralRelocationKind;
58
if (IsPCRel) {
59
switch (Kind) {
60
default:
61
Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
62
return ELF::R_RISCV_NONE;
63
case FK_Data_4:
64
case FK_PCRel_4:
65
return Target.getAccessVariant() == MCSymbolRefExpr::VK_PLT
66
? ELF::R_RISCV_PLT32
67
: ELF::R_RISCV_32_PCREL;
68
case RISCV::fixup_riscv_pcrel_hi20:
69
return ELF::R_RISCV_PCREL_HI20;
70
case RISCV::fixup_riscv_pcrel_lo12_i:
71
return ELF::R_RISCV_PCREL_LO12_I;
72
case RISCV::fixup_riscv_pcrel_lo12_s:
73
return ELF::R_RISCV_PCREL_LO12_S;
74
case RISCV::fixup_riscv_got_hi20:
75
return ELF::R_RISCV_GOT_HI20;
76
case RISCV::fixup_riscv_tls_got_hi20:
77
return ELF::R_RISCV_TLS_GOT_HI20;
78
case RISCV::fixup_riscv_tls_gd_hi20:
79
return ELF::R_RISCV_TLS_GD_HI20;
80
case RISCV::fixup_riscv_tlsdesc_hi20:
81
return ELF::R_RISCV_TLSDESC_HI20;
82
case RISCV::fixup_riscv_tlsdesc_load_lo12:
83
return ELF::R_RISCV_TLSDESC_LOAD_LO12;
84
case RISCV::fixup_riscv_tlsdesc_add_lo12:
85
return ELF::R_RISCV_TLSDESC_ADD_LO12;
86
case RISCV::fixup_riscv_tlsdesc_call:
87
return ELF::R_RISCV_TLSDESC_CALL;
88
case RISCV::fixup_riscv_jal:
89
return ELF::R_RISCV_JAL;
90
case RISCV::fixup_riscv_branch:
91
return ELF::R_RISCV_BRANCH;
92
case RISCV::fixup_riscv_rvc_jump:
93
return ELF::R_RISCV_RVC_JUMP;
94
case RISCV::fixup_riscv_rvc_branch:
95
return ELF::R_RISCV_RVC_BRANCH;
96
case RISCV::fixup_riscv_call:
97
return ELF::R_RISCV_CALL_PLT;
98
case RISCV::fixup_riscv_call_plt:
99
return ELF::R_RISCV_CALL_PLT;
100
}
101
}
102
103
switch (Kind) {
104
default:
105
Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
106
return ELF::R_RISCV_NONE;
107
case RISCV::fixup_riscv_tlsdesc_load_lo12:
108
return ELF::R_RISCV_TLSDESC_LOAD_LO12;
109
case RISCV::fixup_riscv_tlsdesc_add_lo12:
110
return ELF::R_RISCV_TLSDESC_ADD_LO12;
111
case RISCV::fixup_riscv_tlsdesc_call:
112
return ELF::R_RISCV_TLSDESC_CALL;
113
114
case FK_Data_1:
115
Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
116
return ELF::R_RISCV_NONE;
117
case FK_Data_2:
118
Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
119
return ELF::R_RISCV_NONE;
120
case FK_Data_4:
121
if (Expr->getKind() == MCExpr::Target &&
122
cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
123
return ELF::R_RISCV_32_PCREL;
124
if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL)
125
return ELF::R_RISCV_GOT32_PCREL;
126
return ELF::R_RISCV_32;
127
case FK_Data_8:
128
return ELF::R_RISCV_64;
129
case RISCV::fixup_riscv_hi20:
130
return ELF::R_RISCV_HI20;
131
case RISCV::fixup_riscv_lo12_i:
132
return ELF::R_RISCV_LO12_I;
133
case RISCV::fixup_riscv_lo12_s:
134
return ELF::R_RISCV_LO12_S;
135
case RISCV::fixup_riscv_tprel_hi20:
136
return ELF::R_RISCV_TPREL_HI20;
137
case RISCV::fixup_riscv_tprel_lo12_i:
138
return ELF::R_RISCV_TPREL_LO12_I;
139
case RISCV::fixup_riscv_tprel_lo12_s:
140
return ELF::R_RISCV_TPREL_LO12_S;
141
case RISCV::fixup_riscv_tprel_add:
142
return ELF::R_RISCV_TPREL_ADD;
143
case RISCV::fixup_riscv_relax:
144
return ELF::R_RISCV_RELAX;
145
case RISCV::fixup_riscv_align:
146
return ELF::R_RISCV_ALIGN;
147
}
148
}
149
150
std::unique_ptr<MCObjectTargetWriter>
151
llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
152
return std::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit);
153
}
154
155