1 //===-- CSKYELFObjectWriter.cpp - CSKY 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 "CSKYFixupKinds.h"
10 #include "CSKYMCExpr.h"
11 #include "CSKYMCTargetDesc.h"
12 #include "llvm/MC/MCContext.h"
13 #include "llvm/MC/MCELFObjectWriter.h"
14 #include "llvm/MC/MCObjectWriter.h"
15
16 #define DEBUG_TYPE "csky-elf-object-writer"
17
18 using namespace llvm;
19
20 namespace {
21
22 class CSKYELFObjectWriter : public MCELFObjectTargetWriter {
23 public:
CSKYELFObjectWriter(uint8_t OSABI=0)24 CSKYELFObjectWriter(uint8_t OSABI = 0)
25 : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){};
~CSKYELFObjectWriter()26 ~CSKYELFObjectWriter() {}
27
28 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
29 const MCFixup &Fixup, bool IsPCRel) const override;
30 };
31
32 } // namespace
33
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const34 unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
35 const MCValue &Target,
36 const MCFixup &Fixup,
37 bool IsPCRel) const {
38 const MCExpr *Expr = Fixup.getValue();
39 // Determine the type of the relocation
40 unsigned Kind = Fixup.getTargetKind();
41 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
42
43 if (IsPCRel) {
44 switch (Kind) {
45 default:
46 LLVM_DEBUG(dbgs() << "Unknown Kind1 = " << Kind);
47 Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
48 return ELF::R_CKCORE_NONE;
49 case FK_Data_4:
50 case FK_PCRel_4:
51 return ELF::R_CKCORE_PCREL32;
52 case CSKY::fixup_csky_pcrel_uimm16_scale4:
53 return ELF::R_CKCORE_PCREL_IMM16_4;
54 case CSKY::fixup_csky_pcrel_uimm8_scale4:
55 return ELF::R_CKCORE_PCREL_IMM8_4;
56 case CSKY::fixup_csky_pcrel_imm26_scale2:
57 return ELF::R_CKCORE_PCREL_IMM26_2;
58 case CSKY::fixup_csky_pcrel_imm18_scale2:
59 return ELF::R_CKCORE_PCREL_IMM18_2;
60 case CSKY::fixup_csky_pcrel_imm16_scale2:
61 return ELF::R_CKCORE_PCREL_IMM16_2;
62 case CSKY::fixup_csky_pcrel_imm10_scale2:
63 return ELF::R_CKCORE_PCREL_IMM10_2;
64 case CSKY::fixup_csky_pcrel_uimm7_scale4:
65 return ELF::R_CKCORE_PCREL_IMM7_4;
66 }
67 }
68
69 switch (Kind) {
70 default:
71 LLVM_DEBUG(dbgs() << "Unknown Kind2 = " << Kind);
72 Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
73 return ELF::R_CKCORE_NONE;
74 case FK_Data_1:
75 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
76 return ELF::R_CKCORE_NONE;
77 case FK_Data_2:
78 Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
79 return ELF::R_CKCORE_NONE;
80 case FK_Data_4:
81 if (Expr->getKind() == MCExpr::Target) {
82 auto TK = cast<CSKYMCExpr>(Expr)->getKind();
83 if (TK == CSKYMCExpr::VK_CSKY_ADDR)
84 return ELF::R_CKCORE_ADDR32;
85 if (TK == CSKYMCExpr::VK_CSKY_GOT)
86 return ELF::R_CKCORE_GOT32;
87 if (TK == CSKYMCExpr::VK_CSKY_GOTOFF)
88 return ELF::R_CKCORE_GOTOFF;
89 if (TK == CSKYMCExpr::VK_CSKY_PLT)
90 return ELF::R_CKCORE_PLT32;
91 if (TK == CSKYMCExpr::VK_CSKY_TLSIE)
92 return ELF::R_CKCORE_TLS_IE32;
93 if (TK == CSKYMCExpr::VK_CSKY_TLSLE)
94 return ELF::R_CKCORE_TLS_LE32;
95 if (TK == CSKYMCExpr::VK_CSKY_TLSGD)
96 return ELF::R_CKCORE_TLS_GD32;
97 if (TK == CSKYMCExpr::VK_CSKY_TLSLDM)
98 return ELF::R_CKCORE_TLS_LDM32;
99 if (TK == CSKYMCExpr::VK_CSKY_TLSLDO)
100 return ELF::R_CKCORE_TLS_LDO32;
101 if (TK == CSKYMCExpr::VK_CSKY_GOTPC)
102 return ELF::R_CKCORE_GOTPC;
103 if (TK == CSKYMCExpr::VK_CSKY_None)
104 return ELF::R_CKCORE_ADDR32;
105
106 LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK = " << TK);
107 Ctx.reportError(Fixup.getLoc(), "unknown target FK_Data_4");
108 } else {
109 switch (Modifier) {
110 default:
111 Ctx.reportError(Fixup.getLoc(),
112 "invalid fixup for 4-byte data relocation");
113 return ELF::R_CKCORE_NONE;
114 case MCSymbolRefExpr::VK_GOT:
115 return ELF::R_CKCORE_GOT32;
116 case MCSymbolRefExpr::VK_GOTOFF:
117 return ELF::R_CKCORE_GOTOFF;
118 case MCSymbolRefExpr::VK_PLT:
119 return ELF::R_CKCORE_PLT32;
120 case MCSymbolRefExpr::VK_TLSGD:
121 return ELF::R_CKCORE_TLS_GD32;
122 case MCSymbolRefExpr::VK_TLSLDM:
123 return ELF::R_CKCORE_TLS_LDM32;
124 case MCSymbolRefExpr::VK_TPOFF:
125 return ELF::R_CKCORE_TLS_LE32;
126 case MCSymbolRefExpr::VK_None:
127 return ELF::R_CKCORE_ADDR32;
128 }
129 }
130 return ELF::R_CKCORE_NONE;
131 case FK_Data_8:
132 Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported");
133 return ELF::R_CKCORE_NONE;
134 case CSKY::fixup_csky_addr32:
135 return ELF::R_CKCORE_ADDR32;
136 case CSKY::fixup_csky_addr_hi16:
137 return ELF::R_CKCORE_ADDR_HI16;
138 case CSKY::fixup_csky_addr_lo16:
139 return ELF::R_CKCORE_ADDR_LO16;
140 case CSKY::fixup_csky_doffset_imm18:
141 return ELF::R_CKCORE_DOFFSET_IMM18;
142 case CSKY::fixup_csky_doffset_imm18_scale2:
143 return ELF::R_CKCORE_DOFFSET_IMM18_2;
144 case CSKY::fixup_csky_doffset_imm18_scale4:
145 return ELF::R_CKCORE_DOFFSET_IMM18_4;
146 case CSKY::fixup_csky_got_imm18_scale4:
147 return ELF::R_CKCORE_GOT_IMM18_4;
148 case CSKY::fixup_csky_plt_imm18_scale4:
149 return ELF::R_CKCORE_PLT_IMM18_4;
150 }
151 }
152
createCSKYELFObjectWriter()153 std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() {
154 return std::make_unique<CSKYELFObjectWriter>();
155 }
156