MCObjectWriter.h revision 1f7210e808373fa92be3a2d4fa653a6f79d5088b
153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar//===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===// 253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// 353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// The LLVM Compiler Infrastructure 453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// 553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// This file is distributed under the University of Illinois Open Source 653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// License. See LICENSE.TXT for details. 753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar// 853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar//===----------------------------------------------------------------------===// 953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 1053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar#ifndef LLVM_MC_MCOBJECTWRITER_H 1153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar#define LLVM_MC_MCOBJECTWRITER_H 1253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 1353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar#include "llvm/Support/raw_ostream.h" 141f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper#include "llvm/Support/Compiler.h" 151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h" 1653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar#include <cassert> 1753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 1853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarnamespace llvm { 19207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbarclass MCAsmLayout; 2053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarclass MCAssembler; 21c90e30aa6f3792a460202017523171f435e2ba34Daniel Dunbarclass MCFixup; 22b751418a3992c9da6f48c988f549c8e4c65e26f1Daniel Dunbarclass MCFragment; 23fea753b397823c340608925eb7f3256a64a30017Rafael Espindolaclass MCSymbolData; 241f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbarclass MCSymbolRefExpr; 2553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarclass MCValue; 2653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 2753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// MCObjectWriter - Defines the object file and target independent interfaces 2853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// used by the assembler backend to write native file format object files. 2953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// 3053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// The object writer contains a few callbacks used by the assembler to allow 3153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// the object writer to modify the assembler data structures at appropriate 3253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// points. Once assembly is complete, the object writer is given the 3353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// MCAssembler instance, which contains all the symbol and section data which 3453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// should be emitted as part of WriteObject(). 3553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// 3653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// The object writer also contains a number of helper methods for writing 3753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar/// binary data to the output stream. 3853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarclass MCObjectWriter { 391f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION; 401f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION; 4153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 4253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarprotected: 4353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar raw_ostream &OS; 4453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 4553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar unsigned IsLittleEndian : 1; 4653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 4753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarprotected: // Can only create subclasses. 4853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian) 4953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar : OS(_OS), IsLittleEndian(_IsLittleEndian) {} 5053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 5153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbarpublic: 5253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar virtual ~MCObjectWriter(); 5353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 54a5370f11d9c27b2cb37fa61eb29eb56356582978Dan Gohman bool isLittleEndian() const { return IsLittleEndian; } 5553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 5653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar raw_ostream &getStream() { return OS; } 5753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 5853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @name High-Level API 5953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @{ 6053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 6153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// Perform any late binding of symbols (for example, to assign symbol indices 6253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// for use when generating relocations). 6353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// 6453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// This routine is called by the assembler after layout and relaxation is 6553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// complete. 6685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 6785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) = 0; 6853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 6953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// Record a relocation entry. 7053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// 7153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// This routine is called by the assembler after layout and relaxation, and 7253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// post layout binding. The implementation is responsible for storing 7353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// information about the relocation so that it can be emitted during 7453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// WriteObject(). 7553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar virtual void RecordRelocation(const MCAssembler &Asm, 76207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar const MCAsmLayout &Layout, 77b751418a3992c9da6f48c988f549c8e4c65e26f1Daniel Dunbar const MCFragment *Fragment, 78c90e30aa6f3792a460202017523171f435e2ba34Daniel Dunbar const MCFixup &Fixup, MCValue Target, 7953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar uint64_t &FixedValue) = 0; 8053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 811f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar /// \brief Check whether the difference (A - B) between two symbol 821f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar /// references is fully resolved. 831f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar /// 841f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar /// Clients are not required to answer precisely and may conservatively return 851f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar /// false, even when a difference is fully resolved. 86fea753b397823c340608925eb7f3256a64a30017Rafael Espindola bool 871f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, 881f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar const MCSymbolRefExpr *A, 893132780a2ed58945b0ec5033002be44bedb6b785Rafael Espindola const MCSymbolRefExpr *B, 903132780a2ed58945b0ec5033002be44bedb6b785Rafael Espindola bool InSet) const; 911f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar 92fea753b397823c340608925eb7f3256a64a30017Rafael Espindola virtual bool 93fea753b397823c340608925eb7f3256a64a30017Rafael Espindola IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 94fea753b397823c340608925eb7f3256a64a30017Rafael Espindola const MCSymbolData &DataA, 95fea753b397823c340608925eb7f3256a64a30017Rafael Espindola const MCFragment &FB, 96fea753b397823c340608925eb7f3256a64a30017Rafael Espindola bool InSet, 97908159b46ae118d36fccbc1d5145dcedfc3d4185Rafael Espindola bool IsPCRel) const; 98fea753b397823c340608925eb7f3256a64a30017Rafael Espindola 997070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 10053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// Write the object file. 10153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// 10253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// This routine is called by the assembler after layout and relaxation is 1033fa0c8ca96edbd2c77541c937b10149c6fb08cacNick Lewycky /// complete, fixups have been evaluated and applied, and relocations 10453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// generated. 1058f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola virtual void WriteObject(MCAssembler &Asm, 106207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar const MCAsmLayout &Layout) = 0; 10753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 10853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @} 10953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @name Binary Output 11053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @{ 11153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 11253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void Write8(uint8_t Value) { 11353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar OS << char(Value); 11453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 11553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 11653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteLE16(uint16_t Value) { 11773c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer Write8(uint8_t(Value >> 0)); 11873c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer Write8(uint8_t(Value >> 8)); 11953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 12053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 12153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteLE32(uint32_t Value) { 12273c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE16(uint16_t(Value >> 0)); 12373c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE16(uint16_t(Value >> 16)); 12453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 12553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 12653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteLE64(uint64_t Value) { 12773c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE32(uint32_t(Value >> 0)); 12873c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE32(uint32_t(Value >> 32)); 12953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 13053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 13153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteBE16(uint16_t Value) { 13273c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer Write8(uint8_t(Value >> 8)); 13373c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer Write8(uint8_t(Value >> 0)); 13453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 13553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 13653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteBE32(uint32_t Value) { 13773c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE16(uint16_t(Value >> 16)); 13873c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE16(uint16_t(Value >> 0)); 13953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 14053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 14153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteBE64(uint64_t Value) { 14273c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE32(uint32_t(Value >> 32)); 14373c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE32(uint32_t(Value >> 0)); 14453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 14553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 14653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void Write16(uint16_t Value) { 14773c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer if (IsLittleEndian) 14873c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE16(Value); 14973c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer else 15073c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE16(Value); 15153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 15253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 15353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void Write32(uint32_t Value) { 15473c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer if (IsLittleEndian) 15573c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE32(Value); 15673c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer else 15773c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE32(Value); 15853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 15953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 16053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void Write64(uint64_t Value) { 16173c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer if (IsLittleEndian) 16273c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteLE64(Value); 16373c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer else 16473c32f60c41f5078d5b460e3e7c23e40ab7e3e55Benjamin Kramer WriteBE64(Value); 16553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 16653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 16753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteZeros(unsigned N) { 16853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar const char Zeros[16] = { 0 }; 16953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 17053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar for (unsigned i = 0, e = N / 16; i != e; ++i) 17153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar OS << StringRef(Zeros, 16); 17253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 17353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar OS << StringRef(Zeros, N % 16); 17453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 17553b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 17653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 1770783fb7e6d2f03cbb398dc0f083c96ba8af9ab21Nathan Jeffords assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) && 1780783fb7e6d2f03cbb398dc0f083c96ba8af9ab21Nathan Jeffords "data size greater than fill size, unexpected large write will occur"); 17953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar OS << Str; 18053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar if (ZeroFillSize) 18153b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar WriteZeros(ZeroFillSize - Str.size()); 18253b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar } 18353b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 18453b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar /// @} 1853bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby 18653b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar}; 18753b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 18853b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar} // End llvm namespace 18953b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar 19053b2338a1d061ad15a858ff0d641431f4d4ac101Daniel Dunbar#endif 191