1d88c1a5aSDimitry Andric //===-- RISCVELFObjectWriter.cpp - RISCV ELF Writer -----------------------===//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric //                     The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
9d88c1a5aSDimitry Andric 
102cab237bSDimitry Andric #include "MCTargetDesc/RISCVFixupKinds.h"
11d88c1a5aSDimitry Andric #include "MCTargetDesc/RISCVMCTargetDesc.h"
12d88c1a5aSDimitry Andric #include "llvm/MC/MCELFObjectWriter.h"
13d88c1a5aSDimitry Andric #include "llvm/MC/MCFixup.h"
142cab237bSDimitry Andric #include "llvm/MC/MCObjectWriter.h"
15d88c1a5aSDimitry Andric #include "llvm/Support/ErrorHandling.h"
16d88c1a5aSDimitry Andric 
17d88c1a5aSDimitry Andric using namespace llvm;
18d88c1a5aSDimitry Andric 
19d88c1a5aSDimitry Andric namespace {
20d88c1a5aSDimitry Andric class RISCVELFObjectWriter : public MCELFObjectTargetWriter {
21d88c1a5aSDimitry Andric public:
22d88c1a5aSDimitry Andric   RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit);
23d88c1a5aSDimitry Andric 
24d88c1a5aSDimitry Andric   ~RISCVELFObjectWriter() override;
25d88c1a5aSDimitry Andric 
26*4ba319b5SDimitry Andric   // Return true if the given relocation must be with a symbol rather than
27*4ba319b5SDimitry Andric   // section plus offset.
needsRelocateWithSymbol(const MCSymbol & Sym,unsigned Type) const28*4ba319b5SDimitry Andric   bool needsRelocateWithSymbol(const MCSymbol &Sym,
29*4ba319b5SDimitry Andric                                unsigned Type) const override {
30*4ba319b5SDimitry Andric     // TODO: this is very conservative, update once RISC-V psABI requirements
31*4ba319b5SDimitry Andric     //       are clarified.
32*4ba319b5SDimitry Andric     return true;
33*4ba319b5SDimitry Andric   }
34*4ba319b5SDimitry Andric 
35d88c1a5aSDimitry Andric protected:
36d88c1a5aSDimitry Andric   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
37d88c1a5aSDimitry Andric                         const MCFixup &Fixup, bool IsPCRel) const override;
38d88c1a5aSDimitry Andric };
39d88c1a5aSDimitry Andric }
40d88c1a5aSDimitry Andric 
RISCVELFObjectWriter(uint8_t OSABI,bool Is64Bit)41d88c1a5aSDimitry Andric RISCVELFObjectWriter::RISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit)
42d88c1a5aSDimitry Andric     : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_RISCV,
432cab237bSDimitry Andric                               /*HasRelocationAddend*/ true) {}
44d88c1a5aSDimitry Andric 
~RISCVELFObjectWriter()45d88c1a5aSDimitry Andric RISCVELFObjectWriter::~RISCVELFObjectWriter() {}
46d88c1a5aSDimitry Andric 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const47d88c1a5aSDimitry Andric unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
48d88c1a5aSDimitry Andric                                             const MCValue &Target,
49d88c1a5aSDimitry Andric                                             const MCFixup &Fixup,
50d88c1a5aSDimitry Andric                                             bool IsPCRel) const {
512cab237bSDimitry Andric   // Determine the type of the relocation
522cab237bSDimitry Andric   switch ((unsigned)Fixup.getKind()) {
532cab237bSDimitry Andric   default:
54d88c1a5aSDimitry Andric     llvm_unreachable("invalid fixup kind!");
552cab237bSDimitry Andric   case FK_Data_4:
562cab237bSDimitry Andric     return ELF::R_RISCV_32;
572cab237bSDimitry Andric   case FK_Data_8:
582cab237bSDimitry Andric     return ELF::R_RISCV_64;
59*4ba319b5SDimitry Andric   case FK_Data_Add_1:
60*4ba319b5SDimitry Andric     return ELF::R_RISCV_ADD8;
61*4ba319b5SDimitry Andric   case FK_Data_Add_2:
62*4ba319b5SDimitry Andric     return ELF::R_RISCV_ADD16;
63*4ba319b5SDimitry Andric   case FK_Data_Add_4:
64*4ba319b5SDimitry Andric     return ELF::R_RISCV_ADD32;
65*4ba319b5SDimitry Andric   case FK_Data_Add_8:
66*4ba319b5SDimitry Andric     return ELF::R_RISCV_ADD64;
67*4ba319b5SDimitry Andric   case FK_Data_Sub_1:
68*4ba319b5SDimitry Andric     return ELF::R_RISCV_SUB8;
69*4ba319b5SDimitry Andric   case FK_Data_Sub_2:
70*4ba319b5SDimitry Andric     return ELF::R_RISCV_SUB16;
71*4ba319b5SDimitry Andric   case FK_Data_Sub_4:
72*4ba319b5SDimitry Andric     return ELF::R_RISCV_SUB32;
73*4ba319b5SDimitry Andric   case FK_Data_Sub_8:
74*4ba319b5SDimitry Andric     return ELF::R_RISCV_SUB64;
752cab237bSDimitry Andric   case RISCV::fixup_riscv_hi20:
762cab237bSDimitry Andric     return ELF::R_RISCV_HI20;
772cab237bSDimitry Andric   case RISCV::fixup_riscv_lo12_i:
782cab237bSDimitry Andric     return ELF::R_RISCV_LO12_I;
792cab237bSDimitry Andric   case RISCV::fixup_riscv_lo12_s:
802cab237bSDimitry Andric     return ELF::R_RISCV_LO12_S;
812cab237bSDimitry Andric   case RISCV::fixup_riscv_pcrel_hi20:
822cab237bSDimitry Andric     return ELF::R_RISCV_PCREL_HI20;
83*4ba319b5SDimitry Andric   case RISCV::fixup_riscv_pcrel_lo12_i:
84*4ba319b5SDimitry Andric     return ELF::R_RISCV_PCREL_LO12_I;
85*4ba319b5SDimitry Andric   case RISCV::fixup_riscv_pcrel_lo12_s:
86*4ba319b5SDimitry Andric     return ELF::R_RISCV_PCREL_LO12_S;
872cab237bSDimitry Andric   case RISCV::fixup_riscv_jal:
882cab237bSDimitry Andric     return ELF::R_RISCV_JAL;
892cab237bSDimitry Andric   case RISCV::fixup_riscv_branch:
902cab237bSDimitry Andric     return ELF::R_RISCV_BRANCH;
912cab237bSDimitry Andric   case RISCV::fixup_riscv_rvc_jump:
922cab237bSDimitry Andric     return ELF::R_RISCV_RVC_JUMP;
932cab237bSDimitry Andric   case RISCV::fixup_riscv_rvc_branch:
942cab237bSDimitry Andric     return ELF::R_RISCV_RVC_BRANCH;
95*4ba319b5SDimitry Andric   case RISCV::fixup_riscv_call:
96*4ba319b5SDimitry Andric     return ELF::R_RISCV_CALL;
97*4ba319b5SDimitry Andric   case RISCV::fixup_riscv_relax:
98*4ba319b5SDimitry Andric     return ELF::R_RISCV_RELAX;
992cab237bSDimitry Andric   }
100d88c1a5aSDimitry Andric }
101d88c1a5aSDimitry Andric 
102*4ba319b5SDimitry Andric std::unique_ptr<MCObjectTargetWriter>
createRISCVELFObjectWriter(uint8_t OSABI,bool Is64Bit)103*4ba319b5SDimitry Andric llvm::createRISCVELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
104*4ba319b5SDimitry Andric   return llvm::make_unique<RISCVELFObjectWriter>(OSABI, Is64Bit);
105d88c1a5aSDimitry Andric }
106