SparcELFObjectWriter.cpp revision 262261
1169691Skan//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===// 2169691Skan// 3169691Skan// The LLVM Compiler Infrastructure 4169691Skan// 5169691Skan// This file is distributed under the University of Illinois Open Source 6169691Skan// License. See LICENSE.TXT for details. 7169691Skan// 8169691Skan//===----------------------------------------------------------------------===// 9169691Skan 10169691Skan#include "MCTargetDesc/SparcFixupKinds.h" 11169691Skan#include "MCTargetDesc/SparcMCExpr.h" 12169691Skan#include "MCTargetDesc/SparcMCTargetDesc.h" 13169691Skan#include "llvm/ADT/STLExtras.h" 14169691Skan#include "llvm/MC/MCELFObjectWriter.h" 15169691Skan#include "llvm/MC/MCExpr.h" 16169691Skan#include "llvm/MC/MCValue.h" 17169691Skan#include "llvm/Support/ErrorHandling.h" 18169691Skan 19169691Skanusing namespace llvm; 20169691Skan 21169691Skannamespace { 22169691Skan class SparcELFObjectWriter : public MCELFObjectTargetWriter { 23169691Skan public: 24169691Skan SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI) 25169691Skan : MCELFObjectTargetWriter(Is64Bit, OSABI, 26169691Skan Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC, 27169691Skan /*HasRelocationAddend*/ true) {} 28169691Skan 29169691Skan virtual ~SparcELFObjectWriter() {} 30169691Skan protected: 31169691Skan virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 32169691Skan bool IsPCRel, bool IsRelocWithSymbol, 33169691Skan int64_t Addend) const; 34169691Skan 35169691Skan virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 36169691Skan const MCValue &Target, 37169691Skan const MCFragment &F, 38169691Skan const MCFixup &Fixup, 39169691Skan bool IsPCRel) const; 40169691Skan }; 41169691Skan} 42169691Skan 43169691Skan 44169691Skanunsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target, 45169691Skan const MCFixup &Fixup, 46169691Skan bool IsPCRel, 47169691Skan bool IsRelocWithSymbol, 48169691Skan int64_t Addend) const { 49169691Skan 50169691Skan if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) { 51169691Skan if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32) 52169691Skan return ELF::R_SPARC_DISP32; 53169691Skan } 54169691Skan 55169691Skan if (IsPCRel) { 56169691Skan switch((unsigned)Fixup.getKind()) { 57169691Skan default: 58169691Skan llvm_unreachable("Unimplemented fixup -> relocation"); 59169691Skan case FK_Data_1: return ELF::R_SPARC_DISP8; 60169691Skan case FK_Data_2: return ELF::R_SPARC_DISP16; 61169691Skan case FK_Data_4: return ELF::R_SPARC_DISP32; 62169691Skan case FK_Data_8: return ELF::R_SPARC_DISP64; 63169691Skan case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30; 64169691Skan case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22; 65169691Skan case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19; 66169691Skan case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22; 67169691Skan case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10; 68169691Skan case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30; 69169691Skan } 70169691Skan } 71169691Skan 72169691Skan switch((unsigned)Fixup.getKind()) { 73169691Skan default: 74169691Skan llvm_unreachable("Unimplemented fixup -> relocation"); 75169691Skan case FK_Data_1: return ELF::R_SPARC_8; 76169691Skan case FK_Data_2: return ((Fixup.getOffset() % 2) 77169691Skan ? ELF::R_SPARC_UA16 78169691Skan : ELF::R_SPARC_16); 79169691Skan case FK_Data_4: return ((Fixup.getOffset() % 4) 80169691Skan ? ELF::R_SPARC_UA32 81169691Skan : ELF::R_SPARC_32); 82169691Skan case FK_Data_8: return ((Fixup.getOffset() % 8) 83169691Skan ? ELF::R_SPARC_UA64 84169691Skan : ELF::R_SPARC_64); 85169691Skan case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22; 86169691Skan case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10; 87169691Skan case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44; 88169691Skan case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44; 89169691Skan case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44; 90169691Skan case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22; 91169691Skan case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10; 92169691Skan case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22; 93169691Skan case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10; 94169691Skan case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22; 95169691Skan case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10; 96169691Skan case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD; 97169691Skan case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL; 98169691Skan case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22; 99169691Skan case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10; 100169691Skan case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD; 101169691Skan case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL; 102169691Skan case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22; 103169691Skan case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10; 104169691Skan case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD; 105169691Skan case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22; 106169691Skan case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10; 107169691Skan case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD; 108169691Skan case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX; 109169691Skan case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD; 110169691Skan case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22; 111169691Skan case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10; 112169691Skan } 113169691Skan 114169691Skan return ELF::R_SPARC_NONE; 115169691Skan} 116169691Skan 117169691Skanconst MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 118169691Skan const MCValue &Target, 119169691Skan const MCFragment &F, 120169691Skan const MCFixup &Fixup, 121169691Skan bool IsPCRel) const { 122169691Skan 123169691Skan if (!Target.getSymA()) 124169691Skan return NULL; 125169691Skan switch((unsigned)Fixup.getKind()) { 126169691Skan default: break; 127169691Skan case Sparc::fixup_sparc_got22: 128169691Skan case Sparc::fixup_sparc_got10: 129169691Skan return &Target.getSymA()->getSymbol().AliasedSymbol(); 130169691Skan } 131169691Skan return NULL; 132169691Skan} 133169691Skan 134169691SkanMCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS, 135169691Skan bool Is64Bit, 136169691Skan uint8_t OSABI) { 137169691Skan MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI); 138169691Skan return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/false); 139169691Skan} 140169691Skan