1cedee4b38f4786845183be7f5916dd520a170ae0Shih-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#include <mcld/MC/MCLinker.h>
14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Host.h>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/raw_ostream.h>
17cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Resolver.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDContext.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSymbol.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSectionFactory.h>
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/SectionMap.h>
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h>
26cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h>
27cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h>
28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/EhFrame.h>
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/EhFrameHdr.h>
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h>
31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h>
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Constructor
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::MCLinker(TargetLDBackend& pBackend,
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                   MCLDInfo& pInfo,
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                   SectionMap& pSectionMap)
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao: m_Backend(pBackend),
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDInfo(pInfo),
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_SectionMap(pSectionMap),
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSymbolFactory(128),
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSectHdrFactory(10), // the average number of sections. (assuming 10.)
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_LDSectDataFactory(10),
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_pSectionMerger(NULL)
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Destructor
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoMCLinker::~MCLinker()
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL != m_pSectionMerger)
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    delete m_pSectionMerger;
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
57cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Symbol Operations
59cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromObject - add a symbol from object file and resolve it
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromObject(const llvm::StringRef& pName,
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Type pType,
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Desc pDesc,
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Binding pBinding,
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::SizeType pSize,
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        LDSymbol::ValueType pValue,
68cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                        FragmentRef* pFragmentRef,
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Visibility pVisibility)
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result resolved_result;
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info; // used for arrange output symbols
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // resolve them.
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    resolved_result.info     = m_LDInfo.getNamePool().createSymbol(pName,
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         false,
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pType,
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pDesc,
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pBinding,
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pSize,
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                         pVisibility);
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // into output symbol table. So, we let the existent false.
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.existent  = false;
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.overriden = true;
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_LDInfo.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        pSize, pVisibility,
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        &old_info, resolved_result);
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the return ResolveInfo should not NULL
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != resolved_result.info);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a LDSymbol for the input file.
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  new (input_sym) LDSymbol();
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set the relation between input LDSymbol and its ResolveInfo
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setResolveInfo(*resolved_result.info);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up input LDSymbol
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setValue(pValue);
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(NULL == output_sym);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // if it is a new symbol, create a LDSymbol for the output
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // set up the relation between output LDSymbol and its ResolveInfo
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*resolved_result.info);
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // symbol can be overriden only if it exists.
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(output_sym != NULL);
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // should override output LDSymbol
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // After symbol resolution, visibility is changed to the most restrict one.
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // we need to arrange its position in the output symbol .
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pType != ResolveInfo::Section) {
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!has_output_sym) {
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // We merge sections when reading them. So we do not need to output symbols
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // with section type
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // No matter the symbol is already in the output or not, add it if it
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // should be forcefully set local.
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (shouldForceLocal(*resolved_result.info))
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.forceLocal(*output_sym);
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      else {
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // the symbol should not be forcefully local.
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.add(*output_sym);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else if (resolved_result.overriden) {
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!shouldForceLocal(old_info) ||
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          !shouldForceLocal(*resolved_result.info)) {
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // If the old info and the new info are both forcefully local, then
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // we should keep the output_sym in forcefully local category. Else,
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        // we should re-sort the output_sym
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_OutputSymbols.arrange(*output_sym, old_info);
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return input_sym;
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addSymbolFromDynObj - add a symbol from object file and resolve it
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::addSymbolFromDynObj(const llvm::StringRef& pName,
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Type pType,
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Desc pDesc,
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Binding pBinding,
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::SizeType pSize,
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        LDSymbol::ValueType pValue,
175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                        FragmentRef* pFragmentRef,
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        ResolveInfo::Visibility pVisibility)
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // We merge sections when reading them. So we do not need symbols with
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // section type
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pType == ResolveInfo::Section)
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // visibility
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pBinding == ResolveInfo::Local ||
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pVisibility == ResolveInfo::Internal ||
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // A protected symbol in a shared library must be treated as a
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // normal symbol when viewed from outside the shared library.
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pVisibility = ResolveInfo::Default;
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // insert symbol and resolve it immediately
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result resolved_result;
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDInfo.getNamePool().insertSymbol(pName, true, pType, pDesc,
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            pBinding, pSize, pVisibility,
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                            NULL, resolved_result);
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the return ResolveInfo should not NULL
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != resolved_result.info);
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a LDSymbol for the input file.
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* input_sym = m_LDSymbolFactory.allocate();
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  new (input_sym) LDSymbol();
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up the relation between input LDSymbol and its ResolveInfo
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setResolveInfo(*resolved_result.info);
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // set up input LDSymbol
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  input_sym->setValue(pValue);
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = NULL;
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!resolved_result.existent) {
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // we get a new symbol, leave it as NULL
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // we saw the symbol before, but the output_sym still may be NULL.
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = resolved_result.info->outSymbol();
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (output_sym != NULL) {
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // After symbol resolution, visibility is changed to the most restrict one.
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // If we are not doing incremental linking, then any symbol with hidden
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // or internal visibility is forcefully set as a local symbol.
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (shouldForceLocal(*resolved_result.info)) {
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.forceLocal(*output_sym);
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return input_sym;
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolForcefully - define an output symbol and override it immediately
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolForcefully(const llvm::StringRef& pName,
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           bool pIsDyn,
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Type pType,
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Desc pDesc,
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Binding pBinding,
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::SizeType pSize,
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           LDSymbol::ValueType pValue,
246cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                           FragmentRef* pFragmentRef,
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Visibility pVisibility)
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = NULL;
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == info) {
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // the symbol is not in the pool, create a new one.
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a ResolveInfo
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Resolver::Result result;
255affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc,
256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        pBinding, pSize, pVisibility,
257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                        NULL, result);
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(!result.existent);
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a output LDSymbol
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*result.info);
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result.info->setSymPtr(output_sym);
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (shouldForceLocal(*result.info))
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.forceLocal(*output_sym);
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.add(*output_sym);
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // the symbol is already in the pool, override it
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ResolveInfo old_info;
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    old_info.override(*info);
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSource(pIsDyn);
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setType(pType);
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setDesc(pDesc);
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setBinding(pBinding);
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setVisibility(pVisibility);
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setIsSymbol(true);
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSize(pSize);
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = info->outSymbol();
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL != output_sym)
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.arrange(*output_sym, old_info);
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // create a output LDSymbol
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      output_sym = m_LDSymbolFactory.allocate();
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      new (output_sym) LDSymbol();
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      output_sym->setResolveInfo(*info);
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      info->setSymPtr(output_sym);
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_OutputSymbols.add(*output_sym);
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != output_sym) {
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
3035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineSymbolAsRefered - define an output symbol and override it immediately
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineSymbolAsRefered(const llvm::StringRef& pName,
3105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           bool pIsDyn,
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Type pType,
3125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Desc pDesc,
3135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Binding pBinding,
3145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::SizeType pSize,
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           LDSymbol::ValueType pValue,
316cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                           FragmentRef* pFragmentRef,
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                           ResolveInfo::Visibility pVisibility)
3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
319affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
321cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL == info || !(info->isUndef() || info->isDyn())) {
322cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // only undefined symbol and dynamic symbol can make a reference.
3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the symbol is already in the pool, override it
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info;
3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  old_info.override(*info);
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setSource(pIsDyn);
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setType(pType);
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setDesc(pDesc);
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setBinding(pBinding);
3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setVisibility(pVisibility);
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setIsSymbol(true);
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  info->setSize(pSize);
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = info->outSymbol();
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != output_sym) {
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.arrange(*output_sym, old_info);
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // create a output LDSymbol
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*info);
3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    info->setSymPtr(output_sym);
3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.add(*output_sym);
3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolForcefully - define an output symbol and resolve it
3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately
3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolForcefully(const llvm::StringRef& pName,
3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     bool pIsDyn,
3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Type pType,
3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Desc pDesc,
3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Binding pBinding,
3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::SizeType pSize,
3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     LDSymbol::ValueType pValue,
367cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                                     FragmentRef* pFragmentRef,
3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                     ResolveInfo::Visibility pVisibility)
3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Result is <info, existent, override>
3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Resolver::Result result;
3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ResolveInfo old_info;
373affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDInfo.getNamePool().insertSymbol(pName, pIsDyn, pType, pDesc, pBinding,
374affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      pSize, pVisibility,
375affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                      &old_info, result);
3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSymbol* output_sym = result.info->outSymbol();
3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!result.existent || !has_output_sym) {
3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym = m_LDSymbolFactory.allocate();
3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    new (output_sym) LDSymbol();
3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setResolveInfo(*result.info);
3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result.info->setSymPtr(output_sym);
3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (result.overriden || !has_output_sym) {
3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sym->setValue(pValue);
3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // After symbol resolution, the visibility is changed to the most restrict.
3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // arrange the output position
3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (shouldForceLocal(*result.info))
3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.forceLocal(*output_sym);
3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (has_output_sym)
3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.arrange(*output_sym, old_info);
3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_OutputSymbols.add(*output_sym);
4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return output_sym;
4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// defineAndResolveSymbolAsRefered - define an output symbol and resolve it
4055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// immediately.
4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSymbol* MCLinker::defineAndResolveSymbolAsRefered(const llvm::StringRef& pName,
4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    bool pIsDyn,
4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Type pType,
4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Desc pDesc,
4105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Binding pBinding,
4115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::SizeType pSize,
4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    LDSymbol::ValueType pValue,
413cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                                    FragmentRef* pFragmentRef,
4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                    ResolveInfo::Visibility pVisibility)
4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
416affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  ResolveInfo* info = m_LDInfo.getNamePool().findInfo(pName);
4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
418cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL == info || !(info->isUndef() || info->isDyn())) {
419cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    // only undefined symbol and dynamic symbol can make a reference.
4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return NULL;
4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return defineAndResolveSymbolForcefully(pName,
4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pIsDyn,
4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pType,
4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pDesc,
4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pBinding,
4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pSize,
4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pValue,
4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pFragmentRef,
4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          pVisibility);
4325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
4335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
434cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::finalizeSymbols()
435cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
436cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SymbolCategory::iterator symbol, symEnd = m_OutputSymbols.end();
437cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  for (symbol = m_OutputSymbols.begin(); symbol != symEnd; ++symbol) {
438cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
439cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if ((*symbol)->resolveInfo()->isAbsolute() ||
440cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        (*symbol)->resolveInfo()->type() == ResolveInfo::File) {
441cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // absolute symbols or symbols with function type should have
442cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // zero value
443cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*symbol)->setValue(0x0);
444cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      continue;
445cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
446cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
447cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    if ((*symbol)->hasFragRef()) {
448cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // set the virtual address of the symbol. If the output file is
449cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // relocatable object file, the section's virtual address becomes zero.
450cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      // And the symbol's value become section relative offset.
451cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      uint64_t value = getLayout().getOutputOffset(*(*symbol)->fragRef());
452cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      assert(NULL != (*symbol)->fragRef()->frag());
453cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      uint64_t addr  = getLayout().getOutputLDSection(*(*symbol)->fragRef()->frag())->addr();
454cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (*symbol)->setValue(value + addr);
455cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      continue;
456cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    }
457cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  }
458cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
459cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // finialize target-dependent symbols
460cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return m_Backend.finalizeSymbols(*this, m_LDInfo.output());
461cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
462cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
463cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::shouldForceLocal(const ResolveInfo& pInfo) const
464cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
465cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // forced local symbol matches all rules:
466cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // 1. We are not doing incremental linking.
467cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // 2. The symbol is with Hidden or Internal visibility.
468cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
469cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // 4. The symbol is defined or common
470cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (m_LDInfo.output().type() != Output::Object &&
471cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (pInfo.visibility() == ResolveInfo::Hidden ||
472cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao         pInfo.visibility() == ResolveInfo::Internal) &&
473cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (pInfo.isGlobal() || pInfo.isWeak()) &&
474cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao      (pInfo.isDefine() || pInfo.isCommon()))
475cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return true;
476cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return false;
477cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
478cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
479cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
480cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Section Operations
481cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// createSectHdr - create the input section header
4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::createSectHdr(const std::string& pName,
4845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   LDFileFormat::Kind pKind,
4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   uint32_t pType,
4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                   uint32_t pFlag)
4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
488affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(m_LDInfo.output().hasContext());
489affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
4905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // for user such as reader, standard/target fromat
4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* result =
4925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_LDSectHdrFactory.produce(pName, pKind, pType, pFlag);
4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check if we need to create a output section for output LDContext
4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string sect_name = m_SectionMap.getOutputSectName(pName);
496affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name);
4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == output_sect) {
4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a output section and push it into output LDContext
5005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect =
5015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
502affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_LDInfo.output().context()->getSectionTable().push_back(output_sect);
503affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pSectionMerger->addMapping(pName, output_sect);
5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *result;
5065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getOrCreateOutputSectHdr - for reader and standard/target format to get
5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// or create the output's section header
5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoLDSection& MCLinker::getOrCreateOutputSectHdr(const std::string& pName,
5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              LDFileFormat::Kind pKind,
5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pType,
5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pFlag,
5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                              uint32_t pAlign)
5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
516affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  assert(m_LDInfo.output().hasContext());
517affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // check if we need to create a output section for output LDContext
5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string sect_name = m_SectionMap.getOutputSectName(pName);
520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  LDSection* output_sect = m_LDInfo.output().context()->getSection(sect_name);
5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == output_sect) {
5235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // create a output section and push it into output LDContext
5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect =
5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      m_LDSectHdrFactory.produce(sect_name, pKind, pType, pFlag);
5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    output_sect->setAlign(pAlign);
527affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_LDInfo.output().context()->getSectionTable().push_back(output_sect);
528affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pSectionMerger->addMapping(pName, output_sect);
5295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *output_sect;
5315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
533cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao/// getOrCreateSectData - get or create SectionData
5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// pSection is input LDSection
535cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoSectionData& MCLinker::getOrCreateSectData(LDSection& pSection)
5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // if there is already a section data pointed by section, return it.
538cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData* sect_data = pSection.getSectionData();
5395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != sect_data) {
5405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Layout.addInputRange(*sect_data, pSection);
5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return *sect_data;
5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // try to get one from output LDSection
5455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* output_sect =
546affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_pSectionMerger->getOutputSectHdr(pSection.name());
5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(NULL != output_sect);
5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sect_data = output_sect->getSectionData();
5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL != sect_data) {
5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pSection.setSectionData(sect_data);
5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Layout.addInputRange(*sect_data, pSection);
5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return *sect_data;
5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
558cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  // if the output LDSection also has no SectionData, then create one.
5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  sect_data = m_LDSectDataFactory.allocate();
560cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  new (sect_data) SectionData(*output_sect);
5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pSection.setSectionData(sect_data);
5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  output_sect->setSectionData(sect_data);
5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_Layout.addInputRange(*sect_data, pSection);
5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *sect_data;
5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
567cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaovoid MCLinker::initSectionMap()
568cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
569cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  assert(m_LDInfo.output().hasContext());
570cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (NULL == m_pSectionMerger)
571cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    m_pSectionMerger = new SectionMerger(m_SectionMap, *m_LDInfo.output().context());
572cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
573cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
574cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liaobool MCLinker::layout()
575cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
576cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return m_Layout.layout(m_LDInfo.output(), m_Backend, m_LDInfo);
577cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
578cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
579cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
580cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Relocation Operations
581cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// addRelocation - add a relocation entry in MCLinker (only for object file)
5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// All symbols should be read and resolved before calling this function.
5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoRelocation* MCLinker::addRelocation(Relocation::Type pType,
5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    const LDSymbol& pSym,
5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    ResolveInfo& pResolveInfo,
588cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                    FragmentRef& pFragmentRef,
589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                    const LDSection& pSection,
5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                    Relocation::Address pAddend)
5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
592affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // FIXME: we should dicard sections and symbols first instead
593affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // if the symbol is in the discarded input section, then we also need to
594affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // discard this relocation.
595affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pSym.fragRef() == NULL &&
596affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pResolveInfo.type() == ResolveInfo::Section &&
597affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      pResolveInfo.desc() == ResolveInfo::Undefined)
598affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return NULL;
599affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Relocation* relocation = m_Backend.getRelocFactory()->produce(pType,
6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                                pFragmentRef,
6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                                pAddend);
6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  relocation->setSymInfo(&pResolveInfo);
6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_RelocationList.push_back(relocation);
6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
608affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_Backend.scanRelocation(*relocation, pSym, *this, m_LDInfo,
609affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                           m_LDInfo.output(), pSection);
6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
611affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (pResolveInfo.isUndef() && !pResolveInfo.isDyn() && !pResolveInfo.isWeak())
612affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::undefined_reference) << pResolveInfo.name();
6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return relocation;
6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool MCLinker::applyRelocations()
6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
621cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = (Fragment*)relocIter;
622affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    static_cast<Relocation*>(frag)->apply(*m_Backend.getRelocFactory(), m_LDInfo);
6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid MCLinker::syncRelocationResult()
6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
630affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  MemoryRegion* region = m_LDInfo.output().memArea()->request(0,
631affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                              m_LDInfo.output().memArea()->handler()->size());
6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* data = region->getBuffer();
6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  RelocationListType::iterator relocIter, relocEnd = m_RelocationList.end();
6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (relocIter = m_RelocationList.begin(); relocIter != relocEnd; ++relocIter) {
6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
638cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    Fragment* frag = (Fragment*)relocIter;
6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    Relocation* reloc = static_cast<Relocation*>(frag);
6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // get output file offset
6425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    size_t out_offset = m_Layout.getOutputLDSection(*reloc->targetRef().frag())->offset() +
6435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                        m_Layout.getOutputOffset(reloc->targetRef());
6445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    uint8_t* target_addr = data + out_offset;
6465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // byte swapping if target and host has different endian, and then write back
6475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(llvm::sys::isLittleEndianHost() != m_Backend.isLittleEndian()) {
6485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       uint64_t tmp_data = 0;
6495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao       switch(m_Backend.bitclass()) {
6515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         case 32u:
6525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           tmp_data = bswap32(reloc->target());
6535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           std::memcpy(target_addr, &tmp_data, 4);
6545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
6555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         case 64u:
6575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           tmp_data = bswap64(reloc->target());
6585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           std::memcpy(target_addr, &tmp_data, 8);
6595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
6605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao         default:
6625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao           break;
6635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
6645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      std::memcpy(target_addr, &reloc->target(), m_Backend.bitclass()/8);
6675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
6685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of for
6695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
670affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  m_LDInfo.output().memArea()->clear();
6715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
6725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
673cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
674cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Exception Handling Operations
675cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===//
676affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// addEhFrame - add an exception handling section
677affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @param pSection - the input section
678affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// @param pArea - the memory area which pSection is within.
67967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liaouint64_t MCLinker::addEhFrame(const Input& pInput,
68067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                              LDSection& pSection,
68167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                              MemoryArea& pArea)
682affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
683affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t size = 0;
684affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
685affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // get the SectionData of this eh_frame
686cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  SectionData& sect_data = getOrCreateSectData(pSection);
687affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
688affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // parse the eh_frame if the option --eh-frame-hdr is given
689affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (m_LDInfo.options().hasEhFrameHdr()) {
690affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    EhFrame* ehframe = m_Backend.getEhFrame();
691affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    assert(NULL != ehframe);
692affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    if (ehframe->canRecognizeAllEhFrame()) {
69367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      size = ehframe->readEhFrame(m_Layout, m_Backend, sect_data, pInput,
69467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                    pSection, pArea);
695affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // zero size indicate that this is an empty section or we can't recognize
696affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // this eh_frame, handle it as a regular section.
697affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      if (0 != size)
698affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        return size;
699affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
700affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
701affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
702affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // handle eh_frame as a regular section
70367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* region = pArea.request(pInput.fileOffset() + pSection.offset(),
704affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                       pSection.size());
705affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
706cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  Fragment* frag = NULL;
707affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == region) {
708affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // If the input section's size is zero, we got a NULL region.
709affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // use a virtual fill fragment
710cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag = new FillFragment(0x0, 0, 0);
711affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
712affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
713cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    frag = new RegionFragment(*region);
714affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
715affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  size = m_Layout.appendFragment(*frag, sect_data, pSection.align());
716affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return size;
717affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
718affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
719