15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- MCLinker.cpp -----------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file implements the MCLinker class
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Resolver.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDContext.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSymbol.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSectionFactory.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/Host.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/raw_ostream.h>
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Constructor
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::MCLinker(TargetLDBackend& pBackend,
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   MCLDInfo& pInfo,
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   LDContext& pContext,
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   SectionMap& pSectionMap,
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   const Resolver& pResolver)
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao: m_Backend(pBackend),
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Info(pInfo),
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Output(pContext),
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_SectionMap(pSectionMap),
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSymbolFactory(128),
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.)
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSectDataFactory(10),
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_SectionMerger(pSectionMap, pContext),
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_StrSymPool(pResolver, 128)
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Info.setNamePool(m_StrSymPool);
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Destructor
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::~MCLinker()
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromObject - add a symbol from object file and resolve it
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName,
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Type pType,
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Desc pDesc,
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Binding pBinding,
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::SizeType pSize,
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        LDSymbol::ValueType pValue,
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        MCFragmentRef* pFragmentRef,
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Visibility pVisibility)
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result resolved_result;
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info; // used for arrange output symbols
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // resolve them.
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.info     = m_StrSymPool.createSymbol(pName,
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         false,
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pType,
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pDesc,
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pBinding,
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pSize,
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pVisibility);
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // into output symbol table. So, we let the existent false.
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.existent  = false;
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.overriden = true;
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_StrSymPool.insertSymbol(pName, false, pType, pDesc, pBinding, pSize,
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              pVisibility, &old_info, resolved_result);
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the return ResolveInfo should not NULL
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != resolved_result.info);
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a LDSymbol for the input file.
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  new (input_sym) LDSymbol();
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set the relation between input LDSymbol and its ResolveInfo
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setResolveInfo(*resolved_result.info);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up input LDSymbol
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setValue(pValue);
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL == output_sym);
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if it is a new symbol, create a LDSymbol for the output
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // set up the relation between output LDSymbol and its ResolveInfo
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*resolved_result.info);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbol can be overriden only if it exists.
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(output_sym != NULL);
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // should override output LDSymbol
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // After symbol resolution, visibility is changed to the most restrict one.
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // we need to arrange its position in the output symbol .
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pType != ResolveInfo::Section) {
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!has_output_sym) {
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We merge sections when reading them. So we do not need to output symbols
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // with section type
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // No matter the symbol is already in the output or not, add it if it
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // should be forcefully set local.
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (shouldForceLocal(*resolved_result.info))
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.forceLocal(*output_sym);
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // the symbol should not be forcefully local.
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.add(*output_sym);
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else if (resolved_result.overriden) {
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!shouldForceLocal(old_info) ||
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          !shouldForceLocal(*resolved_result.info)) {
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the old info and the new info are both forcefully local, then
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // we should keep the output_sym in forcefully local category. Else,
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // we should re-sort the output_sym
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.arrange(*output_sym, old_info);
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return input_sym;
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromDynObj - add a symbol from object file and resolve it
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName,
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Type pType,
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Desc pDesc,
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Binding pBinding,
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::SizeType pSize,
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        LDSymbol::ValueType pValue,
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        MCFragmentRef* pFragmentRef,
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Visibility pVisibility)
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // We merge sections when reading them. So we do not need symbols with
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // section type
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pType == ResolveInfo::Section)
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // visibility
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pBinding == ResolveInfo::Local ||
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pVisibility == ResolveInfo::Internal ||
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // A protected symbol in a shared library must be treated as a
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // normal symbol when viewed from outside the shared library.
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pVisibility = ResolveInfo::Default;
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // insert symbol and resolve it immediately
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result resolved_result;
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_StrSymPool.insertSymbol(pName, true, pType, pDesc, pBinding, pSize, pVisibility,
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            NULL, resolved_result);
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the return ResolveInfo should not NULL
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != resolved_result.info);
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a LDSymbol for the input file.
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  new (input_sym) LDSymbol();
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up the relation between input LDSymbol and its ResolveInfo
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setResolveInfo(*resolved_result.info);
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up input LDSymbol
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setValue(pValue);
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = NULL;
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!resolved_result.existent) {
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // we get a new symbol, leave it as NULL
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // we saw the symbol before, but the output_sym still may be NULL.
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = resolved_result.info->outSymbol();
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (output_sym != NULL) {
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // After symbol resolution, visibility is changed to the most restrict one.
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // If we are not doing incremental linking, then any symbol with hidden
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // or internal visibility is forcefully set as a local symbol.
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (shouldForceLocal(*resolved_result.info)) {
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.forceLocal(*output_sym);
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return input_sym;
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolForcefully - define an output symbol and override it immediately
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName,
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           bool pIsDyn,
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Type pType,
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Desc pDesc,
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Binding pBinding,
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::SizeType pSize,
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           LDSymbol::ValueType pValue,
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MCFragmentRef* pFragmentRef,
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Visibility pVisibility)
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* info = m_StrSymPool.findInfo(pName);
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = NULL;
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == info) {
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // the symbol is not in the pool, create a new one.
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a ResolveInfo
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Resolver::Result result;
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              NULL, result);
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(!result.existent);
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a output LDSymbol
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*result.info);
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result.info->setSymPtr(output_sym);
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (shouldForceLocal(*result.info))
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.forceLocal(*output_sym);
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.add(*output_sym);
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // the symbol is already in the pool, override it
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ResolveInfo old_info;
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    old_info.override(*info);
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSource(pIsDyn);
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setType(pType);
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setDesc(pDesc);
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setBinding(pBinding);
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setVisibility(pVisibility);
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setIsSymbol(true);
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSize(pSize);
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = info->outSymbol();
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL != output_sym)
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.arrange(*output_sym, old_info);
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create a output LDSymbol
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      output_sym = m_LDSymbolFactory.allocate();
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      new (output_sym) LDSymbol();
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      output_sym->setResolveInfo(*info);
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      info->setSymPtr(output_sym);
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.add(*output_sym);
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != output_sym) {
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolAsRefered - define an output symbol and override it immediately
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName,
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           bool pIsDyn,
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Type pType,
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Desc pDesc,
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Binding pBinding,
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::SizeType pSize,
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           LDSymbol::ValueType pValue,
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           MCFragmentRef* pFragmentRef,
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Visibility pVisibility)
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* info = m_StrSymPool.findInfo(pName);
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == info || !info->isUndef()) {
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // only undefined symbol can make a reference.
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the symbol is already in the pool, override it
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info;
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  old_info.override(*info);
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setSource(pIsDyn);
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setType(pType);
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setDesc(pDesc);
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setBinding(pBinding);
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setVisibility(pVisibility);
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setIsSymbol(true);
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setSize(pSize);
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = info->outSymbol();
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != output_sym) {
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.arrange(*output_sym, old_info);
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a output LDSymbol
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*info);
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSymPtr(output_sym);
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.add(*output_sym);
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolForcefully - define an output symbol and resolve it
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     bool pIsDyn,
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Type pType,
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Desc pDesc,
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Binding pBinding,
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::SizeType pSize,
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     LDSymbol::ValueType pValue,
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     MCFragmentRef* pFragmentRef,
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Visibility pVisibility)
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Result is <info, existent, override>
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result result;
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info;
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_StrSymPool.insertSymbol(pName, pIsDyn, pType, pDesc, pBinding, pSize, pVisibility,
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            &old_info, result);
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = result.info->outSymbol();
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!result.existent || !has_output_sym) {
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*result.info);
3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result.info->setSymPtr(output_sym);
3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (result.overriden || !has_output_sym) {
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // After symbol resolution, the visibility is changed to the most restrict.
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arrange the output position
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (shouldForceLocal(*result.info))
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.forceLocal(*output_sym);
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (has_output_sym)
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.arrange(*output_sym, old_info);
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.add(*output_sym);
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolAsRefered - define an output symbol and resolve it
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately.
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    bool pIsDyn,
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Type pType,
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Desc pDesc,
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Binding pBinding,
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::SizeType pSize,
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    LDSymbol::ValueType pValue,
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    MCFragmentRef* pFragmentRef,
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Visibility pVisibility)
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo* info = m_StrSymPool.findInfo(pName);
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == info || !info->isUndef()) {
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // only undefined symbol can make a reference
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return defineAndResolveSymbolForcefully(pName,
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pIsDyn,
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pType,
4165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pDesc,
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pBinding,
4185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pSize,
4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pValue,
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pFragmentRef,
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pVisibility);
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createSectHdr - create the input section header
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::createSectHdr(const std::string& pName,
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::Kind pKind,
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   uint32_t pType,
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   uint32_t pFlag)
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // for user such as reader, standard/target fromat
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* result =
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag);
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check if we need to create a output section for output LDContext
4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string sect_name = m_SectionMap.getOutputSectName(pName);
4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect = m_Output.getSection(sect_name);
4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == output_sect) {
4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a output section and push it into output LDContext
4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect =
4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Output.getSectionTable().push_back(output_sect);
4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionMerger.addMapping(pName, output_sect);
4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *result;
4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOrCreateOutputSectHdr - for reader and standard/target format to get
4495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// or create the output's section header
4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName,
4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              LDFileFormat::Kind pKind,
4525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pType,
4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pFlag,
4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pAlign)
4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check if we need to create a output section for output LDContext
4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string sect_name = m_SectionMap.getOutputSectName(pName);
4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect = m_Output.getSection(sect_name);
4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == output_sect) {
4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a output section and push it into output LDContext
4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect =
4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect->setAlign(pAlign);
4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Output.getSectionTable().push_back(output_sect);
4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionMerger.addMapping(pName, output_sect);
4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *output_sect;
4695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOrCreateSectData - get or create MCSectionData
4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// pSection is input LDSection
4735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaollvm::MCSectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
4755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if there is already a section data pointed by section, return it.
4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::MCSectionData* sect_data = pSection.getSectionData();
4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != sect_data) {
4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Layout.addInputRange(*sect_data, pSection);
4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return *sect_data;
4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // try to get one from output LDSection
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect =
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_SectionMerger.getOutputSectHdr(pSection.name());
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != output_sect);
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sect_data = output_sect->getSectionData();
4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != sect_data) {
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pSection.setSectionData(sect_data);
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Layout.addInputRange(*sect_data, pSection);
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return *sect_data;
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if the output LDSection also has no MCSectionData, then create one.
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sect_data = m_LDSectDataFactory.allocate();
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  new (sect_data) llvm::MCSectionData(*output_sect);
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pSection.setSectionData(sect_data);
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  output_sect->setSectionData(sect_data);
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Layout.addInputRange(*sect_data, pSection);
5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *sect_data;
5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addRelocation - add a relocation entry in MCLinker (only for object file)
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// All symbols should be read and resolved before calling this function.
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation* MCLinker::addRelocation(Relocation::Type pType,
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const LDSymbol& pSym,
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    ResolveInfo& pResolveInfo,
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    MCFragmentRef& pFragmentRef,
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    Relocation::Address pAddend)
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Relocation* relocation = m_Backend.getRelocFactory()->produce(pType,
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                                pFragmentRef,
5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                                pAddend);
5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  relocation->setSymInfo(&pResolveInfo);
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_RelocationList.push_back(relocation);
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Backend.scanRelocation(*relocation, pSym, *this, m_Info,
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                           m_Info.output());
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return relocation;
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::applyRelocations()
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_Info);
5355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MCLinker::syncRelocationResult()
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Info.output().memArea()->clean();
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryRegion* region = m_Info.output().memArea()->request(0,
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                              m_Info.output().memArea()->size());
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* data = region->getBuffer();
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::MCFragment* frag = (llvm::MCFragment*)relocIter;
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Relocation* reloc = static_cast<Relocation*>(frag);
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get output file offset
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() +
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        m_Layout.getOutputOffset(reloc->targetRef());
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint8_t* target_addr = data + out_offset;
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // byte swapping if target and host has different endian, and then write back
5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) {
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       uint64_t tmp_data = 0;
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       switch(m_Backend.bitclass()) {
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         case 32u:
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           tmp_data = bswap32(reloc->target());
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           std::memcpy(target_addr, &tmp_data, 4);
5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         case 64u:
5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           tmp_data = bswap64(reloc->target());
5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           std::memcpy(target_addr, &tmp_data, 8);
5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         default:
5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8);
5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of for
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Info.output().memArea()->sync();
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::layout()
5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_Layout.layout(m_Info.output(), m_Backend);
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::finalizeSymbols()
5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (0x0 != (*symbol)->resolveInfo()->reserved()) {
5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if the symbol is target reserved, target backend is responsible
5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // for finalizing the value.
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // if target backend does not know this symbol, it will return false
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // and we have to take over the symbol.
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (m_Backend.finalizeSymbol(**symbol))
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*symbol)->resolveInfo()->isAbsolute() ||
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // absolute symbols and symbols with function type should have
6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // zero value
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*symbol)->setValue(0x0);
6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*symbol)->hasFragRef()) {
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // set the virtual address of the symbol. If the output file is
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // relocatable object file, the section's virtual address becomes zero.
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // And the symbol's value become section relative offset.
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      assert(NULL != (*symbol)->fragRef()->frag());
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      uint64_t addr  = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (*symbol)->setValue(value + addr);
6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      continue;
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // forced local symbol matches all rules:
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // 1. We are not doing incremental linking.
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // 2. The symbol is with Hidden or Internal visibility.
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // 4. The symbol is defined or common
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (m_Info.output().type() != Output::Object &&
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (pInfo.visibility() == ResolveInfo::Hidden ||
6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         pInfo.visibility() == ResolveInfo::Internal) &&
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (pInfo.isGlobal() || pInfo.isWeak()) &&
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (pInfo.isDefine() || pInfo.isCommon()))
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return true;
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return false;
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645