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