1*d415bd75Srobert //===-- M68kELFObjectWriter.cpp - M68k ELF Writer ---------------*- C++ -*-===//
273471bf0Spatrick //
373471bf0Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
473471bf0Spatrick // See https://llvm.org/LICENSE.txt for license information.
573471bf0Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
673471bf0Spatrick //
773471bf0Spatrick //===----------------------------------------------------------------------===//
873471bf0Spatrick ///
973471bf0Spatrick /// \file
1073471bf0Spatrick /// This file contains definitions for M68k ELF Writers
1173471bf0Spatrick ///
1273471bf0Spatrick //===----------------------------------------------------------------------===//
1373471bf0Spatrick
1473471bf0Spatrick #include "MCTargetDesc/M68kFixupKinds.h"
1573471bf0Spatrick #include "MCTargetDesc/M68kMCTargetDesc.h"
1673471bf0Spatrick
1773471bf0Spatrick #include "llvm/BinaryFormat/ELF.h"
1873471bf0Spatrick #include "llvm/MC/MCAsmInfo.h"
1973471bf0Spatrick #include "llvm/MC/MCContext.h"
2073471bf0Spatrick #include "llvm/MC/MCELFObjectWriter.h"
2173471bf0Spatrick #include "llvm/MC/MCExpr.h"
2273471bf0Spatrick #include "llvm/MC/MCValue.h"
2373471bf0Spatrick #include "llvm/Support/ErrorHandling.h"
2473471bf0Spatrick
2573471bf0Spatrick using namespace llvm;
2673471bf0Spatrick
2773471bf0Spatrick namespace {
2873471bf0Spatrick class M68kELFObjectWriter : public MCELFObjectTargetWriter {
2973471bf0Spatrick public:
3073471bf0Spatrick M68kELFObjectWriter(uint8_t OSABI);
3173471bf0Spatrick
3273471bf0Spatrick ~M68kELFObjectWriter() override;
3373471bf0Spatrick
3473471bf0Spatrick protected:
3573471bf0Spatrick unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
3673471bf0Spatrick const MCFixup &Fixup, bool IsPCRel) const override;
3773471bf0Spatrick };
3873471bf0Spatrick } // namespace
3973471bf0Spatrick
M68kELFObjectWriter(uint8_t OSABI)4073471bf0Spatrick M68kELFObjectWriter::M68kELFObjectWriter(uint8_t OSABI)
4173471bf0Spatrick : MCELFObjectTargetWriter(false, OSABI, ELF::EM_68K, /* RELA */ true) {}
4273471bf0Spatrick
~M68kELFObjectWriter()4373471bf0Spatrick M68kELFObjectWriter::~M68kELFObjectWriter() {}
4473471bf0Spatrick
4573471bf0Spatrick enum M68kRelType { RT_32, RT_16, RT_8 };
4673471bf0Spatrick
4773471bf0Spatrick static M68kRelType
getType(unsigned Kind,MCSymbolRefExpr::VariantKind & Modifier,bool & IsPCRel)4873471bf0Spatrick getType(unsigned Kind, MCSymbolRefExpr::VariantKind &Modifier, bool &IsPCRel) {
4973471bf0Spatrick switch (Kind) {
5073471bf0Spatrick case FK_Data_4:
5173471bf0Spatrick case FK_PCRel_4:
5273471bf0Spatrick return RT_32;
5373471bf0Spatrick case FK_PCRel_2:
5473471bf0Spatrick case FK_Data_2:
5573471bf0Spatrick return RT_16;
5673471bf0Spatrick case FK_PCRel_1:
5773471bf0Spatrick case FK_Data_1:
5873471bf0Spatrick return RT_8;
5973471bf0Spatrick }
6073471bf0Spatrick llvm_unreachable("Unimplemented");
6173471bf0Spatrick }
6273471bf0Spatrick
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const6373471bf0Spatrick unsigned M68kELFObjectWriter::getRelocType(MCContext &Ctx,
6473471bf0Spatrick const MCValue &Target,
6573471bf0Spatrick const MCFixup &Fixup,
6673471bf0Spatrick bool IsPCRel) const {
6773471bf0Spatrick MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
6873471bf0Spatrick unsigned Kind = Fixup.getKind();
6973471bf0Spatrick M68kRelType Type = getType(Kind, Modifier, IsPCRel);
7073471bf0Spatrick switch (Modifier) {
7173471bf0Spatrick default:
7273471bf0Spatrick llvm_unreachable("Unimplemented");
7373471bf0Spatrick case MCSymbolRefExpr::VK_None:
7473471bf0Spatrick switch (Type) {
7573471bf0Spatrick case RT_32:
7673471bf0Spatrick return IsPCRel ? ELF::R_68K_PC32 : ELF::R_68K_32;
7773471bf0Spatrick case RT_16:
7873471bf0Spatrick return IsPCRel ? ELF::R_68K_PC16 : ELF::R_68K_16;
7973471bf0Spatrick case RT_8:
8073471bf0Spatrick return IsPCRel ? ELF::R_68K_PC8 : ELF::R_68K_8;
8173471bf0Spatrick }
8273471bf0Spatrick llvm_unreachable("Unrecognized size");
8373471bf0Spatrick case MCSymbolRefExpr::VK_GOTPCREL:
8473471bf0Spatrick switch (Type) {
8573471bf0Spatrick case RT_32:
8673471bf0Spatrick return ELF::R_68K_GOTPCREL32;
8773471bf0Spatrick case RT_16:
8873471bf0Spatrick return ELF::R_68K_GOTPCREL16;
8973471bf0Spatrick case RT_8:
9073471bf0Spatrick return ELF::R_68K_GOTPCREL8;
9173471bf0Spatrick }
9273471bf0Spatrick llvm_unreachable("Unrecognized size");
9373471bf0Spatrick case MCSymbolRefExpr::VK_GOTOFF:
9473471bf0Spatrick assert(!IsPCRel);
9573471bf0Spatrick switch (Type) {
9673471bf0Spatrick case RT_32:
9773471bf0Spatrick return ELF::R_68K_GOTOFF32;
9873471bf0Spatrick case RT_16:
9973471bf0Spatrick return ELF::R_68K_GOTOFF16;
10073471bf0Spatrick case RT_8:
10173471bf0Spatrick return ELF::R_68K_GOTOFF8;
10273471bf0Spatrick }
10373471bf0Spatrick llvm_unreachable("Unrecognized size");
10473471bf0Spatrick case MCSymbolRefExpr::VK_PLT:
10573471bf0Spatrick switch (Type) {
10673471bf0Spatrick case RT_32:
10773471bf0Spatrick return ELF::R_68K_PLT32;
10873471bf0Spatrick case RT_16:
10973471bf0Spatrick return ELF::R_68K_PLT16;
11073471bf0Spatrick case RT_8:
11173471bf0Spatrick return ELF::R_68K_PLT8;
11273471bf0Spatrick }
11373471bf0Spatrick llvm_unreachable("Unrecognized size");
11473471bf0Spatrick }
11573471bf0Spatrick }
11673471bf0Spatrick
11773471bf0Spatrick std::unique_ptr<MCObjectTargetWriter>
createM68kELFObjectWriter(uint8_t OSABI)11873471bf0Spatrick llvm::createM68kELFObjectWriter(uint8_t OSABI) {
11973471bf0Spatrick return std::make_unique<M68kELFObjectWriter>(OSABI);
12073471bf0Spatrick }
121