1 //===-- SparcELFObjectWriter.cpp - Sparc 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/SparcMCTargetDesc.h" 11 #include "MCTargetDesc/SparcFixupKinds.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/MC/MCELFObjectWriter.h" 14 #include "llvm/MC/MCExpr.h" 15 #include "llvm/MC/MCValue.h" 16 #include "llvm/Support/ErrorHandling.h" 17 18 using namespace llvm; 19 20 namespace { 21 class SparcELFObjectWriter : public MCELFObjectTargetWriter { 22 public: 23 SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) 24 : MCELFObjectTargetWriter(Is64Bit, OSABI, 25 Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC, 26 /*HasRelocationAddend*/ true) {} 27 28 virtual ~SparcELFObjectWriter() {} 29 protected: 30 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 31 bool IsPCRel, bool IsRelocWithSymbol, 32 int64_t Addend) const; 33 34 }; 35 } 36 37 38 unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, 39 const MCFixup &Fixup, 40 bool IsPCRel, 41 bool IsRelocWithSymbol, 42 int64_t Addend) const { 43 if (IsPCRel) { 44 switch((unsigned)Fixup.getKind()) { 45 default: 46 llvm_unreachable("Unimplemented fixup -> relocation"); 47 case FK_Data_1: return ELF::R_SPARC_DISP8; 48 case FK_Data_2: return ELF::R_SPARC_DISP16; 49 case FK_Data_4: return ELF::R_SPARC_DISP32; 50 case FK_Data_8: return ELF::R_SPARC_DISP64; 51 case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30; 52 case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22; 53 case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19; 54 } 55 } 56 57 switch((unsigned)Fixup.getKind()) { 58 default: 59 llvm_unreachable("Unimplemented fixup -> relocation"); 60 case FK_Data_1: return ELF::R_SPARC_8; 61 case FK_Data_2: return ((Fixup.getOffset() % 2) 62 ? ELF::R_SPARC_UA16 63 : ELF::R_SPARC_16); 64 case FK_Data_4: return ((Fixup.getOffset() % 4) 65 ? ELF::R_SPARC_UA32 66 : ELF::R_SPARC_32); 67 case FK_Data_8: return ((Fixup.getOffset() % 8) 68 ? ELF::R_SPARC_UA64 69 : ELF::R_SPARC_64); 70 case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22; 71 case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10; 72 case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44; 73 case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44; 74 case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44; 75 case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22; 76 case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10; 77 } 78 return ELF::R_SPARC_NONE; 79 } 80 81 MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS, 82 bool Is64Bit, 83 uint8_t OSABI) { 84 MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI); 85 return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); 86 } 87