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