C++程序  |  180行  |  6.38 KB

//===-- llvm/Target/TargetLDBackend.h - Target LD Backend -----*- C++ -*-===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_TARGETLDBACKEND_H
#define LLVM_TARGET_TARGETLDBACKEND_H

#include <llvm/Support/DataTypes.h>
#include <mcld/MC/MCLDOutput.h>
#include <mcld/LD/EhFrame.h>

namespace mcld {

class MCLinker;
class Relocation;
class RelocationFactory;
class Layout;
class ArchiveReader;
class ObjectReader;
class DynObjReader;
class ObjectWriter;
class DynObjWriter;
class ExecWriter;
class LDContext;
class SectionMap;
class Output;
class MCLDInfo;
class SymbolCategory;
class Input;
class LDFileFormat;
class GOT;
class MemoryAreaFactory;

//===----------------------------------------------------------------------===//
/// TargetLDBackend - Generic interface to target specific assembler backends.
///
class TargetLDBackend
{
  TargetLDBackend(const TargetLDBackend &);   // DO NOT IMPLEMENT
  void operator=(const TargetLDBackend &);  // DO NOT IMPLEMENT

protected:
  TargetLDBackend();

public:
  virtual ~TargetLDBackend();

  // -----  target dependent  ----- //
  virtual bool initTargetSectionMap(SectionMap& pSectionMap) { return true;}
  virtual void initTargetSegments(MCLinker& pLinker) { }
  virtual void initTargetSections(MCLinker& pLinker) { }
  virtual void initTargetSymbols(MCLinker& pLinker, const Output& pOutput) { }
  virtual void initTargetRelocation(MCLinker& pLinker) { }
  virtual bool initStandardSymbols(MCLinker& pLinker, const Output& pOutput) = 0;
  virtual bool initRelocFactory(const MCLinker& pLinker) = 0;

  virtual RelocationFactory* getRelocFactory() = 0;

  /// scanRelocation - When read in relocations, backend can do any modification
  /// to relocation and generate empty entries, such as GOT, dynamic relocation
  /// entries and other target dependent entries. These entries are generated
  /// for layout to adjust the ouput offset.
  /// @param pReloc - a read in relocation entry
  /// @param pInputSym - the input LDSymbol of relocation target symbol
  /// @param pOutput - the ouput file
  virtual void scanRelocation(Relocation& pReloc,
                              const LDSymbol& pInputSym,
                              MCLinker& pLinker,
                              const MCLDInfo& pLDInfo,
                              const Output& pOutput,
                              const LDSection& pSection) = 0;

  // -----  format dependent  ----- //
  virtual bool initArchiveReader(MCLinker&,
                                 MCLDInfo&,
                                 MemoryAreaFactory&) = 0;
  virtual bool initObjectReader(MCLinker&) = 0;
  virtual bool initDynObjReader(MCLinker&) = 0;
  virtual bool initObjectWriter(MCLinker&) = 0;
  virtual bool initDynObjWriter(MCLinker&) = 0;
  virtual bool initExecWriter(MCLinker&) = 0;

  virtual bool initExecSections(MCLinker&) = 0;
  virtual bool initDynObjSections(MCLinker&) = 0;

  virtual ArchiveReader *getArchiveReader() = 0;
  virtual ObjectReader *getObjectReader() = 0;
  virtual DynObjReader *getDynObjReader() = 0;
  virtual ObjectWriter *getObjectWriter() = 0;
  virtual DynObjWriter *getDynObjWriter() = 0;
  virtual ExecWriter *getExecWriter() = 0;

  virtual LDFileFormat* getDynObjFileFormat() = 0;
  virtual LDFileFormat* getExecFileFormat() = 0;

  /// preLayout - Backend can do any needed modification before layout
  virtual void preLayout(const Output& pOutput,
                         const MCLDInfo& pInfo,
                         MCLinker& pLinker) = 0;

  /// postLayout -Backend can do any needed modification after layout
  virtual void postLayout(const Output& pOutput,
                          const MCLDInfo& pInfo,
                          MCLinker& pLinker) = 0;

  /// postProcessing - Backend can do any needed modification in the final stage
  virtual void postProcessing(const Output& pOutput,
                              const MCLDInfo& pInfo,
                              MCLinker& pLinker) = 0;

  /// Is the target machine little endian? **/
  virtual bool isLittleEndian() const = 0;

  /// bit class. the bit length of the target machine, 32 or 64 **/
  virtual unsigned int bitclass() const = 0;

  /// the common page size of the target machine
  virtual uint64_t commonPageSize(const MCLDInfo& pInfo) const = 0;

  /// the abi page size of the target machine
  virtual uint64_t abiPageSize(const MCLDInfo& pInfo) const = 0;

  /// section start offset in the output file
  virtual size_t sectionStartOffset() const = 0;

  /// computeSectionOrder - compute the layout order of the given section
  virtual unsigned int getSectionOrder(const Output& pOutput,
                                       const LDSection& pSectHdr,
                                       const MCLDInfo& pInfo) const = 0;

  /// sizeNamePools - compute the size of regular name pools
  /// In ELF executable files, regular name pools are .symtab, .strtab.,
  /// .dynsym, .dynstr, and .hash
  virtual void
  sizeNamePools(const Output& pOutput,
                const SymbolCategory& pSymbols,
                const MCLDInfo& pLDInfo) = 0;

  /// finalizeSymbol - Linker checks pSymbol.reserved() if it's not zero,
  /// then it will ask backend to finalize the symbol value.
  /// @return ture - if backend set the symbol value sucessfully
  /// @return false - if backend do not recognize the symbol
  virtual bool finalizeSymbols(MCLinker& pLinker, const Output& pOutput) = 0;

  /// allocateCommonSymbols - allocate common symbols in the corresponding
  /// sections.
  virtual bool allocateCommonSymbols(const MCLDInfo& pLDInfo, MCLinker& pLinker) const = 0;

  /// readSection - read a target dependent section
  virtual bool readSection(Input& pInput,
                           MCLinker& pLinker,
                           LDSection& pInputSectHdr)
  { return true; }

  /// dyld - the name of the default dynamic linker
  virtual const char* dyld() const = 0;

  /// sizeInterp - compute the size of program interpreter's name
  /// In ELF executables, this is the length of dynamic linker's path name
  virtual void sizeInterp(const Output& pOutput, const MCLDInfo& pLDInfo) = 0;

public:
  EhFrame* getEhFrame();

  const EhFrame* getEhFrame() const;

private:
  /// m_pEhFrame - section .eh_frame
  EhFrame* m_pEhFrame;

};

} // End mcld namespace

#endif