LLVM 17.0.0git
RISCVELFObjectWriter.cpp
Go to the documentation of this file.
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
12#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCFixup.h"
16#include "llvm/MC/MCValue.h"
18
19using namespace llvm;
20
21namespace {
22class RISCVELFObjectWriter : public MCELFObjectTargetWriter {
23public:
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.
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
37protected:
38 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
39 const MCFixup &Fixup, bool IsPCRel) const override;
40};
41}
42
43RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
44 : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,
45 /*HasRelocationAddend*/ true) {}
46
47RISCVELFObjectWriter::~RISCVELFObjectWriter() = default;
48
49unsigned 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();
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;
69 return ELF::R_RISCV_PCREL_HI20;
71 return ELF::R_RISCV_PCREL_LO12_I;
73 return ELF::R_RISCV_PCREL_LO12_S;
75 return ELF::R_RISCV_GOT_HI20;
77 return ELF::R_RISCV_TLS_GOT_HI20;
79 return ELF::R_RISCV_TLS_GD_HI20;
81 return ELF::R_RISCV_JAL;
83 return ELF::R_RISCV_BRANCH;
85 return ELF::R_RISCV_RVC_JUMP;
87 return ELF::R_RISCV_RVC_BRANCH;
89 return ELF::R_RISCV_CALL_PLT;
91 return ELF::R_RISCV_CALL_PLT;
93 return ELF::R_RISCV_ADD8;
95 return ELF::R_RISCV_SUB8;
97 return ELF::R_RISCV_ADD16;
99 return ELF::R_RISCV_SUB16;
101 return ELF::R_RISCV_ADD32;
103 return ELF::R_RISCV_SUB32;
105 return ELF::R_RISCV_ADD64;
107 return ELF::R_RISCV_SUB64;
108 }
109 }
110
111 switch (Kind) {
112 default:
113 Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
114 return ELF::R_RISCV_NONE;
115 case FK_Data_1:
116 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
117 return ELF::R_RISCV_NONE;
118 case FK_Data_2:
119 Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
120 return ELF::R_RISCV_NONE;
121 case FK_Data_4:
122 if (Expr->getKind() == MCExpr::Target &&
123 cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
124 return ELF::R_RISCV_32_PCREL;
125 return ELF::R_RISCV_32;
126 case FK_Data_8:
127 return ELF::R_RISCV_64;
129 return ELF::R_RISCV_HI20;
131 return ELF::R_RISCV_LO12_I;
133 return ELF::R_RISCV_LO12_S;
135 return ELF::R_RISCV_TPREL_HI20;
137 return ELF::R_RISCV_TPREL_LO12_I;
139 return ELF::R_RISCV_TPREL_LO12_S;
141 return ELF::R_RISCV_TPREL_ADD;
143 return ELF::R_RISCV_RELAX;
145 return ELF::R_RISCV_ALIGN;
147 return ELF::R_RISCV_SET6;
149 return ELF::R_RISCV_SUB6;
151 return ELF::R_RISCV_ADD8;
153 return ELF::R_RISCV_SET8;
155 return ELF::R_RISCV_SUB8;
157 return ELF::R_RISCV_SET16;
159 return ELF::R_RISCV_ADD16;
161 return ELF::R_RISCV_SUB16;
163 return ELF::R_RISCV_SET32;
165 return ELF::R_RISCV_ADD32;
167 return ELF::R_RISCV_SUB32;
169 return ELF::R_RISCV_ADD64;
171 return ELF::R_RISCV_SUB64;
172 }
173}
174
175std::unique_ptr<MCObjectTargetWriter>
176llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
177 return std::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit);
178}
basic Basic Alias true
Symbol * Sym
Definition: ELF_riscv.cpp:463
PowerPC TLS Dynamic Call Fixup
Context object for machine code objects.
Definition: MCContext.h:76
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1049
virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const
virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const =0
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
@ Target
Target specific expression.
Definition: MCExpr.h:42
ExprKind getKind() const
Definition: MCExpr.h:81
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
This represents an "assembler immediate".
Definition: MCValue.h:36
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
@ EM_RISCV
Definition: ELF.h:317
@ fixup_riscv_tprel_lo12_s
@ fixup_riscv_tls_got_hi20
@ fixup_riscv_pcrel_lo12_i
@ fixup_riscv_pcrel_lo12_s
@ fixup_riscv_tprel_lo12_i
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::unique_ptr< MCObjectTargetWriter > createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
@ FK_PCRel_4
A four-byte pc relative fixup.
Definition: MCFixup.h:30
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:26
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24