1 //===-- MipsELFObjectWriter.cpp - Mips ELF Writer ---------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/MipsFixupKinds.h" 11 #include "MCTargetDesc/MipsMCTargetDesc.h" 12 #include "llvm/MC/MCELFObjectWriter.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCSection.h" 15 #include "llvm/MC/MCValue.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 using namespace llvm; 19 20 namespace { 21 class MipsELFObjectWriter : public MCELFObjectTargetWriter { 22 public: 23 MipsELFObjectWriter(uint8_t OSABI); 24 25 virtual ~MipsELFObjectWriter(); 26 27 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 28 bool IsPCRel, bool IsRelocWithSymbol, 29 int64_t Addend) const; 30 virtual unsigned getEFlags() const; 31 virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 32 const MCValue &Target, 33 const MCFragment &F, 34 const MCFixup &Fixup, 35 bool IsPCRel) const; 36 }; 37 } 38 39 MipsELFObjectWriter::MipsELFObjectWriter(uint8_t OSABI) 40 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MIPS, 41 /*HasRelocationAddend*/ false) {} 42 43 MipsELFObjectWriter::~MipsELFObjectWriter() {} 44 45 // FIXME: get the real EABI Version from the Triple. 46 unsigned MipsELFObjectWriter::getEFlags() const { 47 return ELF::EF_MIPS_NOREORDER | ELF::EF_MIPS_ARCH_32R2; 48 } 49 50 const MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 51 const MCValue &Target, 52 const MCFragment &F, 53 const MCFixup &Fixup, 54 bool IsPCRel) const { 55 assert(Target.getSymA() && "SymA cannot be 0."); 56 const MCSymbol &Sym = Target.getSymA()->getSymbol().AliasedSymbol(); 57 58 if (Sym.getSection().getKind().isMergeableCString() || 59 Sym.getSection().getKind().isMergeableConst()) 60 return &Sym; 61 62 return NULL; 63 } 64 65 unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, 66 const MCFixup &Fixup, 67 bool IsPCRel, 68 bool IsRelocWithSymbol, 69 int64_t Addend) const { 70 // determine the type of the relocation 71 unsigned Type = (unsigned)ELF::R_MIPS_NONE; 72 unsigned Kind = (unsigned)Fixup.getKind(); 73 74 switch (Kind) { 75 default: 76 llvm_unreachable("invalid fixup kind!"); 77 case FK_Data_4: 78 Type = ELF::R_MIPS_32; 79 break; 80 case FK_GPRel_4: 81 Type = ELF::R_MIPS_GPREL32; 82 break; 83 case Mips::fixup_Mips_GPREL16: 84 Type = ELF::R_MIPS_GPREL16; 85 break; 86 case Mips::fixup_Mips_26: 87 Type = ELF::R_MIPS_26; 88 break; 89 case Mips::fixup_Mips_CALL16: 90 Type = ELF::R_MIPS_CALL16; 91 break; 92 case Mips::fixup_Mips_GOT_Global: 93 case Mips::fixup_Mips_GOT_Local: 94 Type = ELF::R_MIPS_GOT16; 95 break; 96 case Mips::fixup_Mips_HI16: 97 Type = ELF::R_MIPS_HI16; 98 break; 99 case Mips::fixup_Mips_LO16: 100 Type = ELF::R_MIPS_LO16; 101 break; 102 case Mips::fixup_Mips_TLSGD: 103 Type = ELF::R_MIPS_TLS_GD; 104 break; 105 case Mips::fixup_Mips_GOTTPREL: 106 Type = ELF::R_MIPS_TLS_GOTTPREL; 107 break; 108 case Mips::fixup_Mips_TPREL_HI: 109 Type = ELF::R_MIPS_TLS_TPREL_HI16; 110 break; 111 case Mips::fixup_Mips_TPREL_LO: 112 Type = ELF::R_MIPS_TLS_TPREL_LO16; 113 break; 114 case Mips::fixup_Mips_TLSLDM: 115 Type = ELF::R_MIPS_TLS_LDM; 116 break; 117 case Mips::fixup_Mips_DTPREL_HI: 118 Type = ELF::R_MIPS_TLS_DTPREL_HI16; 119 break; 120 case Mips::fixup_Mips_DTPREL_LO: 121 Type = ELF::R_MIPS_TLS_DTPREL_LO16; 122 break; 123 case Mips::fixup_Mips_Branch_PCRel: 124 case Mips::fixup_Mips_PC16: 125 Type = ELF::R_MIPS_PC16; 126 break; 127 } 128 129 return Type; 130 } 131 132 MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, 133 bool IsLittleEndian, 134 uint8_t OSABI) { 135 MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(OSABI); 136 return createELFObjectWriter(MOTW, OS, IsLittleEndian); 137 } 138