1 //===- subzero/src/IceFixups.cpp - Implementation of Assembler Fixups -----===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Implements the AssemblerFixup class, a very basic target-independent 12 /// representation of a fixup or relocation. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "IceFixups.h" 17 18 #include "IceOperand.h" 19 20 namespace Ice { 21 22 const Constant *AssemblerFixup::NullSymbol = nullptr; 23 offset() const24RelocOffsetT AssemblerFixup::offset() const { 25 if (isNullSymbol()) 26 return addend_; 27 if (!ValueIsSymbol) { 28 if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) 29 return CR->getOffset() + addend_; 30 } 31 return addend_; 32 } 33 symbol() const34GlobalString AssemblerFixup::symbol() const { 35 assert(!isNullSymbol()); 36 assert(!ValueIsSymbol); 37 const Constant *C = ConstValue; 38 if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(C)) { 39 return CR->getName(); 40 } 41 // NOTE: currently only float/doubles are put into constant pools. In the 42 // future we may put integers as well. 43 assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C)); 44 return C->getLabelName(); 45 } 46 emit(GlobalContext * Ctx,const Assembler & Asm) const47size_t AssemblerFixup::emit(GlobalContext *Ctx, const Assembler &Asm) const { 48 static constexpr const size_t FixupSize = 4; 49 if (!BuildDefs::dump()) 50 return FixupSize; 51 Ostream &Str = Ctx->getStrEmit(); 52 Str << "\t.long "; 53 std::string Symbol; 54 if (isNullSymbol()) { 55 Str << "__Sz_AbsoluteZero"; 56 } else { 57 Symbol = symbol().toString(); 58 Str << Symbol; 59 assert(!ValueIsSymbol); 60 if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(ConstValue)) { 61 if (!Asm.fixupIsPCRel(kind()) && getFlags().getUseNonsfi() && 62 CR->getName().toString() != GlobalOffsetTable) { 63 Str << "@GOTOFF"; 64 } 65 } 66 } 67 68 assert(Asm.load<RelocOffsetT>(position()) == 0); 69 70 RelocOffsetT Offset = offset(); 71 if (Offset != 0) { 72 if (Offset > 0) { 73 Str << " + " << Offset; 74 } else { 75 assert(Offset != std::numeric_limits<RelocOffsetT>::lowest()); 76 Str << " - " << -Offset; 77 } 78 } 79 80 // We need to emit the '- .' for PCRel fixups. Even if the relocation kind() 81 // is not PCRel, we emit the '- .' for the _GLOBAL_OFFSET_TABLE_. 82 // TODO(jpp): create fixups wrt the GOT with the right fixup kind. 83 if (Asm.fixupIsPCRel(kind()) || Symbol == GlobalOffsetTable) 84 Str << " - ."; 85 Str << "\n"; 86 return FixupSize; 87 } 88 emitOffset(Assembler * Asm) const89void AssemblerFixup::emitOffset(Assembler *Asm) const { 90 Asm->store(position(), offset()); 91 } 92 emit(GlobalContext * Ctx,const Assembler &) const93size_t AssemblerTextFixup::emit(GlobalContext *Ctx, const Assembler &) const { 94 Ctx->getStrEmit() << Message << "\n"; 95 return NumBytes; 96 } 97 98 } // end of namespace Ice 99