122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- IRBuilder.cpp ------------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFReader.h>
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/SectionData.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h>
16f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/ELF.h>
17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/FragmentRef.h>
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Helper Functions
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesLDFileFormat::Kind GetELFSectionKind(uint32_t pType, const char* pName,
25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                     uint32_t pFlag)
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pFlag & mcld::ELF::SHF_EXCLUDE)
28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Exclude;
29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pFlag & llvm::ELF::SHF_MASKPROC)
31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Target;
32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name rules
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::StringRef name(pName);
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".debug") ||
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".zdebug") ||
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".line") ||
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".stab"))
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Debug;
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".comment"))
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::MetaData;
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".interp") || name.startswith(".dynamic"))
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame"))
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrame;
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame_hdr"))
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrameHdr;
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".gcc_except_table"))
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::GCCExceptTable;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".note.GNU-stack"))
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::StackNote;
52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (name.startswith(".gnu.linkonce"))
53f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::LinkOnce;
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // type rules
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(pType) {
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NULL:
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Null;
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_INIT_ARRAY:
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_FINI_ARRAY:
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_PREINIT_ARRAY:
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_PROGBITS:
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Regular;
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SYMTAB:
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNSYM:
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_STRTAB:
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_HASH:
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNAMIC:
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::NamePool;
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_RELA:
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_REL:
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Relocation;
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOBITS:
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::BSS;
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOTE:
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GROUP:
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Group;
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_versym:
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verdef:
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verneed:
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Version;
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SHLIB:
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Target;
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  default:
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return LDFileFormat::Target;
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_unsupported_section) << pName << pType;
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return LDFileFormat::MetaData;
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ShouldForceLocal(const ResolveInfo& pInfo, const LinkerConfig& pConfig)
96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // forced local symbol matches all rules:
98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. We are not doing incremental linking.
99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 2. The symbol is with Hidden or Internal visibility.
100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. The symbol is defined or common
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != pConfig.codeGenType() &&
103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.visibility() == ResolveInfo::Hidden ||
104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao         pInfo.visibility() == ResolveInfo::Internal) &&
105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.isGlobal() || pInfo.isWeak()) &&
106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.isDefine() || pInfo.isCommon()))
107d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return true;
108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return false;
109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// IRBuilder
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::IRBuilder(Module& pModule, const LinkerConfig& pConfig)
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : m_Module(pModule), m_Config(pConfig), m_InputBuilder(pConfig) {
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setCurrentTree(m_Module.getInputTree());
117f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // FIXME: where to set up Relocation?
119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Relocation::SetUp(m_Config);
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::~IRBuilder()
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateInput - To create an input file and append it to the input tree.
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::CreateInput(const std::string& pName,
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              const sys::fs::Path& pPath, Input::Type pType)
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (Input::Unknown == pType)
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return ReadInput(pName, pPath);
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, pType);
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput*
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::ReadInput(const std::string& pName, const sys::fs::Path& pPath)
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, Input::Unknown);
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(const std::string& pNameSpec)
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const sys::fs::Path* path = NULL;
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // find out the real path of the namespec.
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.getConstraint().isSharedSystem()) {
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system with shared object support, we can find both archive
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // and shared object.
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_InputBuilder.getAttributes().isStatic()) {
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // with --static, we must search an archive.
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // otherwise, with --Bdynamic, we can find either an archive or a
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // shared object.
174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::DynObj);
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system without shared object support, we only look for an archive
179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == path) {
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_cannot_find_namespec) << pNameSpec;
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pNameSpec, *path);
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(raw_mem_ostream& pMemOStream)
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = NULL;
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pMemOStream.getMemoryArea().hasHandler()) {
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.createNode<InputTree::Positional>(
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               "memory ostream",
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               pMemOStream.getMemoryArea().handler()->path());
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input = *m_InputBuilder.getCurrentNode();
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input->setMemArea(&pMemOStream.getMemoryArea());
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.createNode<InputTree::Positional>("memory ostream", "NAN");
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input = *m_InputBuilder.getCurrentNode();
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input->setMemArea(&pMemOStream.getMemoryArea());
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(FileHandle& pFileHandle)
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>("file handler",
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   pFileHandle.path());
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pFileHandle.path().empty()) {
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, pFileHandle.handler(), FileHandle::ReadOnly);
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, true);
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(const std::string& pName, void* pRawMemory, size_t pSize)
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, "NAN");
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setContext(*input, false);
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setMemory(*input, pRawMemory, pSize);
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::StartGroup()
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.isInGroup()) {
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_forbid_nest_group);
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.enterGroup();
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::EndGroup()
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.exitGroup();
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::WholeArchive()
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setWholeArchive();
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoWholeArchive()
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetWholeArchive();
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AsNeeded()
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAsNeeded();
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoAsNeeded()
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAsNeeded();
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::CopyDTNeeded()
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAddNeeded();
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoCopyDTNeeded()
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAddNeeded();
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstShared()
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setDynamic();
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstStatic()
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setStatic();
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSection* IRBuilder::CreateELFHeader(Input& pInput,
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      const std::string& pName,
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pType,
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pFlag,
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pAlign)
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Create section header
314f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LDFileFormat::Kind kind = GetELFSectionKind(pType, pName.c_str(), pFlag);
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection* header = LDSection::Create(pName, kind, pType, pFlag);
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  header->setAlign(pAlign);
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Append section header in input
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pInput.context()->appendSection(*header);
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return header;
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateSectionData - To create a section data for given pSection.
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateSectionData(LDSection& pSection)
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRelocData - To create a relocation data for given pSection.
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoRelocData* IRBuilder::CreateRelocData(LDSection &pSection)
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasRelocData() && "pSection already has relocation data.");
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  RelocData* reloc_data = RelocData::Create(pSection);
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setRelocData(reloc_data);
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return reloc_data;
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateEhFrame - To create a eh_frame for given pSection
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoEhFrame* IRBuilder::CreateEhFrame(LDSection& pSection)
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasEhFrame() && "pSection already has eh_frame.");
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame* eh_frame = EhFrame::Create(pSection);
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setEhFrame(eh_frame);
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return eh_frame;
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateBSS - To create a bss section for given pSection
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateBSS(LDSection& pSection)
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert((pSection.kind() == LDFileFormat::BSS) && "pSection is not a BSS section.");
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   /*  value, valsize, size*/
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FillFragment* frag = new FillFragment(0x0, 1, pSection.size());
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ObjectBuilder::AppendFragment(*frag, *sect_data);
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment in the input file.
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(Input& pInput, size_t pOffset, size_t pLength)
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pInput.hasMemArea()) {
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_cannot_read_input) << pInput.path();
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pOffset, pLength);
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == region)
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new RegionFragment(*region);
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment wrapping the given memory
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(void* pMemory, size_t pLength)
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* region = MemoryRegion::Create(pMemory, pLength);
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == region)
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new RegionFragment(*region);
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendFragment - To append pFrag to the given SectionData pSD
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD)
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD,
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD.getSection().align());
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSD.getSection().setSize(pSD.getSection().size() + size);
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendRelocation - To append an relocation to the given RelocData pRD.
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD)
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
414d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pRD.append(pRelocation);
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a fragment to EhFrame.
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame)
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
421f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                              *pEhFrame.getSectionData(),
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              pEhFrame.getSection().align());
42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + size);
42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame)
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addFDE(pFDE);
43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pFDE.size());
43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pFDE.size();
43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame)
43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addCIE(pCIE);
43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pCIE.size());
44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pCIE.size();
44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
443d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddSymbol - To add a symbol in the input file and resolve the symbol
444d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// immediately
445d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::AddSymbol(Input& pInput,
446d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               const std::string& pName,
447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Type pType,
448d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Desc pDesc,
449d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Binding pBind,
450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::SizeType pSize,
451d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSymbol::ValueType pValue,
452d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSection* pSection,
453d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Visibility pVis)
454d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
455d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // rename symbols
456d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::string name = pName;
457f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!m_Module.getScript().renameMap().empty() &&
458d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == pDesc) {
459d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If the renameMap is not empty, some symbols should be renamed.
460d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // --wrap and --portable defines the symbol rename map.
461f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    const LinkerScript& script = m_Module.getScript();
462f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    LinkerScript::SymbolRenameMap::const_iterator renameSym =
463f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                script.renameMap().find(pName);
464f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (script.renameMap().end() != renameSym)
465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      name = renameSym.getEntry()->value();
466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
468d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (pInput.type()) {
469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::Object: {
470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
471d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      FragmentRef* frag = NULL;
472d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (NULL == pSection ||
473d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Undefined == pDesc ||
474d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Common    == pDesc ||
475d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Absolute  == pBind ||
476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Ignore   == pSection->kind() ||
477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Group    == pSection->kind())
478d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Null();
479d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else
480d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Create(*pSection, pValue);
481d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
482d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LDSymbol* input_sym = addSymbolFromObject(name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
483d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pInput.context()->addSymbol(input_sym);
484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return input_sym;
485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
486d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::DynObj: {
4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return addSymbolFromDynObj(pInput, name, pType, pDesc, pBind, pSize, pValue, pVis);
488d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default: {
490d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return NULL;
491d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      break;
492d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
493d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return NULL;
495d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
496d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
497d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
498d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
499d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
500d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
501d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
502d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
503d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         FragmentRef* pFragmentRef,
504d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
505d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
506d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 1. calculate a Resolver::Result
507d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
508d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
509d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ResolveInfo old_info; // used for arrange output symbols
510d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
511d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
512d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
513d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // resolve them.
514d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info     = m_Module.getNamePool().createSymbol(pName,
515d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   false,
516d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pType,
517d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pDesc,
518d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pBinding,
519d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pSize,
520d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pVisibility);
521d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // into output symbol table. So, we let the existent false.
524d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.existent  = false;
525d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.overriden = true;
526d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
527d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
528d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
529d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        pSize, pVisibility,
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        &old_info, resolved_result);
532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
534d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
535d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
536d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
537d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// Step 2. create an input LDSymbol.
538d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
539d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
540d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
541d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
542d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
543d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 3. Set up corresponding output LDSymbol
544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
545d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
546d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(NULL == output_sym);
549d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (pType == ResolveInfo::Section) {
551d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
552d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = input_sym;
553d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
554d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else {
555d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a new symbol, create a LDSymbol for the output
556d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = LDSymbol::Create(*resolved_result.info);
557d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
558d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
559d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
560d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
561d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
562d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // symbol can be overriden only if it exists.
563d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(output_sym != NULL);
564d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // should override output LDSymbol
566d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
567d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setValue(pValue);
568d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
569d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
570d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 4. Adjust the position of output LDSymbol.
571d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // After symbol resolution, visibility is changed to the most restrict one.
572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // we need to arrange its position in the output symbol. We arrange the
573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // positions by sorting symbols in SymbolCategory.
574d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType != ResolveInfo::Section) {
575d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (!has_output_sym) {
576d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // We merge sections when reading them. So we do not need to output symbols
577d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // with section type
578d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
579d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // No matter the symbol is already in the output or not, add it if it
580d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // should be forcefully set local.
5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (ShouldForceLocal(*resolved_result.info, m_Config))
582d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().forceLocal(*output_sym);
583d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else {
584d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // the symbol should not be forcefully local.
585d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().add(*output_sym);
586d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      }
587d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
588d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else if (resolved_result.overriden) {
5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      if (!ShouldForceLocal(old_info, m_Config) ||
5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines          !ShouldForceLocal(*resolved_result.info, m_Config)) {
591d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // If the old info and the new info are both forcefully local, then
592d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // we should keep the output_sym in forcefully local category. Else,
593d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // we should re-sort the output_sym
594d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().arrange(*output_sym, old_info);
595d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      }
596d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
597d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
598d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
599d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
600d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
601d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesLDSymbol* IRBuilder::addSymbolFromDynObj(Input& pInput,
6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         const std::string& pName,
604d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
605d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
606d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
607d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
608d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
609d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
610d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
611d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // We don't need sections of dynamic objects. So we ignore section symbols.
612d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType == ResolveInfo::Section)
613d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
614d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
615d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
616d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // visibility
617d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local ||
618d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Internal ||
619d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
620d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
621d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
622d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // A protected symbol in a shared library must be treated as a
623d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // normal symbol when viewed from outside the shared library.
624d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
625d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pVisibility = ResolveInfo::Default;
626d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
627d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // insert symbol and resolve it immediately
628d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
629d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
630d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Module.getNamePool().insertSymbol(pName, true, pType, pDesc,
631d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      pBinding, pSize, pVisibility,
632d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      NULL, resolved_result);
633d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
634d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
635d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
636d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (resolved_result.overriden || !resolved_result.existent)
6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pInput.setNeeded();
6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
640d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
641d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
642d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(FragmentRef::Null());
643d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
644d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
645d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = NULL;
646d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent) {
647d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we get a new symbol, leave it as NULL
648d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
649d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
650d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
651d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we saw the symbol before, but the output_sym still may be NULL.
652d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym = resolved_result.info->outSymbol();
653d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
655d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (output_sym != NULL) {
656d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // After symbol resolution, visibility is changed to the most restrict one.
657d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If we are not doing incremental linking, then any symbol with hidden
658d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // or internal visibility is forcefully set as a local symbol.
6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (ShouldForceLocal(*resolved_result.info, m_Config)) {
660d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_Module.getSymbolTable().forceLocal(*output_sym);
661d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
663d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
664d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
665d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
666d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
667d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddRelocation - add a relocation entry
668d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao///
669d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// All symbols should be read and resolved before calling this function.
670d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* IRBuilder::AddRelocation(LDSection& pSection,
671d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Type pType,
672d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     LDSymbol& pSym,
673d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     uint32_t pOffset,
674d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Address pAddend)
675d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
676d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // FIXME: we should dicard sections and symbols first instead
677d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // if the symbol is in the discarded input section, then we also need to
678d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // discard this relocation.
679d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ResolveInfo* resolve_info = pSym.resolveInfo();
680d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!pSym.hasFragRef() &&
681d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Section == resolve_info->type() &&
682d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == resolve_info->desc())
683d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
684d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
685d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
686d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
687d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
688d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
689d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  relocation->setSymInfo(resolve_info);
690d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pSection.getRelocData()->append(*relocation);
691d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
692d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return relocation;
693d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
694d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           const llvm::StringRef& pName,
6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Type pType,
7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Desc pDesc,
7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Binding pBinding,
7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::SizeType pSize,
7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           LDSymbol::ValueType pValue,
7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           FragmentRef* pFragmentRef,
7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Visibility pVisibility)
7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
7076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
7086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = NULL;
7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info) {
7106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is not in the pool, create a new one.
7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a ResolveInfo
7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    Resolver::Result result;
7136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc,
7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        pBinding, pSize, pVisibility,
7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        NULL, result);
7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(!result.existent);
7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (ShouldForceLocal(*result.info, m_Config))
7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().forceLocal(*output_sym);
7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is already in the pool, override it
7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ResolveInfo old_info;
7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    old_info.override(*info);
7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setRegular();
7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setType(pType);
7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setDesc(pDesc);
7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setBinding(pBinding);
7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setVisibility(pVisibility);
7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setIsSymbol(true);
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSize(pSize);
7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = info->outSymbol();
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL != output_sym)
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().arrange(*output_sym, old_info);
7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // create a output LDSymbol
7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      output_sym = LDSymbol::Create(*info);
7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      info->setSymPtr(output_sym);
7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != output_sym) {
7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
7616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           const llvm::StringRef& pName,
7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Type pType,
7656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Desc pDesc,
7666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Binding pBinding,
7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::SizeType pSize,
7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           LDSymbol::ValueType pValue,
7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           FragmentRef* pFragmentRef,
7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Visibility pVisibility)
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info || !(info->isUndef() || info->isDyn())) {
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // the symbol is already in the pool, override it
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  old_info.override(*info);
7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setRegular();
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setType(pType);
7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setDesc(pDesc);
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setBinding(pBinding);
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setVisibility(pVisibility);
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setIsSymbol(true);
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setSize(pSize);
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = info->outSymbol();
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != output_sym) {
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*info);
8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSymPtr(output_sym);
8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and resolve it
8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// immediately
8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             const llvm::StringRef& pName,
8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Type pType,
8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Desc pDesc,
8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Binding pBinding,
8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::SizeType pSize,
8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             LDSymbol::ValueType pValue,
8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             FragmentRef* pFragmentRef,
8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Visibility pVisibility)
8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Result is <info, existent, override>
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Resolver::Result result;
8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      pSize, pVisibility,
8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      &old_info, result);
8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = result.info->outSymbol();
8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool has_output_sym = (NULL != output_sym);
8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!result.existent || !has_output_sym) {
8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (result.overriden || !has_output_sym) {
8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // After symbol resolution, the visibility is changed to the most restrict.
8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // arrange the output position
8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (ShouldForceLocal(*result.info, m_Config))
8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().forceLocal(*output_sym);
8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (has_output_sym)
8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
8516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// defineSymbol - define an output symbol and resolve it immediately.
8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            const llvm::StringRef& pName,
8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Type pType,
8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Desc pDesc,
8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Binding pBinding,
8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::SizeType pSize,
8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            LDSymbol::ValueType pValue,
8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            FragmentRef* pFragmentRef,
8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Visibility pVisibility)
8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info || !(info->isUndef() || info->isDyn())) {
8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return AddSymbol<Force, Resolve>(pName,
8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pType,
8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pDesc,
8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pBinding,
8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pSize,
8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pValue,
8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pFragmentRef,
8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pVisibility);
8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
882