IRBuilder.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
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>
16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/FragmentRef.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Helper Functions
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDFileFormat::Kind GetELFSectionKind(uint32_t pType, const char* pName)
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name rules
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::StringRef name(pName);
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".debug") ||
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".zdebug") ||
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".gnu.linkonce.wi.") ||
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".line") ||
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".stab"))
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Debug;
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".comment"))
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::MetaData;
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".interp") || name.startswith(".dynamic"))
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame"))
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrame;
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame_hdr"))
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrameHdr;
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".gcc_except_table"))
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::GCCExceptTable;
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".note.GNU-stack"))
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::StackNote;
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // type rules
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(pType) {
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NULL:
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Null;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_INIT_ARRAY:
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_FINI_ARRAY:
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_PREINIT_ARRAY:
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_PROGBITS:
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Regular;
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SYMTAB:
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNSYM:
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_STRTAB:
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_HASH:
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNAMIC:
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::NamePool;
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_RELA:
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_REL:
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Relocation;
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOBITS:
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::BSS;
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOTE:
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GROUP:
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Group;
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_versym:
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verdef:
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verneed:
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Version;
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SHLIB:
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Target;
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  default:
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return LDFileFormat::Target;
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_unsupported_section) << pName << pType;
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return LDFileFormat::MetaData;
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
86d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaobool shouldForceLocal(const ResolveInfo& pInfo, const LinkerConfig& pConfig)
87d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
88d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // forced local symbol matches all rules:
89d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 1. We are not doing incremental linking.
90d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 2. The symbol is with Hidden or Internal visibility.
91d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 3. The symbol should be global or weak. Otherwise, local symbol is local.
92d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // 4. The symbol is defined or common
93d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::Object != pConfig.codeGenType() &&
94d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.visibility() == ResolveInfo::Hidden ||
95d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao         pInfo.visibility() == ResolveInfo::Internal) &&
96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.isGlobal() || pInfo.isWeak()) &&
97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (pInfo.isDefine() || pInfo.isCommon()))
98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return true;
99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return false;
100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// IRBuilder
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::IRBuilder(Module& pModule, const LinkerConfig& pConfig)
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : m_Module(pModule), m_Config(pConfig), m_InputBuilder(pConfig) {
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setCurrentTree(m_Module.getInputTree());
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::~IRBuilder()
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateInput - To create an input file and append it to the input tree.
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::CreateInput(const std::string& pName,
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              const sys::fs::Path& pPath, Input::Type pType)
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (Input::Unknown == pType)
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return ReadInput(pName, pPath);
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, pType);
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput*
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::ReadInput(const std::string& pName, const sys::fs::Path& pPath)
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, Input::Unknown);
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(const std::string& pNameSpec)
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const sys::fs::Path* path = NULL;
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // find out the real path of the namespec.
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.getConstraint().isSharedSystem()) {
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system with shared object support, we can find both archive
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // and shared object.
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_InputBuilder.getAttributes().isStatic()) {
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // with --static, we must search an archive.
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      path = m_Config.options().directories().find(pNameSpec, Input::Archive);
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // otherwise, with --Bdynamic, we can find either an archive or a
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // shared object.
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      path = m_Config.options().directories().find(pNameSpec, Input::DynObj);
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system without shared object support, we only look for an archive
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    path = m_Config.options().directories().find(pNameSpec, Input::Archive);
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == path) {
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_cannot_find_namespec) << pNameSpec;
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pNameSpec, *path);
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(raw_mem_ostream& pMemOStream)
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = NULL;
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pMemOStream.getMemoryArea().hasHandler()) {
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.createNode<InputTree::Positional>(
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               "memory ostream",
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                               pMemOStream.getMemoryArea().handler()->path());
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input = *m_InputBuilder.getCurrentNode();
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input->setMemArea(&pMemOStream.getMemoryArea());
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.createNode<InputTree::Positional>("memory ostream", "NAN");
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input = *m_InputBuilder.getCurrentNode();
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    input->setMemArea(&pMemOStream.getMemoryArea());
20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(FileHandle& pFileHandle)
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>("file handler",
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   pFileHandle.path());
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pFileHandle.path().empty()) {
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, pFileHandle.handler(), FileHandle::ReadOnly);
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, true);
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(const std::string& pName, void* pRawMemory, size_t pSize)
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, "NAN");
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setContext(*input, false);
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setMemory(*input, pRawMemory, pSize);
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::StartGroup()
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.isInGroup()) {
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_forbid_nest_group);
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.enterGroup();
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::EndGroup()
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.exitGroup();
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::WholeArchive()
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setWholeArchive();
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoWholeArchive()
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetWholeArchive();
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AsNeeded()
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAsNeeded();
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoAsNeeded()
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAsNeeded();
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::CopyDTNeeded()
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAddNeeded();
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoCopyDTNeeded()
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAddNeeded();
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstShared()
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setDynamic();
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstStatic()
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setStatic();
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSection* IRBuilder::CreateELFHeader(Input& pInput,
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      const std::string& pName,
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pType,
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pFlag,
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pAlign)
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Create section header
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDFileFormat::Kind kind = GetELFSectionKind(pType, pName.c_str());
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection* header = LDSection::Create(pName, kind, pType, pFlag);
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  header->setAlign(pAlign);
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Append section header in input
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pInput.context()->appendSection(*header);
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return header;
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateSectionData - To create a section data for given pSection.
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateSectionData(LDSection& pSection)
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRelocData - To create a relocation data for given pSection.
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoRelocData* IRBuilder::CreateRelocData(LDSection &pSection)
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasRelocData() && "pSection already has relocation data.");
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  RelocData* reloc_data = RelocData::Create(pSection);
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setRelocData(reloc_data);
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return reloc_data;
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateEhFrame - To create a eh_frame for given pSection
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoEhFrame* IRBuilder::CreateEhFrame(LDSection& pSection)
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasEhFrame() && "pSection already has eh_frame.");
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  EhFrame* eh_frame = new EhFrame(pSection);
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setEhFrame(eh_frame);
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return eh_frame;
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateBSS - To create a bss section for given pSection
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateBSS(LDSection& pSection)
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert((pSection.kind() == LDFileFormat::BSS) && "pSection is not a BSS section.");
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   /*  value, valsize, size*/
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FillFragment* frag = new FillFragment(0x0, 1, pSection.size());
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ObjectBuilder::AppendFragment(*frag, *sect_data);
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment in the input file.
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(Input& pInput, size_t pOffset, size_t pLength)
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pInput.hasMemArea()) {
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_cannot_read_input) << pInput.path();
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pOffset, pLength);
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == region)
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new RegionFragment(*region);
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment wrapping the given memory
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(void* pMemory, size_t pLength)
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MemoryRegion* region = MemoryRegion::Create(pMemory, pLength);
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == region)
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return new RegionFragment(*region);
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendFragment - To append pFrag to the given SectionData pSD
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD)
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD,
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD.getSection().align());
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSD.getSection().setSize(pSD.getSection().size() + size);
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendRelocation - To append an relocation to the given RelocData pRD.
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD)
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
402d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pRD.append(pRelocation);
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a fragment to EhFrame.
40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame)
40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              pEhFrame.getSectionData(),
41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              pEhFrame.getSection().align());
41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + size);
41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame)
41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addFDE(pFDE);
41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pFDE.size());
42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pFDE.size();
42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame)
42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addCIE(pCIE);
42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pCIE.size());
42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pCIE.size();
42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
431d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddSymbol - To add a symbol in the input file and resolve the symbol
432d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// immediately
433d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::AddSymbol(Input& pInput,
434d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               const std::string& pName,
435d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Type pType,
436d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Desc pDesc,
437d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Binding pBind,
438d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::SizeType pSize,
439d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSymbol::ValueType pValue,
440d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSection* pSection,
441d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Visibility pVis)
442d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
443d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // rename symbols
444d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::string name = pName;
445d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!m_Config.scripts().renameMap().empty() &&
446d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == pDesc) {
447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If the renameMap is not empty, some symbols should be renamed.
448d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // --wrap and --portable defines the symbol rename map.
449d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    ScriptOptions::SymbolRenameMap::const_iterator renameSym =
450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                    m_Config.scripts().renameMap().find(pName);
451d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (renameSym != m_Config.scripts().renameMap().end())
452d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      name = renameSym.getEntry()->value();
453d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
454d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
455d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (pInput.type()) {
456d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::Object: {
457d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
458d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      FragmentRef* frag = NULL;
459d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (NULL == pSection ||
460d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Undefined == pDesc ||
461d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Common    == pDesc ||
462d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Absolute  == pBind ||
463d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Ignore   == pSection->kind() ||
464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Group    == pSection->kind())
465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Null();
466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else
467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Create(*pSection, pValue);
468d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LDSymbol* input_sym = addSymbolFromObject(name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pInput.context()->addSymbol(input_sym);
471d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return input_sym;
472d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
473d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::DynObj: {
474d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return addSymbolFromDynObj(name, pType, pDesc, pBind, pSize, pValue, pVis);
475d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default: {
477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return NULL;
478d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      break;
479d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
480d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
481d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
482d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
483d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
486d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
487d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
488d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         FragmentRef* pFragmentRef,
490d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
491d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
492d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 1. calculate a Resolver::Result
493d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
494d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
495d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ResolveInfo old_info; // used for arrange output symbols
496d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
497d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
498d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
499d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // resolve them.
500d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info     = m_Module.getNamePool().createSymbol(pName,
501d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   false,
502d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pType,
503d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pDesc,
504d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pBinding,
505d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pSize,
506d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pVisibility);
507d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
508d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
509d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // into output symbol table. So, we let the existent false.
510d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.existent  = false;
511d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.overriden = true;
512d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
513d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
514d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
515d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
516d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        pSize, pVisibility,
517d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        &old_info, resolved_result);
518d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
519d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
520d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
521d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// Step 2. create an input LDSymbol.
524d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
525d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
526d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
527d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
528d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
529d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 3. Set up corresponding output LDSymbol
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
534d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(NULL == output_sym);
535d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
536d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (pType == ResolveInfo::Section) {
537d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
538d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = input_sym;
539d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
540d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else {
541d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a new symbol, create a LDSymbol for the output
542d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = LDSymbol::Create(*resolved_result.info);
543d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
545d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
546d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // symbol can be overriden only if it exists.
549d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(output_sym != NULL);
550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
551d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // should override output LDSymbol
552d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
553d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setValue(pValue);
554d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
555d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
556d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 4. Adjust the position of output LDSymbol.
557d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // After symbol resolution, visibility is changed to the most restrict one.
558d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // we need to arrange its position in the output symbol. We arrange the
559d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // positions by sorting symbols in SymbolCategory.
560d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType != ResolveInfo::Section) {
561d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (!has_output_sym) {
562d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // We merge sections when reading them. So we do not need to output symbols
563d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // with section type
564d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // No matter the symbol is already in the output or not, add it if it
566d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // should be forcefully set local.
567d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (shouldForceLocal(*resolved_result.info, m_Config))
568d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().forceLocal(*output_sym);
569d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else {
570d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // the symbol should not be forcefully local.
571d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().add(*output_sym);
572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      }
573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
574d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else if (resolved_result.overriden) {
575d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (!shouldForceLocal(old_info, m_Config) ||
576d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          !shouldForceLocal(*resolved_result.info, m_Config)) {
577d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // If the old info and the new info are both forcefully local, then
578d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // we should keep the output_sym in forcefully local category. Else,
579d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // we should re-sort the output_sym
580d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Module.getSymbolTable().arrange(*output_sym, old_info);
581d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      }
582d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
583d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
584d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
585d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
586d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
587d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
588d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::addSymbolFromDynObj(const std::string& pName,
589d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
590d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
591d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
592d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
593d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
594d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
595d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
596d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // We don't need sections of dynamic objects. So we ignore section symbols.
597d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType == ResolveInfo::Section)
598d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
599d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
600d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
601d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // visibility
602d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local ||
603d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Internal ||
604d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
605d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
606d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
607d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // A protected symbol in a shared library must be treated as a
608d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // normal symbol when viewed from outside the shared library.
609d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
610d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pVisibility = ResolveInfo::Default;
611d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
612d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // insert symbol and resolve it immediately
613d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
614d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
615d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Module.getNamePool().insertSymbol(pName, true, pType, pDesc,
616d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      pBinding, pSize, pVisibility,
617d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      NULL, resolved_result);
618d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
619d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
620d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
621d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
622d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
623d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
624d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(FragmentRef::Null());
625d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
626d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
627d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = NULL;
628d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent) {
629d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we get a new symbol, leave it as NULL
630d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
631d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
632d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
633d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we saw the symbol before, but the output_sym still may be NULL.
634d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym = resolved_result.info->outSymbol();
635d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
636d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
637d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (output_sym != NULL) {
638d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // After symbol resolution, visibility is changed to the most restrict one.
639d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If we are not doing incremental linking, then any symbol with hidden
640d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // or internal visibility is forcefully set as a local symbol.
641d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (shouldForceLocal(*resolved_result.info, m_Config)) {
642d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_Module.getSymbolTable().forceLocal(*output_sym);
643d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
644d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
645d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
646d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
647d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
648d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
649d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddRelocation - add a relocation entry
650d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao///
651d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// All symbols should be read and resolved before calling this function.
652d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* IRBuilder::AddRelocation(LDSection& pSection,
653d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Type pType,
654d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     LDSymbol& pSym,
655d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     uint32_t pOffset,
656d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Address pAddend)
657d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
658d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // FIXME: we should dicard sections and symbols first instead
659d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // if the symbol is in the discarded input section, then we also need to
660d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // discard this relocation.
661d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ResolveInfo* resolve_info = pSym.resolveInfo();
662d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!pSym.hasFragRef() &&
663d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Section == resolve_info->type() &&
664d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == resolve_info->desc())
665d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
666d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
667d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
668d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
669d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
670d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
671d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  relocation->setSymInfo(resolve_info);
672d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pSection.getRelocData()->append(*relocation);
673d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
674d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return relocation;
675d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
676d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
677