C++程序  |  995行  |  36.62 KB

//===- ObjectLinker.cpp ---------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "mcld/Object/ObjectLinker.h"

#include "mcld/InputTree.h"
#include "mcld/IRBuilder.h"
#include "mcld/LinkerConfig.h"
#include "mcld/LinkerScript.h"
#include "mcld/Module.h"
#include "mcld/Fragment/Relocation.h"
#include "mcld/LD/Archive.h"
#include "mcld/LD/ArchiveReader.h"
#include "mcld/LD/BinaryReader.h"
#include "mcld/LD/BranchIslandFactory.h"
#include "mcld/LD/DebugString.h"
#include "mcld/LD/DynObjReader.h"
#include "mcld/LD/GarbageCollection.h"
#include "mcld/LD/GroupReader.h"
#include "mcld/LD/IdenticalCodeFolding.h"
#include "mcld/LD/LDContext.h"
#include "mcld/LD/LDSection.h"
#include "mcld/LD/ObjectReader.h"
#include "mcld/LD/ObjectWriter.h"
#include "mcld/LD/Relocator.h"
#include "mcld/LD/RelocData.h"
#include "mcld/LD/ResolveInfo.h"
#include "mcld/LD/SectionData.h"
#include "mcld/Object/ObjectBuilder.h"
#include "mcld/Script/Assignment.h"
#include "mcld/Script/Operand.h"
#include "mcld/Script/RpnEvaluator.h"
#include "mcld/Script/ScriptFile.h"
#include "mcld/Script/ScriptReader.h"
#include "mcld/Support/FileOutputBuffer.h"
#include "mcld/Support/MsgHandling.h"
#include "mcld/Support/RealPath.h"
#include "mcld/Target/TargetLDBackend.h"

#include <llvm/Support/Casting.h>
#include <llvm/Support/Host.h>

#include <system_error>

namespace mcld {

//===----------------------------------------------------------------------===//
// ObjectLinker
//===----------------------------------------------------------------------===//
ObjectLinker::ObjectLinker(const LinkerConfig& pConfig,
                           TargetLDBackend& pLDBackend)
    : m_Config(pConfig),
      m_pModule(NULL),
      m_pBuilder(NULL),
      m_LDBackend(pLDBackend),
      m_pObjectReader(NULL),
      m_pDynObjReader(NULL),
      m_pArchiveReader(NULL),
      m_pGroupReader(NULL),
      m_pBinaryReader(NULL),
      m_pScriptReader(NULL),
      m_pWriter(NULL) {
}

ObjectLinker::~ObjectLinker() {
  delete m_pObjectReader;
  delete m_pDynObjReader;
  delete m_pArchiveReader;
  delete m_pGroupReader;
  delete m_pBinaryReader;
  delete m_pScriptReader;
  delete m_pWriter;
}

bool ObjectLinker::initialize(Module& pModule, IRBuilder& pBuilder) {
  m_pModule = &pModule;
  m_pBuilder = &pBuilder;

  // initialize the readers and writers
  m_pObjectReader = m_LDBackend.createObjectReader(*m_pBuilder);
  m_pArchiveReader = m_LDBackend.createArchiveReader(*m_pModule);
  m_pDynObjReader = m_LDBackend.createDynObjReader(*m_pBuilder);
  m_pBinaryReader = m_LDBackend.createBinaryReader(*m_pBuilder);
  m_pGroupReader = new GroupReader(*m_pModule,
                                   *m_pObjectReader,
                                   *m_pDynObjReader,
                                   *m_pArchiveReader,
                                   *m_pBinaryReader);
  m_pScriptReader = new ScriptReader(
      *m_pObjectReader, *m_pArchiveReader, *m_pDynObjReader, *m_pGroupReader);
  m_pWriter = m_LDBackend.createWriter();

  // initialize Relocator
  m_LDBackend.initRelocator();

  return true;
}

/// initStdSections - initialize standard sections
bool ObjectLinker::initStdSections() {
  ObjectBuilder builder(*m_pModule);

  // initialize standard sections
  if (!m_LDBackend.initStdSections(builder))
    return false;

  // initialize target-dependent sections
  m_LDBackend.initTargetSections(*m_pModule, builder);

  return true;
}

void ObjectLinker::addUndefinedSymbols() {
  // Add the symbol set by -u as an undefind global symbol into symbol pool
  GeneralOptions::const_undef_sym_iterator usym;
  GeneralOptions::const_undef_sym_iterator usymEnd =
      m_Config.options().undef_sym_end();
  for (usym = m_Config.options().undef_sym_begin(); usym != usymEnd; ++usym) {
    Resolver::Result result;
    m_pModule->getNamePool().insertSymbol(*usym,  // name
                                          false,  // isDyn
                                          ResolveInfo::NoType,
                                          ResolveInfo::Undefined,
                                          ResolveInfo::Global,
                                          0x0,  // size
                                          0x0,  // value
                                          ResolveInfo::Default,
                                          NULL,
                                          result);

    LDSymbol* output_sym = result.info->outSymbol();
    // create the output symbol if it dose not have one
    if (!result.existent || (output_sym != NULL)) {
      output_sym = LDSymbol::Create(*result.info);
      result.info->setSymPtr(output_sym);
      output_sym->setFragmentRef(FragmentRef::Null());
    }
  }
}

void ObjectLinker::normalize() {
  // -----  set up inputs  ----- //
  Module::input_iterator input, inEnd = m_pModule->input_end();
  for (input = m_pModule->input_begin(); input != inEnd; ++input) {
    // is a group node
    if (isGroup(input)) {
      getGroupReader()->readGroup(
          input, inEnd, m_pBuilder->getInputBuilder(), m_Config);
      continue;
    }

    // already got type - for example, bitcode or external OIR (object
    // intermediate representation)
    if ((*input)->type() == Input::Script ||
        (*input)->type() == Input::Archive ||
        (*input)->type() == Input::External)
      continue;

    if (Input::Object == (*input)->type()) {
      m_pModule->getObjectList().push_back(*input);
      continue;
    }

    if (Input::DynObj == (*input)->type()) {
      m_pModule->getLibraryList().push_back(*input);
      continue;
    }

    bool doContinue = false;
    // read input as a binary file
    if (getBinaryReader()->isMyFormat(**input, doContinue)) {
      (*input)->setType(Input::Object);
      getBinaryReader()->readBinary(**input);
      m_pModule->getObjectList().push_back(*input);
    } else if (doContinue &&
               getObjectReader()->isMyFormat(**input, doContinue)) {
      // is a relocatable object file
      (*input)->setType(Input::Object);
      getObjectReader()->readHeader(**input);
      getObjectReader()->readSections(**input);
      getObjectReader()->readSymbols(**input);
      m_pModule->getObjectList().push_back(*input);
    } else if (doContinue &&
               getDynObjReader()->isMyFormat(**input, doContinue)) {
      // is a shared object file
      (*input)->setType(Input::DynObj);
      getDynObjReader()->readHeader(**input);
      getDynObjReader()->readSymbols(**input);
      m_pModule->getLibraryList().push_back(*input);
    } else if (doContinue &&
               getArchiveReader()->isMyFormat(**input, doContinue)) {
      // is an archive
      (*input)->setType(Input::Archive);
      if (m_Config.options().isInExcludeLIBS(**input)) {
        (*input)->setNoExport();
      }
      Archive archive(**input, m_pBuilder->getInputBuilder());
      getArchiveReader()->readArchive(m_Config, archive);
      if (archive.numOfObjectMember() > 0) {
        m_pModule->getInputTree().merge<InputTree::Inclusive>(input,
                                                              archive.inputs());
      }
    } else if (doContinue &&
               getScriptReader()->isMyFormat(**input, doContinue)) {
      // try to parse input as a linker script
      ScriptFile script(
          ScriptFile::LDScript, **input, m_pBuilder->getInputBuilder());
      if (getScriptReader()->readScript(m_Config, script)) {
        (*input)->setType(Input::Script);
        script.activate(*m_pModule);
        if (script.inputs().size() > 0) {
          m_pModule->getInputTree().merge<InputTree::Inclusive>(
              input, script.inputs());
        }
      }
    } else {
      if (m_Config.options().warnMismatch())
        warning(diag::warn_unrecognized_input_file)
            << (*input)->path() << m_Config.targets().triple().str();
    }
  }  // end of for
}

bool ObjectLinker::linkable() const {
  // check we have input and output files
  if (m_pModule->getInputTree().empty()) {
    error(diag::err_no_inputs);
    return false;
  }

  // can not mix -static with shared objects
  Module::const_lib_iterator lib, libEnd = m_pModule->lib_end();
  for (lib = m_pModule->lib_begin(); lib != libEnd; ++lib) {
    if ((*lib)->attribute()->isStatic()) {
      error(diag::err_mixed_shared_static_objects) << (*lib)->name()
                                                   << (*lib)->path();
      return false;
    }
  }

  // --nmagic and --omagic options lead to static executable program.
  // These options turn off page alignment of sections. Because the
  // sections are not aligned to pages, these sections can not contain any
  // exported functions. Also, because the two options disable linking
  // against shared libraries, the output absolutely does not call outside
  // functions.
  if (m_Config.options().nmagic() && !m_Config.isCodeStatic()) {
    error(diag::err_nmagic_not_static);
    return false;
  }
  if (m_Config.options().omagic() && !m_Config.isCodeStatic()) {
    error(diag::err_omagic_not_static);
    return false;
  }

  return true;
}

void ObjectLinker::dataStrippingOpt() {
  if (m_Config.codeGenType() == LinkerConfig::Object) {
    return;
  }

  // Garbege collection
  if (m_Config.options().GCSections()) {
    GarbageCollection GC(m_Config, m_LDBackend, *m_pModule);
    GC.run();
  }

  // Identical code folding
  if (m_Config.options().getICFMode() != GeneralOptions::ICF::None) {
    IdenticalCodeFolding icf(m_Config, m_LDBackend, *m_pModule);
    icf.foldIdenticalCode();
  }
  return;
}

/// readRelocations - read all relocation entries
///
/// All symbols should be read and resolved before this function.
bool ObjectLinker::readRelocations() {
  // Bitcode is read by the other path. This function reads relocation sections
  // in object files.
  mcld::InputTree::bfs_iterator input,
      inEnd = m_pModule->getInputTree().bfs_end();
  for (input = m_pModule->getInputTree().bfs_begin(); input != inEnd; ++input) {
    if ((*input)->type() == Input::Object && (*input)->hasMemArea()) {
      if (!getObjectReader()->readRelocations(**input))
        return false;
    }
    // ignore the other kinds of files.
  }
  return true;
}

/// mergeSections - put allinput sections into output sections
bool ObjectLinker::mergeSections() {
  // run the target-dependent hooks before merging sections
  m_LDBackend.preMergeSections(*m_pModule);

  // Set up input/output from ldscript requirement if any
  {
    RpnEvaluator evaluator(*m_pModule, m_LDBackend);
    SectionMap::iterator out, outBegin, outEnd;
    outBegin = m_pModule->getScript().sectionMap().begin();
    outEnd = m_pModule->getScript().sectionMap().end();
    for (out = outBegin; out != outEnd; ++out) {
      uint64_t out_align = 0x0, in_align = 0x0;
      LDSection* out_sect = (*out)->getSection();
      SectionMap::Output::iterator in, inBegin, inEnd;
      inBegin = (*out)->begin();
      inEnd = (*out)->end();

      // force input alignment from ldscript if any
      if ((*out)->prolog().hasSubAlign()) {
        evaluator.eval((*out)->prolog().subAlign(), in_align);
      }

      for (in = inBegin; in != inEnd; ++in) {
        LDSection* in_sect = (*in)->getSection();
        if ((*out)->prolog().hasSubAlign())
          in_sect->setAlign(in_align);
      }  // for each input section description

      // force output alignment from ldscript if any
      if ((*out)->prolog().hasAlign()) {
        evaluator.eval((*out)->prolog().align(), out_align);
        out_sect->setAlign(out_align);
      }
    }  // for each output section description
  }

  ObjectBuilder builder(*m_pModule);
  Module::obj_iterator obj, objEnd = m_pModule->obj_end();
  for (obj = m_pModule->obj_begin(); obj != objEnd; ++obj) {
    LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
    for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
      switch ((*sect)->kind()) {
        // Some *INPUT sections should not be merged.
        case LDFileFormat::Folded:
        case LDFileFormat::Ignore:
        case LDFileFormat::Null:
        case LDFileFormat::NamePool:
        case LDFileFormat::Group:
        case LDFileFormat::StackNote:
          // skip
          continue;
        case LDFileFormat::Relocation:
          if (!(*sect)->hasRelocData())
            continue;  // skip

          if ((*sect)->getLink()->kind() == LDFileFormat::Ignore ||
              (*sect)->getLink()->kind() == LDFileFormat::Folded)
            (*sect)->setKind(LDFileFormat::Ignore);
          break;
        case LDFileFormat::Target:
          if (!m_LDBackend.mergeSection(*m_pModule, **obj, **sect)) {
            error(diag::err_cannot_merge_section) << (*sect)->name()
                                                  << (*obj)->name();
            return false;
          }
          break;
        case LDFileFormat::EhFrame: {
          if (!(*sect)->hasEhFrame())
            continue;  // skip

          LDSection* out_sect = NULL;
          if ((out_sect = builder.MergeSection(**obj, **sect)) != NULL) {
            if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
              error(diag::err_cannot_merge_section) << (*sect)->name()
                                                    << (*obj)->name();
              return false;
            }
          }
          break;
        }
        case LDFileFormat::DebugString: {
          // FIXME: disable debug string merge when doing partial link.
          if (LinkerConfig::Object == m_Config.codeGenType())
            (*sect)->setKind(LDFileFormat::Debug);
        }
        // Fall through
        default: {
          if (!(*sect)->hasSectionData())
            continue;  // skip

          LDSection* out_sect = NULL;
          if ((out_sect = builder.MergeSection(**obj, **sect)) != NULL) {
            if (!m_LDBackend.updateSectionFlags(*out_sect, **sect)) {
              error(diag::err_cannot_merge_section) << (*sect)->name()
                                                    << (*obj)->name();
              return false;
            }
          }
          break;
        }
      }  // end of switch
    }    // for each section
  }      // for each obj

  {
    SectionMap::iterator out, outBegin, outEnd;
    outBegin = m_pModule->getScript().sectionMap().begin();
    outEnd = m_pModule->getScript().sectionMap().end();
    for (out = outBegin; out != outEnd; ++out) {
      LDSection* out_sect = (*out)->getSection();
      SectionMap::Output::iterator in, inBegin, inEnd;
      inBegin = (*out)->begin();
      inEnd = (*out)->end();

      for (in = inBegin; in != inEnd; ++in) {
        LDSection* in_sect = (*in)->getSection();
        if (builder.MoveSectionData(*in_sect->getSectionData(),
                                    *out_sect->getSectionData())) {
          builder.UpdateSectionAlign(*out_sect, *in_sect);
          m_LDBackend.updateSectionFlags(*out_sect, *in_sect);
        }
      }  // for each input section description

      if ((*out)->hasContent()) {
        LDSection* target = m_pModule->getSection((*out)->name());
        assert(target != NULL && target->hasSectionData());
        if (builder.MoveSectionData(*out_sect->getSectionData(),
                                    *target->getSectionData())) {
          builder.UpdateSectionAlign(*target, *out_sect);
          m_LDBackend.updateSectionFlags(*target, *out_sect);
        }
      }
    }  // for each output section description
  }

  // run the target-dependent hooks after merging sections
  m_LDBackend.postMergeSections(*m_pModule);

  return true;
}

void ObjectLinker::addSymbolToOutput(ResolveInfo& pInfo, Module& pModule) {
  // section symbols will be defined by linker later, we should not add section
  // symbols to output here
  if (ResolveInfo::Section == pInfo.type() || pInfo.outSymbol() == NULL)
    return;

  // if the symbols defined in the Ignore sections (e.g. discared by GC), then
  // not to put them to output
  // make sure that symbols defined in .debug_str won't add into output
  // symbol table. Since these symbols has fragRef to input fragments, which
  // will refer to input LDSection and has bad result when emitting their
  // section index. However, .debug_str actually does not need symobl in
  // shrad/executable objects, so it's fine to do so.
  if (pInfo.outSymbol()->hasFragRef() &&
      (LDFileFormat::Ignore ==
           pInfo.outSymbol()
               ->fragRef()
               ->frag()
               ->getParent()
               ->getSection()
               .kind() ||
       LDFileFormat::DebugString ==
           pInfo.outSymbol()
               ->fragRef()
               ->frag()
               ->getParent()
               ->getSection()
               .kind()))
    return;

  if (pInfo.shouldForceLocal(m_Config))
    pModule.getSymbolTable().forceLocal(*pInfo.outSymbol());
  else
    pModule.getSymbolTable().add(*pInfo.outSymbol());
}

void ObjectLinker::addSymbolsToOutput(Module& pModule) {
  // Traverse all the free ResolveInfo and add the output symobols to output
  NamePool::freeinfo_iterator free_it,
      free_end = pModule.getNamePool().freeinfo_end();
  for (free_it = pModule.getNamePool().freeinfo_begin(); free_it != free_end;
       ++free_it)
    addSymbolToOutput(**free_it, pModule);

  // Traverse all the resolveInfo and add the output symbol to output
  NamePool::syminfo_iterator info_it,
      info_end = pModule.getNamePool().syminfo_end();
  for (info_it = pModule.getNamePool().syminfo_begin(); info_it != info_end;
       ++info_it)
    addSymbolToOutput(*info_it.getEntry(), pModule);
}

/// addStandardSymbols - shared object and executable files need some
/// standard symbols
///   @return if there are some input symbols with the same name to the
///   standard symbols, return false
bool ObjectLinker::addStandardSymbols() {
  // create and add section symbols for each output section
  Module::iterator iter, iterEnd = m_pModule->end();
  for (iter = m_pModule->begin(); iter != iterEnd; ++iter) {
    m_pModule->getSectionSymbolSet().add(**iter, m_pModule->getNamePool());
  }

  return m_LDBackend.initStandardSymbols(*m_pBuilder, *m_pModule);
}

/// addTargetSymbols - some targets, such as MIPS and ARM, need some
/// target-dependent symbols
///   @return if there are some input symbols with the same name to the
///   target symbols, return false
bool ObjectLinker::addTargetSymbols() {
  m_LDBackend.initTargetSymbols(*m_pBuilder, *m_pModule);
  return true;
}

/// addScriptSymbols - define symbols from the command line option or linker
/// scripts.
bool ObjectLinker::addScriptSymbols() {
  LinkerScript& script = m_pModule->getScript();
  LinkerScript::Assignments::iterator it, ie = script.assignments().end();
  // go through the entire symbol assignments
  for (it = script.assignments().begin(); it != ie; ++it) {
    LDSymbol* symbol = NULL;
    assert((*it).second.symbol().type() == Operand::SYMBOL);
    const llvm::StringRef symName = (*it).second.symbol().name();
    ResolveInfo::Type type = ResolveInfo::NoType;
    ResolveInfo::Visibility vis = ResolveInfo::Default;
    size_t size = 0;
    ResolveInfo* old_info = m_pModule->getNamePool().findInfo(symName);
    // if the symbol does not exist, we can set type to NOTYPE
    // else we retain its type, same goes for size - 0 or retain old value
    // and visibility - Default or retain
    if (old_info != NULL) {
      type = static_cast<ResolveInfo::Type>(old_info->type());
      vis = old_info->visibility();
      size = old_info->size();
    }

    // Add symbol and refine the visibility if needed
    // FIXME: bfd linker would change the binding instead, but currently
    //        ABS is also a kind of Binding in ResolveInfo.
    switch ((*it).second.type()) {
      case Assignment::HIDDEN:
        vis = ResolveInfo::Hidden;
      // Fall through
      case Assignment::DEFAULT:
        symbol = m_pBuilder->AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
            symName,
            type,
            ResolveInfo::Define,
            ResolveInfo::Absolute,
            size,
            0x0,
            FragmentRef::Null(),
            vis);
        break;
      case Assignment::PROVIDE_HIDDEN:
        vis = ResolveInfo::Hidden;
      // Fall through
      case Assignment::PROVIDE:
        symbol =
            m_pBuilder->AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
                symName,
                type,
                ResolveInfo::Define,
                ResolveInfo::Absolute,
                size,
                0x0,
                FragmentRef::Null(),
                vis);
        break;
    }
    // Set symbol of this assignment.
    (*it).first = symbol;
  }
  return true;
}

bool ObjectLinker::scanRelocations() {
  // apply all relocations of all inputs
  Module::obj_iterator input, inEnd = m_pModule->obj_end();
  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
    m_LDBackend.getRelocator()->initializeScan(**input);
    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
      // bypass the reloc section if
      // 1. its section kind is changed to Ignore. (The target section is a
      // discarded group section.)
      // 2. it has no reloc data. (All symbols in the input relocs are in the
      // discarded group sections)
      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
        continue;
      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
        Relocation* relocation = llvm::cast<Relocation>(reloc);

        // bypass the reloc if the symbol is in the discarded input section
        ResolveInfo* info = relocation->symInfo();
        if (!info->outSymbol()->hasFragRef() &&
            ResolveInfo::Section == info->type() &&
            ResolveInfo::Undefined == info->desc())
          continue;

        // scan relocation
        if (LinkerConfig::Object != m_Config.codeGenType()) {
          m_LDBackend.getRelocator()->scanRelocation(
              *relocation, *m_pBuilder, *m_pModule, **rs, **input);
        } else {
          m_LDBackend.getRelocator()->partialScanRelocation(
              *relocation, *m_pModule);
        }
      }  // for all relocations
    }    // for all relocation section
    m_LDBackend.getRelocator()->finalizeScan(**input);
  }  // for all inputs
  return true;
}

/// initStubs - initialize stub-related stuff.
bool ObjectLinker::initStubs() {
  // initialize BranchIslandFactory
  m_LDBackend.initBRIslandFactory();

  // initialize StubFactory
  m_LDBackend.initStubFactory();

  // initialize target stubs
  m_LDBackend.initTargetStubs();
  return true;
}

/// allocateCommonSymobols - allocate fragments for common symbols to the
/// corresponding sections
bool ObjectLinker::allocateCommonSymbols() {
  if (LinkerConfig::Object != m_Config.codeGenType() ||
      m_Config.options().isDefineCommon())
    return m_LDBackend.allocateCommonSymbols(*m_pModule);
  return true;
}

/// prelayout - help backend to do some modification before layout
bool ObjectLinker::prelayout() {
  // finalize the section symbols, set their fragment reference and push them
  // into output symbol table
  Module::iterator sect, sEnd = m_pModule->end();
  for (sect = m_pModule->begin(); sect != sEnd; ++sect) {
    m_pModule->getSectionSymbolSet().finalize(
        **sect,
        m_pModule->getSymbolTable(),
        m_Config.codeGenType() == LinkerConfig::Object);
  }

  m_LDBackend.preLayout(*m_pModule, *m_pBuilder);

  /// check program interpreter - computer the name size of the runtime dyld
  if (!m_Config.isCodeStatic() &&
      (LinkerConfig::Exec == m_Config.codeGenType() ||
       m_Config.options().isPIE() || m_Config.options().hasDyld()))
    m_LDBackend.sizeInterp();

  /// measure NamePools - compute the size of name pool sections
  /// In ELF, will compute  the size of.symtab, .strtab, .dynsym, .dynstr,
  /// .hash and .shstrtab sections.
  ///
  /// dump all symbols and strings from ObjectLinker and build the
  /// format-dependent
  /// hash table.
  /// @note sizeNamePools replies on LinkerConfig::CodePosition. Must determine
  /// code position model before calling GNULDBackend::sizeNamePools()
  m_LDBackend.sizeNamePools(*m_pModule);

  // Do this after backend prelayout since it may add eh_frame entries.
  LDSection* eh_frame_sect = m_pModule->getSection(".eh_frame");
  if (eh_frame_sect && eh_frame_sect->hasEhFrame())
    eh_frame_sect->getEhFrame()->computeOffsetSize();
  m_LDBackend.createAndSizeEhFrameHdr(*m_pModule);

  // size debug string table and set up the debug string offset
  // we set the .debug_str size here so that there won't be a section symbol for
  // .debug_str. While actually it doesn't matter that .debug_str has section
  // symbol or not.
  // FIXME: disable debug string merge when doing partial link.
  if (LinkerConfig::Object != m_Config.codeGenType()) {
    LDSection* debug_str_sect = m_pModule->getSection(".debug_str");
    if (debug_str_sect && debug_str_sect->hasDebugString())
      debug_str_sect->getDebugString()->computeOffsetSize();
  }
  return true;
}

/// layout - linearly layout all output sections and reserve some space
/// for GOT/PLT
///   Because we do not support instruction relaxing in this early version,
///   if there is a branch can not jump to its target, we return false
///   directly
bool ObjectLinker::layout() {
  m_LDBackend.layout(*m_pModule);
  return true;
}

/// prelayout - help backend to do some modification after layout
bool ObjectLinker::postlayout() {
  m_LDBackend.postLayout(*m_pModule, *m_pBuilder);
  return true;
}

/// finalizeSymbolValue - finalize the resolved symbol value.
///   Before relocate(), after layout(), ObjectLinker should correct value of
///   all
///   symbol.
bool ObjectLinker::finalizeSymbolValue() {
  Module::sym_iterator symbol, symEnd = m_pModule->sym_end();
  for (symbol = m_pModule->sym_begin(); symbol != symEnd; ++symbol) {
    if ((*symbol)->resolveInfo()->isAbsolute() ||
        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
      // absolute symbols should just use its value directly (i.e., the result
      // of symbol resolution)
      continue;
    }

    if ((*symbol)->resolveInfo()->type() == ResolveInfo::ThreadLocal) {
      m_LDBackend.finalizeTLSSymbol(**symbol);
      continue;
    }

    if ((*symbol)->hasFragRef()) {
      // set the virtual address of the symbol. If the output file is
      // relocatable object file, the section's virtual address becomes zero.
      // And the symbol's value become section relative offset.
      uint64_t value = (*symbol)->fragRef()->getOutputOffset();
      assert((*symbol)->fragRef()->frag() != NULL);
      uint64_t addr =
          (*symbol)->fragRef()->frag()->getParent()->getSection().addr();
      (*symbol)->setValue(value + addr);
      continue;
    }
  }

  RpnEvaluator evaluator(*m_pModule, m_LDBackend);
  bool finalized = m_LDBackend.finalizeSymbols();
  bool scriptSymsFinalized = true;
  LinkerScript& script = m_pModule->getScript();
  LinkerScript::Assignments::iterator assign, assignEnd;
  assignEnd = script.assignments().end();
  for (assign = script.assignments().begin(); assign != assignEnd; ++assign) {
    LDSymbol* symbol = (*assign).first;
    Assignment& assignment = (*assign).second;

    if (symbol == NULL)
      continue;

    scriptSymsFinalized &= assignment.assign(evaluator);
    if (!scriptSymsFinalized)
      break;

    symbol->setValue(assignment.symbol().value());
  }  // for each script symbol assignment

  bool assertionsPassed = true;
  LinkerScript::Assertions::iterator assert, assertEnd;
  assertEnd = script.assertions().end();
  for (assert = script.assertions().begin(); assert != assertEnd; ++assert) {
    uint64_t res = 0x0;
    evaluator.eval((*assert).getRpnExpr(), res);
    if (res == 0x0)
      fatal(diag::err_assert_failed) << (*assert).message();
  }  // for each assertion in ldscript

  return finalized && scriptSymsFinalized && assertionsPassed;
}

/// relocate - applying relocation entries and create relocation
/// section in the output files
/// Create relocation section, asking TargetLDBackend to
/// read the relocation information into RelocationEntry
/// and push_back into the relocation section
bool ObjectLinker::relocation() {
  // when producing relocatables, no need to apply relocation
  if (LinkerConfig::Object == m_Config.codeGenType())
    return true;

  LDSection* debug_str_sect = m_pModule->getSection(".debug_str");

  // apply all relocations of all inputs
  Module::obj_iterator input, inEnd = m_pModule->obj_end();
  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
    m_LDBackend.getRelocator()->initializeApply(**input);
    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
      // bypass the reloc section if
      // 1. its section kind is changed to Ignore. (The target section is a
      // discarded group section.)
      // 2. it has no reloc data. (All symbols in the input relocs are in the
      // discarded group sections)
      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
        continue;
      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
        Relocation* relocation = llvm::cast<Relocation>(reloc);

        // bypass the reloc if the symbol is in the discarded input section
        ResolveInfo* info = relocation->symInfo();
        if (!info->outSymbol()->hasFragRef() &&
            ResolveInfo::Section == info->type() &&
            ResolveInfo::Undefined == info->desc())
          continue;

        // apply the relocation aginst symbol on DebugString
        if (info->outSymbol()->hasFragRef() &&
            info->outSymbol()->fragRef()->frag()->getKind()
                == Fragment::Region &&
            info->outSymbol()->fragRef()->frag()->getParent()->getSection()
                .kind() == LDFileFormat::DebugString) {
          assert(debug_str_sect != NULL);
          assert(debug_str_sect->hasDebugString());
          debug_str_sect->getDebugString()->applyOffset(*relocation,
                                                        m_LDBackend);
          continue;
        }

        relocation->apply(*m_LDBackend.getRelocator());
      }  // for all relocations
    }    // for all relocation section
    m_LDBackend.getRelocator()->finalizeApply(**input);
  }  // for all inputs

  // apply relocations created by relaxation
  BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory();
  BranchIslandFactory::iterator facIter, facEnd = br_factory->end();
  for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) {
    BranchIsland& island = *facIter;
    BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end();
    for (iter = island.reloc_begin(); iter != iterEnd; ++iter)
      (*iter)->apply(*m_LDBackend.getRelocator());
  }

  // apply relocations created by LD backend
  for (TargetLDBackend::extra_reloc_iterator
       iter = m_LDBackend.extra_reloc_begin(),
       end = m_LDBackend.extra_reloc_end(); iter != end; ++iter) {
    iter->apply(*m_LDBackend.getRelocator());
  }

  return true;
}

/// emitOutput - emit the output file.
bool ObjectLinker::emitOutput(FileOutputBuffer& pOutput) {
  return std::error_code() == getWriter()->writeObject(*m_pModule, pOutput);
}

/// postProcessing - do modification after all processes
bool ObjectLinker::postProcessing(FileOutputBuffer& pOutput) {
  if (LinkerConfig::Object != m_Config.codeGenType())
    normalSyncRelocationResult(pOutput);
  else
    partialSyncRelocationResult(pOutput);

  // emit .eh_frame_hdr
  // eh_frame_hdr should be emitted after syncRelocation, because eh_frame_hdr
  // needs FDE PC value, which will be corrected at syncRelocation
  m_LDBackend.postProcessing(pOutput);
  return true;
}

void ObjectLinker::normalSyncRelocationResult(FileOutputBuffer& pOutput) {
  uint8_t* data = pOutput.getBufferStart();

  // sync all relocations of all inputs
  Module::obj_iterator input, inEnd = m_pModule->obj_end();
  for (input = m_pModule->obj_begin(); input != inEnd; ++input) {
    LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
    for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
      // bypass the reloc section if
      // 1. its section kind is changed to Ignore. (The target section is a
      // discarded group section.)
      // 2. it has no reloc data. (All symbols in the input relocs are in the
      // discarded group sections)
      if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
        continue;
      RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
      for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
        Relocation* relocation = llvm::cast<Relocation>(reloc);

        // bypass the reloc if the symbol is in the discarded input section
        ResolveInfo* info = relocation->symInfo();
        if (!info->outSymbol()->hasFragRef() &&
            ResolveInfo::Section == info->type() &&
            ResolveInfo::Undefined == info->desc())
          continue;

        // bypass the relocation with NONE type. This is to avoid overwrite the
        // target result by NONE type relocation if there is a place which has
        // two relocations to apply to, and one of it is NONE type. The result
        // we want is the value of the other relocation result. For example,
        // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to
        // the same place
        if (relocation->type() == 0x0)
          continue;
        writeRelocationResult(*relocation, data);
      }  // for all relocations
    }    // for all relocation section
  }      // for all inputs

  // sync relocations created by relaxation
  BranchIslandFactory* br_factory = m_LDBackend.getBRIslandFactory();
  BranchIslandFactory::iterator facIter, facEnd = br_factory->end();
  for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) {
    BranchIsland& island = *facIter;
    BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end();
    for (iter = island.reloc_begin(); iter != iterEnd; ++iter) {
      Relocation* reloc = *iter;
      writeRelocationResult(*reloc, data);
    }
  }

  // sync relocations created by LD backend
  for (TargetLDBackend::extra_reloc_iterator
       iter = m_LDBackend.extra_reloc_begin(),
       end = m_LDBackend.extra_reloc_end(); iter != end; ++iter) {
    writeRelocationResult(*iter, data);
  }
}

void ObjectLinker::partialSyncRelocationResult(FileOutputBuffer& pOutput) {
  uint8_t* data = pOutput.getBufferStart();

  // traverse outputs' LDSection to get RelocData
  Module::iterator sectIter, sectEnd = m_pModule->end();
  for (sectIter = m_pModule->begin(); sectIter != sectEnd; ++sectIter) {
    if (LDFileFormat::Relocation != (*sectIter)->kind())
      continue;

    RelocData* reloc_data = (*sectIter)->getRelocData();
    RelocData::iterator relocIter, relocEnd = reloc_data->end();
    for (relocIter = reloc_data->begin(); relocIter != relocEnd; ++relocIter) {
      Relocation* reloc = llvm::cast<Relocation>(relocIter);

      // bypass the relocation with NONE type. This is to avoid overwrite the
      // target result by NONE type relocation if there is a place which has
      // two relocations to apply to, and one of it is NONE type. The result
      // we want is the value of the other relocation result. For example,
      // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to
      // the same place
      if (reloc->type() == 0x0)
        continue;
      writeRelocationResult(*reloc, data);
    }
  }
}

void ObjectLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput) {
  // get output file offset
  size_t out_offset =
      pReloc.targetRef().frag()->getParent()->getSection().offset() +
      pReloc.targetRef().getOutputOffset();

  uint8_t* target_addr = pOutput + out_offset;
  // byte swapping if target and host has different endian, and then write back
  if (llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) {
    uint64_t tmp_data = 0;

    switch (pReloc.size(*m_LDBackend.getRelocator())) {
      case 8u:
        std::memcpy(target_addr, &pReloc.target(), 1);
        break;

      case 16u:
        tmp_data = mcld::bswap16(pReloc.target());
        std::memcpy(target_addr, &tmp_data, 2);
        break;

      case 32u:
        tmp_data = mcld::bswap32(pReloc.target());
        std::memcpy(target_addr, &tmp_data, 4);
        break;

      case 64u:
        tmp_data = mcld::bswap64(pReloc.target());
        std::memcpy(target_addr, &tmp_data, 8);
        break;

      default:
        break;
    }
  } else {
    std::memcpy(target_addr, &pReloc.target(),
                (pReloc.size(*m_LDBackend.getRelocator()) + 7) / 8);
  }
}

}  // namespace mcld