xref: /llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp (revision 6922eedd46a991766ba8d568183250b94b1842b3)
1ec17c4f0SZi Xuan Wu //===-- CSKYELFObjectWriter.cpp - CSKY ELF Writer -------------------------===//
2ec17c4f0SZi Xuan Wu //
3ec17c4f0SZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ec17c4f0SZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
5ec17c4f0SZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec17c4f0SZi Xuan Wu //
7ec17c4f0SZi Xuan Wu //===----------------------------------------------------------------------===//
8ec17c4f0SZi Xuan Wu 
9582836faSZi Xuan Wu #include "CSKYFixupKinds.h"
10582836faSZi Xuan Wu #include "CSKYMCExpr.h"
110365c54cSZi Xuan Wu #include "CSKYMCTargetDesc.h"
12ec17c4f0SZi Xuan Wu #include "llvm/MC/MCContext.h"
13ec17c4f0SZi Xuan Wu #include "llvm/MC/MCELFObjectWriter.h"
14ec17c4f0SZi Xuan Wu #include "llvm/MC/MCObjectWriter.h"
15ec17c4f0SZi Xuan Wu 
16ec17c4f0SZi Xuan Wu #define DEBUG_TYPE "csky-elf-object-writer"
17ec17c4f0SZi Xuan Wu 
18ec17c4f0SZi Xuan Wu using namespace llvm;
19ec17c4f0SZi Xuan Wu 
20ec17c4f0SZi Xuan Wu namespace {
21ec17c4f0SZi Xuan Wu 
22ec17c4f0SZi Xuan Wu class CSKYELFObjectWriter : public MCELFObjectTargetWriter {
23ec17c4f0SZi Xuan Wu public:
CSKYELFObjectWriter(uint8_t OSABI=0)24ec17c4f0SZi Xuan Wu   CSKYELFObjectWriter(uint8_t OSABI = 0)
25ec17c4f0SZi Xuan Wu       : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){};
~CSKYELFObjectWriter()26ec17c4f0SZi Xuan Wu   ~CSKYELFObjectWriter() {}
27ec17c4f0SZi Xuan Wu 
28ec17c4f0SZi Xuan Wu   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29ec17c4f0SZi Xuan Wu                         const MCFixup &Fixup, bool IsPCRel) const override;
30ec17c4f0SZi Xuan Wu };
31ec17c4f0SZi Xuan Wu 
32ec17c4f0SZi Xuan Wu } // namespace
33ec17c4f0SZi Xuan Wu 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const34ec17c4f0SZi Xuan Wu unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
35ec17c4f0SZi Xuan Wu                                            const MCValue &Target,
36ec17c4f0SZi Xuan Wu                                            const MCFixup &Fixup,
37ec17c4f0SZi Xuan Wu                                            bool IsPCRel) const {
38582836faSZi Xuan Wu   const MCExpr *Expr = Fixup.getValue();
39582836faSZi Xuan Wu   // Determine the type of the relocation
40582836faSZi Xuan Wu   unsigned Kind = Fixup.getTargetKind();
41582836faSZi Xuan Wu   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
42582836faSZi Xuan Wu 
43582836faSZi Xuan Wu   if (IsPCRel) {
44582836faSZi Xuan Wu     switch (Kind) {
45ec17c4f0SZi Xuan Wu     default:
46582836faSZi Xuan Wu       LLVM_DEBUG(dbgs() << "Unknown Kind1  = " << Kind);
47582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
48582836faSZi Xuan Wu       return ELF::R_CKCORE_NONE;
49582836faSZi Xuan Wu     case FK_Data_4:
50582836faSZi Xuan Wu     case FK_PCRel_4:
51582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL32;
52582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_uimm16_scale4:
53582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM16_4;
54582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_uimm8_scale4:
55582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM8_4;
56582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_imm26_scale2:
57582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM26_2;
58582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_imm18_scale2:
59582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM18_2;
60582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_imm16_scale2:
61582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM16_2;
62582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_imm10_scale2:
63582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM10_2;
64582836faSZi Xuan Wu     case CSKY::fixup_csky_pcrel_uimm7_scale4:
65582836faSZi Xuan Wu       return ELF::R_CKCORE_PCREL_IMM7_4;
66582836faSZi Xuan Wu     }
67582836faSZi Xuan Wu   }
68582836faSZi Xuan Wu 
69582836faSZi Xuan Wu   switch (Kind) {
70582836faSZi Xuan Wu   default:
71582836faSZi Xuan Wu     LLVM_DEBUG(dbgs() << "Unknown Kind2  = " << Kind);
72582836faSZi Xuan Wu     Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
73582836faSZi Xuan Wu     return ELF::R_CKCORE_NONE;
74582836faSZi Xuan Wu   case FK_Data_1:
75582836faSZi Xuan Wu     Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
76582836faSZi Xuan Wu     return ELF::R_CKCORE_NONE;
77582836faSZi Xuan Wu   case FK_Data_2:
78582836faSZi Xuan Wu     Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
79582836faSZi Xuan Wu     return ELF::R_CKCORE_NONE;
80582836faSZi Xuan Wu   case FK_Data_4:
81582836faSZi Xuan Wu     if (Expr->getKind() == MCExpr::Target) {
82582836faSZi Xuan Wu       auto TK = cast<CSKYMCExpr>(Expr)->getKind();
83582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_ADDR)
84582836faSZi Xuan Wu         return ELF::R_CKCORE_ADDR32;
85582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_GOT)
86582836faSZi Xuan Wu         return ELF::R_CKCORE_GOT32;
87582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_GOTOFF)
88582836faSZi Xuan Wu         return ELF::R_CKCORE_GOTOFF;
89582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_PLT)
90582836faSZi Xuan Wu         return ELF::R_CKCORE_PLT32;
91582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_TLSIE)
92582836faSZi Xuan Wu         return ELF::R_CKCORE_TLS_IE32;
93582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_TLSLE)
94582836faSZi Xuan Wu         return ELF::R_CKCORE_TLS_LE32;
95582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_TLSGD)
96582836faSZi Xuan Wu         return ELF::R_CKCORE_TLS_GD32;
97582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_TLSLDM)
98582836faSZi Xuan Wu         return ELF::R_CKCORE_TLS_LDM32;
99582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_TLSLDO)
100582836faSZi Xuan Wu         return ELF::R_CKCORE_TLS_LDO32;
101582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_GOTPC)
102582836faSZi Xuan Wu         return ELF::R_CKCORE_GOTPC;
103582836faSZi Xuan Wu       if (TK == CSKYMCExpr::VK_CSKY_None)
104582836faSZi Xuan Wu         return ELF::R_CKCORE_ADDR32;
105582836faSZi Xuan Wu 
106582836faSZi Xuan Wu       LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK  = " << TK);
107582836faSZi Xuan Wu       Ctx.reportError(Fixup.getLoc(), "unknown target FK_Data_4");
108582836faSZi Xuan Wu     } else {
109582836faSZi Xuan Wu       switch (Modifier) {
110582836faSZi Xuan Wu       default:
111582836faSZi Xuan Wu         Ctx.reportError(Fixup.getLoc(),
112582836faSZi Xuan Wu                         "invalid fixup for 4-byte data relocation");
113582836faSZi Xuan Wu         return ELF::R_CKCORE_NONE;
114582836faSZi Xuan Wu       case MCSymbolRefExpr::VK_GOT:
115582836faSZi Xuan Wu         return ELF::R_CKCORE_GOT32;
116582836faSZi Xuan Wu       case MCSymbolRefExpr::VK_GOTOFF:
117582836faSZi Xuan Wu         return ELF::R_CKCORE_GOTOFF;
118582836faSZi Xuan Wu       case MCSymbolRefExpr::VK_PLT:
119582836faSZi Xuan Wu         return ELF::R_CKCORE_PLT32;
120*6922eeddSZi Xuan Wu (Zeson)       case MCSymbolRefExpr::VK_TLSGD:
121*6922eeddSZi Xuan Wu (Zeson)         return ELF::R_CKCORE_TLS_GD32;
122*6922eeddSZi Xuan Wu (Zeson)       case MCSymbolRefExpr::VK_TLSLDM:
123*6922eeddSZi Xuan Wu (Zeson)         return ELF::R_CKCORE_TLS_LDM32;
124*6922eeddSZi Xuan Wu (Zeson)       case MCSymbolRefExpr::VK_TPOFF:
125*6922eeddSZi Xuan Wu (Zeson)         return ELF::R_CKCORE_TLS_LE32;
126582836faSZi Xuan Wu       case MCSymbolRefExpr::VK_None:
127582836faSZi Xuan Wu         return ELF::R_CKCORE_ADDR32;
128582836faSZi Xuan Wu       }
129582836faSZi Xuan Wu     }
130ef437a7dSFangrui Song     return ELF::R_CKCORE_NONE;
131582836faSZi Xuan Wu   case FK_Data_8:
132582836faSZi Xuan Wu     Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported");
133582836faSZi Xuan Wu     return ELF::R_CKCORE_NONE;
134582836faSZi Xuan Wu   case CSKY::fixup_csky_addr32:
135582836faSZi Xuan Wu     return ELF::R_CKCORE_ADDR32;
136582836faSZi Xuan Wu   case CSKY::fixup_csky_addr_hi16:
137582836faSZi Xuan Wu     return ELF::R_CKCORE_ADDR_HI16;
138582836faSZi Xuan Wu   case CSKY::fixup_csky_addr_lo16:
139582836faSZi Xuan Wu     return ELF::R_CKCORE_ADDR_LO16;
140582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18:
141582836faSZi Xuan Wu     return ELF::R_CKCORE_DOFFSET_IMM18;
142582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18_scale2:
143582836faSZi Xuan Wu     return ELF::R_CKCORE_DOFFSET_IMM18_2;
144582836faSZi Xuan Wu   case CSKY::fixup_csky_doffset_imm18_scale4:
145582836faSZi Xuan Wu     return ELF::R_CKCORE_DOFFSET_IMM18_4;
146582836faSZi Xuan Wu   case CSKY::fixup_csky_got_imm18_scale4:
147582836faSZi Xuan Wu     return ELF::R_CKCORE_GOT_IMM18_4;
148582836faSZi Xuan Wu   case CSKY::fixup_csky_plt_imm18_scale4:
149582836faSZi Xuan Wu     return ELF::R_CKCORE_PLT_IMM18_4;
150ec17c4f0SZi Xuan Wu   }
151ec17c4f0SZi Xuan Wu }
152ec17c4f0SZi Xuan Wu 
createCSKYELFObjectWriter()153ec17c4f0SZi Xuan Wu std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() {
154ec17c4f0SZi Xuan Wu   return std::make_unique<CSKYELFObjectWriter>();
155ec17c4f0SZi Xuan Wu }
156