LCOV - code coverage report
Current view: top level - include/llvm/MC - MCObjectWriter.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 40 97.5 %
Date: 2017-09-14 15:23:50 Functions: 13 17 76.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/MC/MCObjectWriter.h - Object File Writer Interface --*- C++ -*-===//
       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             : #ifndef LLVM_MC_MCOBJECTWRITER_H
      11             : #define LLVM_MC_MCOBJECTWRITER_H
      12             : 
      13             : #include "llvm/ADT/SmallVector.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/Support/Endian.h"
      16             : #include "llvm/Support/EndianStream.h"
      17             : #include "llvm/Support/raw_ostream.h"
      18             : #include <cassert>
      19             : #include <cstdint>
      20             : 
      21             : namespace llvm {
      22             : 
      23             : class MCAsmLayout;
      24             : class MCAssembler;
      25             : class MCFixup;
      26             : class MCFragment;
      27             : class MCSymbol;
      28             : class MCSymbolRefExpr;
      29             : class MCValue;
      30             : 
      31             : /// Defines the object file and target independent interfaces used by the
      32             : /// assembler backend to write native file format object files.
      33             : ///
      34             : /// The object writer contains a few callbacks used by the assembler to allow
      35             : /// the object writer to modify the assembler data structures at appropriate
      36             : /// points. Once assembly is complete, the object writer is given the
      37             : /// MCAssembler instance, which contains all the symbol and section data which
      38             : /// should be emitted as part of writeObject().
      39             : ///
      40             : /// The object writer also contains a number of helper methods for writing
      41             : /// binary data to the output stream.
      42        4144 : class MCObjectWriter {
      43             :   raw_pwrite_stream *OS;
      44             : 
      45             : protected:
      46             :   unsigned IsLittleEndian : 1;
      47             : 
      48             :   // Can only create subclasses.
      49             :   MCObjectWriter(raw_pwrite_stream &OS, bool IsLittleEndian)
      50        4170 :       : OS(&OS), IsLittleEndian(IsLittleEndian) {}
      51             : 
      52             :   unsigned getInitialOffset() {
      53         552 :     return OS->tell();
      54             :   }
      55             : 
      56             : public:
      57             :   MCObjectWriter(const MCObjectWriter &) = delete;
      58             :   MCObjectWriter &operator=(const MCObjectWriter &) = delete;
      59             :   virtual ~MCObjectWriter();
      60             : 
      61             :   /// lifetime management
      62           0 :   virtual void reset() {}
      63             : 
      64        3290 :   bool isLittleEndian() const { return IsLittleEndian; }
      65             : 
      66             :   raw_pwrite_stream &getStream() { return *OS; }
      67        2434 :   void setStream(raw_pwrite_stream &NewOS) { OS = &NewOS; }
      68             : 
      69             :   /// \name High-Level API
      70             :   /// @{
      71             : 
      72             :   /// Perform any late binding of symbols (for example, to assign symbol
      73             :   /// indices for use when generating relocations).
      74             :   ///
      75             :   /// This routine is called by the assembler after layout and relaxation is
      76             :   /// complete.
      77             :   virtual void executePostLayoutBinding(MCAssembler &Asm,
      78             :                                         const MCAsmLayout &Layout) = 0;
      79             : 
      80             :   /// Record a relocation entry.
      81             :   ///
      82             :   /// This routine is called by the assembler after layout and relaxation, and
      83             :   /// post layout binding. The implementation is responsible for storing
      84             :   /// information about the relocation so that it can be emitted during
      85             :   /// writeObject().
      86             :   virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
      87             :                                 const MCFragment *Fragment,
      88             :                                 const MCFixup &Fixup, MCValue Target,
      89             :                                 uint64_t &FixedValue) = 0;
      90             : 
      91             :   /// Check whether the difference (A - B) between two symbol references is
      92             :   /// fully resolved.
      93             :   ///
      94             :   /// Clients are not required to answer precisely and may conservatively return
      95             :   /// false, even when a difference is fully resolved.
      96             :   bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
      97             :                                           const MCSymbolRefExpr *A,
      98             :                                           const MCSymbolRefExpr *B,
      99             :                                           bool InSet) const;
     100             : 
     101             :   virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
     102             :                                                       const MCSymbol &A,
     103             :                                                       const MCSymbol &B,
     104             :                                                       bool InSet) const;
     105             : 
     106             :   virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
     107             :                                                       const MCSymbol &SymA,
     108             :                                                       const MCFragment &FB,
     109             :                                                       bool InSet,
     110             :                                                       bool IsPCRel) const;
     111             : 
     112             :   /// Write the object file.
     113             :   ///
     114             :   /// This routine is called by the assembler after layout and relaxation is
     115             :   /// complete, fixups have been evaluated and applied, and relocations
     116             :   /// generated.
     117             :   virtual void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0;
     118             : 
     119             :   /// @}
     120             :   /// \name Binary Output
     121             :   /// @{
     122             : 
     123      593308 :   void write8(uint8_t Value) { *OS << char(Value); }
     124             : 
     125             :   void writeLE16(uint16_t Value) {
     126       82146 :     support::endian::Writer<support::little>(*OS).write(Value);
     127             :   }
     128             : 
     129             :   void writeLE32(uint32_t Value) {
     130     3683830 :     support::endian::Writer<support::little>(*OS).write(Value);
     131             :   }
     132             : 
     133             :   void writeLE64(uint64_t Value) {
     134     4452052 :     support::endian::Writer<support::little>(*OS).write(Value);
     135             :   }
     136             : 
     137             :   void writeBE16(uint16_t Value) {
     138        5854 :     support::endian::Writer<support::big>(*OS).write(Value);
     139             :   }
     140             : 
     141             :   void writeBE32(uint32_t Value) {
     142       54746 :     support::endian::Writer<support::big>(*OS).write(Value);
     143             :   }
     144             : 
     145             :   void writeBE64(uint64_t Value) {
     146       18064 :     support::endian::Writer<support::big>(*OS).write(Value);
     147             :   }
     148             : 
     149       27960 :   void write16(uint16_t Value) {
     150       27960 :     if (IsLittleEndian)
     151       25033 :       writeLE16(Value);
     152             :     else
     153        2927 :       writeBE16(Value);
     154       27960 :   }
     155             : 
     156     1849726 :   void write32(uint32_t Value) {
     157     1849726 :     if (IsLittleEndian)
     158     1822353 :       writeLE32(Value);
     159             :     else
     160       27373 :       writeBE32(Value);
     161     1849727 :   }
     162             : 
     163     2235053 :   void write64(uint64_t Value) {
     164     2235053 :     if (IsLittleEndian)
     165     2226026 :       writeLE64(Value);
     166             :     else
     167        9027 :       writeBE64(Value);
     168     2235050 :   }
     169             : 
     170      413328 :   void WriteZeros(unsigned N) {
     171      413328 :     const char Zeros[16] = {0};
     172             : 
     173      462839 :     for (unsigned i = 0, e = N / 16; i != e; ++i)
     174       99022 :       *OS << StringRef(Zeros, 16);
     175             : 
     176      826656 :     *OS << StringRef(Zeros, N % 16);
     177      413329 :   }
     178             : 
     179             :   void writeBytes(const SmallVectorImpl<char> &ByteVec,
     180             :                   unsigned ZeroFillSize = 0) {
     181     2490080 :     writeBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
     182             :   }
     183             : 
     184      622532 :   void writeBytes(StringRef Str, unsigned ZeroFillSize = 0) {
     185             :     // TODO: this version may need to go away once all fragment contents are
     186             :     // converted to SmallVector<char, N>
     187             :     assert(
     188             :         (ZeroFillSize == 0 || Str.size() <= ZeroFillSize) &&
     189             :         "data size greater than fill size, unexpected large write will occur");
     190    44620580 :     *OS << Str;
     191      622533 :     if (ZeroFillSize)
     192        6174 :       WriteZeros(ZeroFillSize - Str.size());
     193      622533 :   }
     194             : 
     195             :   /// @}
     196             : };
     197             : 
     198             : } // end namespace llvm
     199             : 
     200             : #endif // LLVM_MC_MCOBJECTWRITER_H

Generated by: LCOV version 1.13