157 lines · cpp
1//===-- AVRELFObjectWriter.cpp - AVR 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/AVRFixupKinds.h"10#include "MCTargetDesc/AVRMCAsmInfo.h"11#include "MCTargetDesc/AVRMCTargetDesc.h"12 13#include "llvm/MC/MCAssembler.h"14#include "llvm/MC/MCELFObjectWriter.h"15#include "llvm/MC/MCExpr.h"16#include "llvm/MC/MCObjectWriter.h"17#include "llvm/MC/MCValue.h"18#include "llvm/Support/ErrorHandling.h"19 20namespace llvm {21 22/// Writes AVR machine code into an ELF32 object file.23class AVRELFObjectWriter : public MCELFObjectTargetWriter {24public:25 AVRELFObjectWriter(uint8_t OSABI);26 27 ~AVRELFObjectWriter() override = default;28 29 unsigned getRelocType(const MCFixup &, const MCValue &,30 bool IsPCRel) const override;31};32 33AVRELFObjectWriter::AVRELFObjectWriter(uint8_t OSABI)34 : MCELFObjectTargetWriter(false, OSABI, ELF::EM_AVR, true) {}35 36unsigned AVRELFObjectWriter::getRelocType(const MCFixup &Fixup,37 const MCValue &Target,38 bool IsPCRel) const {39 auto Spec = Target.getSpecifier();40 switch ((unsigned)Fixup.getKind()) {41 case FK_Data_1:42 switch (Spec) {43 default:44 llvm_unreachable("Unsupported Modifier");45 case AVR::S_None:46 return ELF::R_AVR_8;47 case AVR::S_DIFF8:48 return ELF::R_AVR_DIFF8;49 case AVR::S_LO8:50 return ELF::R_AVR_8_LO8;51 case AVR::S_HI8:52 return ELF::R_AVR_8_HI8;53 case AVR::S_HH8:54 return ELF::R_AVR_8_HLO8;55 }56 case FK_Data_4:57 switch (Spec) {58 default:59 llvm_unreachable("Unsupported Modifier");60 case AVR::S_None:61 return ELF::R_AVR_32;62 case AVR::S_DIFF32:63 return ELF::R_AVR_DIFF32;64 }65 case FK_Data_2:66 switch (Spec) {67 default:68 llvm_unreachable("Unsupported Modifier");69 case AVR::S_None:70 return ELF::R_AVR_16;71 case AVR::S_AVR_NONE:72 case AVR::S_PM:73 return ELF::R_AVR_16_PM;74 case AVR::S_DIFF16:75 return ELF::R_AVR_DIFF16;76 }77 case AVR::fixup_32:78 return ELF::R_AVR_32;79 case AVR::fixup_7_pcrel:80 return ELF::R_AVR_7_PCREL;81 case AVR::fixup_13_pcrel:82 return ELF::R_AVR_13_PCREL;83 case AVR::fixup_16:84 return ELF::R_AVR_16;85 case AVR::fixup_16_pm:86 return ELF::R_AVR_16_PM;87 case AVR::fixup_lo8_ldi:88 return ELF::R_AVR_LO8_LDI;89 case AVR::fixup_hi8_ldi:90 return ELF::R_AVR_HI8_LDI;91 case AVR::fixup_hh8_ldi:92 return ELF::R_AVR_HH8_LDI;93 case AVR::fixup_lo8_ldi_neg:94 return ELF::R_AVR_LO8_LDI_NEG;95 case AVR::fixup_hi8_ldi_neg:96 return ELF::R_AVR_HI8_LDI_NEG;97 case AVR::fixup_hh8_ldi_neg:98 return ELF::R_AVR_HH8_LDI_NEG;99 case AVR::fixup_lo8_ldi_pm:100 return ELF::R_AVR_LO8_LDI_PM;101 case AVR::fixup_hi8_ldi_pm:102 return ELF::R_AVR_HI8_LDI_PM;103 case AVR::fixup_hh8_ldi_pm:104 return ELF::R_AVR_HH8_LDI_PM;105 case AVR::fixup_lo8_ldi_pm_neg:106 return ELF::R_AVR_LO8_LDI_PM_NEG;107 case AVR::fixup_hi8_ldi_pm_neg:108 return ELF::R_AVR_HI8_LDI_PM_NEG;109 case AVR::fixup_hh8_ldi_pm_neg:110 return ELF::R_AVR_HH8_LDI_PM_NEG;111 case AVR::fixup_call:112 return ELF::R_AVR_CALL;113 case AVR::fixup_ldi:114 return ELF::R_AVR_LDI;115 case AVR::fixup_6:116 return ELF::R_AVR_6;117 case AVR::fixup_6_adiw:118 return ELF::R_AVR_6_ADIW;119 case AVR::fixup_ms8_ldi:120 return ELF::R_AVR_MS8_LDI;121 case AVR::fixup_ms8_ldi_neg:122 return ELF::R_AVR_MS8_LDI_NEG;123 case AVR::fixup_lo8_ldi_gs:124 return ELF::R_AVR_LO8_LDI_GS;125 case AVR::fixup_hi8_ldi_gs:126 return ELF::R_AVR_HI8_LDI_GS;127 case AVR::fixup_8:128 return ELF::R_AVR_8;129 case AVR::fixup_8_lo8:130 return ELF::R_AVR_8_LO8;131 case AVR::fixup_8_hi8:132 return ELF::R_AVR_8_HI8;133 case AVR::fixup_8_hlo8:134 return ELF::R_AVR_8_HLO8;135 case AVR::fixup_diff8:136 return ELF::R_AVR_DIFF8;137 case AVR::fixup_diff16:138 return ELF::R_AVR_DIFF16;139 case AVR::fixup_diff32:140 return ELF::R_AVR_DIFF32;141 case AVR::fixup_lds_sts_16:142 return ELF::R_AVR_LDS_STS_16;143 case AVR::fixup_port6:144 return ELF::R_AVR_PORT6;145 case AVR::fixup_port5:146 return ELF::R_AVR_PORT5;147 default:148 llvm_unreachable("invalid fixup kind!");149 }150}151 152std::unique_ptr<MCObjectTargetWriter> createAVRELFObjectWriter(uint8_t OSABI) {153 return std::make_unique<AVRELFObjectWriter>(OSABI);154}155 156} // end of namespace llvm157