xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFObjectWriter.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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 
981ad6265SDimitry Andric #include "CSKYFixupKinds.h"
1081ad6265SDimitry 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:
CSKYELFObjectWriter(uint8_t OSABI=0)24e8d8bef9SDimitry Andric   CSKYELFObjectWriter(uint8_t OSABI = 0)
25e8d8bef9SDimitry Andric       : MCELFObjectTargetWriter(false, OSABI, ELF::EM_CSKY, true){};
~CSKYELFObjectWriter()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 
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const34e8d8bef9SDimitry Andric unsigned CSKYELFObjectWriter::getRelocType(MCContext &Ctx,
35e8d8bef9SDimitry Andric                                            const MCValue &Target,
36e8d8bef9SDimitry Andric                                            const MCFixup &Fixup,
37e8d8bef9SDimitry Andric                                            bool IsPCRel) const {
3881ad6265SDimitry Andric   const MCExpr *Expr = Fixup.getValue();
3981ad6265SDimitry Andric   // Determine the type of the relocation
4081ad6265SDimitry Andric   unsigned Kind = Fixup.getTargetKind();
4181ad6265SDimitry Andric   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
4281ad6265SDimitry Andric 
4381ad6265SDimitry Andric   if (IsPCRel) {
4481ad6265SDimitry Andric     switch (Kind) {
45e8d8bef9SDimitry Andric     default:
4681ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << "Unknown Kind1  = " << Kind);
4781ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
4881ad6265SDimitry Andric       return ELF::R_CKCORE_NONE;
4981ad6265SDimitry Andric     case FK_Data_4:
5081ad6265SDimitry Andric     case FK_PCRel_4:
5181ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL32;
5281ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_uimm16_scale4:
5381ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM16_4;
5481ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_uimm8_scale4:
5581ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM8_4;
5681ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_imm26_scale2:
5781ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM26_2;
5881ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_imm18_scale2:
5981ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM18_2;
6081ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_imm16_scale2:
6181ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM16_2;
6281ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_imm10_scale2:
6381ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM10_2;
6481ad6265SDimitry Andric     case CSKY::fixup_csky_pcrel_uimm7_scale4:
6581ad6265SDimitry Andric       return ELF::R_CKCORE_PCREL_IMM7_4;
6681ad6265SDimitry Andric     }
6781ad6265SDimitry Andric   }
6881ad6265SDimitry Andric 
6981ad6265SDimitry Andric   switch (Kind) {
7081ad6265SDimitry Andric   default:
7181ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << "Unknown Kind2  = " << Kind);
7281ad6265SDimitry Andric     Ctx.reportError(Fixup.getLoc(), "Unsupported relocation type");
7381ad6265SDimitry Andric     return ELF::R_CKCORE_NONE;
7481ad6265SDimitry Andric   case FK_Data_1:
7581ad6265SDimitry Andric     Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
7681ad6265SDimitry Andric     return ELF::R_CKCORE_NONE;
7781ad6265SDimitry Andric   case FK_Data_2:
7881ad6265SDimitry Andric     Ctx.reportError(Fixup.getLoc(), "2-byte data relocations not supported");
7981ad6265SDimitry Andric     return ELF::R_CKCORE_NONE;
8081ad6265SDimitry Andric   case FK_Data_4:
8181ad6265SDimitry Andric     if (Expr->getKind() == MCExpr::Target) {
8281ad6265SDimitry Andric       auto TK = cast<CSKYMCExpr>(Expr)->getKind();
8381ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_ADDR)
8481ad6265SDimitry Andric         return ELF::R_CKCORE_ADDR32;
8581ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_GOT)
8681ad6265SDimitry Andric         return ELF::R_CKCORE_GOT32;
8781ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_GOTOFF)
8881ad6265SDimitry Andric         return ELF::R_CKCORE_GOTOFF;
8981ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_PLT)
9081ad6265SDimitry Andric         return ELF::R_CKCORE_PLT32;
9181ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_TLSIE)
9281ad6265SDimitry Andric         return ELF::R_CKCORE_TLS_IE32;
9381ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_TLSLE)
9481ad6265SDimitry Andric         return ELF::R_CKCORE_TLS_LE32;
9581ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_TLSGD)
9681ad6265SDimitry Andric         return ELF::R_CKCORE_TLS_GD32;
9781ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_TLSLDM)
9881ad6265SDimitry Andric         return ELF::R_CKCORE_TLS_LDM32;
9981ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_TLSLDO)
10081ad6265SDimitry Andric         return ELF::R_CKCORE_TLS_LDO32;
10181ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_GOTPC)
10281ad6265SDimitry Andric         return ELF::R_CKCORE_GOTPC;
10381ad6265SDimitry Andric       if (TK == CSKYMCExpr::VK_CSKY_None)
10481ad6265SDimitry Andric         return ELF::R_CKCORE_ADDR32;
10581ad6265SDimitry Andric 
10681ad6265SDimitry Andric       LLVM_DEBUG(dbgs() << "Unknown FK_Data_4 TK  = " << TK);
10781ad6265SDimitry Andric       Ctx.reportError(Fixup.getLoc(), "unknown target FK_Data_4");
10881ad6265SDimitry Andric     } else {
10981ad6265SDimitry Andric       switch (Modifier) {
11081ad6265SDimitry Andric       default:
11181ad6265SDimitry Andric         Ctx.reportError(Fixup.getLoc(),
11281ad6265SDimitry Andric                         "invalid fixup for 4-byte data relocation");
11381ad6265SDimitry Andric         return ELF::R_CKCORE_NONE;
11481ad6265SDimitry Andric       case MCSymbolRefExpr::VK_GOT:
11581ad6265SDimitry Andric         return ELF::R_CKCORE_GOT32;
11681ad6265SDimitry Andric       case MCSymbolRefExpr::VK_GOTOFF:
11781ad6265SDimitry Andric         return ELF::R_CKCORE_GOTOFF;
11881ad6265SDimitry Andric       case MCSymbolRefExpr::VK_PLT:
11981ad6265SDimitry Andric         return ELF::R_CKCORE_PLT32;
120*06c3fb27SDimitry Andric       case MCSymbolRefExpr::VK_TLSGD:
121*06c3fb27SDimitry Andric         return ELF::R_CKCORE_TLS_GD32;
122*06c3fb27SDimitry Andric       case MCSymbolRefExpr::VK_TLSLDM:
123*06c3fb27SDimitry Andric         return ELF::R_CKCORE_TLS_LDM32;
124*06c3fb27SDimitry Andric       case MCSymbolRefExpr::VK_TPOFF:
125*06c3fb27SDimitry Andric         return ELF::R_CKCORE_TLS_LE32;
12681ad6265SDimitry Andric       case MCSymbolRefExpr::VK_None:
12781ad6265SDimitry Andric         return ELF::R_CKCORE_ADDR32;
12881ad6265SDimitry Andric       }
12981ad6265SDimitry Andric     }
13081ad6265SDimitry Andric     return ELF::R_CKCORE_NONE;
13181ad6265SDimitry Andric   case FK_Data_8:
13281ad6265SDimitry Andric     Ctx.reportError(Fixup.getLoc(), "8-byte data relocations not supported");
13381ad6265SDimitry Andric     return ELF::R_CKCORE_NONE;
13481ad6265SDimitry Andric   case CSKY::fixup_csky_addr32:
13581ad6265SDimitry Andric     return ELF::R_CKCORE_ADDR32;
13681ad6265SDimitry Andric   case CSKY::fixup_csky_addr_hi16:
13781ad6265SDimitry Andric     return ELF::R_CKCORE_ADDR_HI16;
13881ad6265SDimitry Andric   case CSKY::fixup_csky_addr_lo16:
13981ad6265SDimitry Andric     return ELF::R_CKCORE_ADDR_LO16;
14081ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18:
14181ad6265SDimitry Andric     return ELF::R_CKCORE_DOFFSET_IMM18;
14281ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18_scale2:
14381ad6265SDimitry Andric     return ELF::R_CKCORE_DOFFSET_IMM18_2;
14481ad6265SDimitry Andric   case CSKY::fixup_csky_doffset_imm18_scale4:
14581ad6265SDimitry Andric     return ELF::R_CKCORE_DOFFSET_IMM18_4;
14681ad6265SDimitry Andric   case CSKY::fixup_csky_got_imm18_scale4:
14781ad6265SDimitry Andric     return ELF::R_CKCORE_GOT_IMM18_4;
14881ad6265SDimitry Andric   case CSKY::fixup_csky_plt_imm18_scale4:
14981ad6265SDimitry Andric     return ELF::R_CKCORE_PLT_IMM18_4;
150e8d8bef9SDimitry Andric   }
151e8d8bef9SDimitry Andric }
152e8d8bef9SDimitry Andric 
createCSKYELFObjectWriter()153e8d8bef9SDimitry Andric std::unique_ptr<MCObjectTargetWriter> llvm::createCSKYELFObjectWriter() {
154e8d8bef9SDimitry Andric   return std::make_unique<CSKYELFObjectWriter>();
155e8d8bef9SDimitry Andric }
156