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>
10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LinkerScript.h>
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFReader.h>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/SectionData.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h>
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h>
17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/MemoryArea.h>
18f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/ELF.h>
19d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/FragmentRef.h>
20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/StringRef.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace mcld;
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Helper Functions
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen HinesLDFileFormat::Kind GetELFSectionKind(uint32_t pType, const char* pName,
28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                     uint32_t pFlag)
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pFlag & mcld::ELF::SHF_EXCLUDE)
31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Exclude;
32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pFlag & llvm::ELF::SHF_MASKPROC)
34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Target;
35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name rules
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::StringRef name(pName);
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".debug") ||
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".zdebug") ||
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".line") ||
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      name.startswith(".stab"))
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Debug;
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".comment"))
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::MetaData;
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".interp") || name.startswith(".dynamic"))
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame"))
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrame;
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame_hdr"))
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrameHdr;
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".gcc_except_table"))
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::GCCExceptTable;
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".note.GNU-stack"))
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::StackNote;
55f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (name.startswith(".gnu.linkonce"))
56f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::LinkOnce;
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // type rules
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  switch(pType) {
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NULL:
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Null;
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_INIT_ARRAY:
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_FINI_ARRAY:
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_PREINIT_ARRAY:
65a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  case llvm::ELF::SHT_PROGBITS: {
66a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    if ((pFlag & llvm::ELF::SHF_EXECINSTR) != 0)
67a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      return LDFileFormat::TEXT;
68a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    else
69a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      return LDFileFormat::DATA;
70a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  }
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SYMTAB:
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNSYM:
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_STRTAB:
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_HASH:
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_DYNAMIC:
76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  case llvm::ELF::SHT_SYMTAB_SHNDX:
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::NamePool;
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_RELA:
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_REL:
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Relocation;
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOBITS:
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::BSS;
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_NOTE:
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GROUP:
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Group;
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_versym:
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verdef:
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_GNU_verneed:
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Version;
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  case llvm::ELF::SHT_SHLIB:
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Target;
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  default:
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return LDFileFormat::Target;
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_unsupported_section) << pName << pType;
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return LDFileFormat::MetaData;
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// IRBuilder
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::IRBuilder(Module& pModule, const LinkerConfig& pConfig)
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  : m_Module(pModule), m_Config(pConfig), m_InputBuilder(pConfig) {
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setCurrentTree(m_Module.getInputTree());
109f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // FIXME: where to set up Relocation?
111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Relocation::SetUp(m_Config);
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::~IRBuilder()
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateInput - To create an input file and append it to the input tree.
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::CreateInput(const std::string& pName,
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              const sys::fs::Path& pPath, Input::Type pType)
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (Input::Unknown == pType)
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return ReadInput(pName, pPath);
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, pType);
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput*
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::ReadInput(const std::string& pName, const sys::fs::Path& pPath)
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, Input::Unknown);
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(const std::string& pNameSpec)
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const sys::fs::Path* path = NULL;
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // find out the real path of the namespec.
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.getConstraint().isSharedSystem()) {
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system with shared object support, we can find both archive
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // and shared object.
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_InputBuilder.getAttributes().isStatic()) {
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // with --static, we must search an archive.
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    else {
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // otherwise, with --Bdynamic, we can find either an archive or a
16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // shared object.
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::DynObj);
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system without shared object support, we only look for an archive
171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (NULL == path) {
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_cannot_find_namespec) << pNameSpec;
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pNameSpec, *path);
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::ReadInput(FileHandle& pFileHandle)
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>("file handler",
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   pFileHandle.path());
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pFileHandle.path().empty()) {
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, pFileHandle.handler(), FileHandle::ReadOnly);
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else {
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, true);
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setMemory(*input, FileHandle::ReadOnly, FileHandle::System);
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(const std::string& pName, void* pRawMemory, size_t pSize)
21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, "NAN");
21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setContext(*input, false);
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setMemory(*input, pRawMemory, pSize);
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::StartGroup()
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.isInGroup()) {
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_forbid_nest_group);
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.enterGroup();
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool IRBuilder::EndGroup()
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.exitGroup();
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::WholeArchive()
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setWholeArchive();
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoWholeArchive()
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetWholeArchive();
24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AsNeeded()
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAsNeeded();
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoAsNeeded()
25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAsNeeded();
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::CopyDTNeeded()
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAddNeeded();
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::NoCopyDTNeeded()
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAddNeeded();
26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstShared()
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setDynamic();
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AgainstStatic()
27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setStatic();
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSection* IRBuilder::CreateELFHeader(Input& pInput,
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      const std::string& pName,
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pType,
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pFlag,
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pAlign)
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Create section header
283f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LDFileFormat::Kind kind = GetELFSectionKind(pType, pName.c_str(), pFlag);
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection* header = LDSection::Create(pName, kind, pType, pFlag);
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  header->setAlign(pAlign);
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Append section header in input
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pInput.context()->appendSection(*header);
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return header;
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateSectionData - To create a section data for given pSection.
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateSectionData(LDSection& pSection)
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRelocData - To create a relocation data for given pSection.
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoRelocData* IRBuilder::CreateRelocData(LDSection &pSection)
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasRelocData() && "pSection already has relocation data.");
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  RelocData* reloc_data = RelocData::Create(pSection);
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setRelocData(reloc_data);
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return reloc_data;
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateEhFrame - To create a eh_frame for given pSection
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoEhFrame* IRBuilder::CreateEhFrame(LDSection& pSection)
31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasEhFrame() && "pSection already has eh_frame.");
31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame* eh_frame = EhFrame::Create(pSection);
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setEhFrame(eh_frame);
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return eh_frame;
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateBSS - To create a bss section for given pSection
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoSectionData* IRBuilder::CreateBSS(LDSection& pSection)
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert((pSection.kind() == LDFileFormat::BSS) && "pSection is not a BSS section.");
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   /*  value, valsize, size*/
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FillFragment* frag = new FillFragment(0x0, 1, pSection.size());
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ObjectBuilder::AppendFragment(*frag, *sect_data);
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment in the input file.
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(Input& pInput, size_t pOffset, size_t pLength)
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pInput.hasMemArea()) {
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_cannot_read_input) << pInput.path();
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
349f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::StringRef region = pInput.memArea()->request(pOffset, pLength);
350f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return new RegionFragment(region);
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment wrapping the given memory
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragment* IRBuilder::CreateRegion(void* pMemory, size_t pLength)
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
359f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  llvm::StringRef region(reinterpret_cast<const char*>(pMemory), pLength);
360f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return new RegionFragment(region);
36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendFragment - To append pFrag to the given SectionData pSD
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD)
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD,
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                pSD.getSection().align());
36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSD.getSection().setSize(pSD.getSection().size() + size);
37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendRelocation - To append an relocation to the given RelocData pRD.
37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD)
37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
376d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pRD.append(pRelocation);
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a fragment to EhFrame.
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame)
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  uint64_t size = ObjectBuilder::AppendFragment(pFrag,
383f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                              *pEhFrame.getSectionData(),
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                              pEhFrame.getSection().align());
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + size);
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame)
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addFDE(pFDE);
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pFDE.size());
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pFDE.size();
39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaouint64_t IRBuilder::AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame)
39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addCIE(pCIE);
40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pCIE.size());
40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pCIE.size();
40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
405d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddSymbol - To add a symbol in the input file and resolve the symbol
406d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// immediately
407d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::AddSymbol(Input& pInput,
408d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               const std::string& pName,
409d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Type pType,
410d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Desc pDesc,
411d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Binding pBind,
412d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::SizeType pSize,
413d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSymbol::ValueType pValue,
414d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSection* pSection,
415d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Visibility pVis)
416d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
417d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // rename symbols
418d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::string name = pName;
419f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!m_Module.getScript().renameMap().empty() &&
420d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == pDesc) {
421d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If the renameMap is not empty, some symbols should be renamed.
422d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // --wrap and --portable defines the symbol rename map.
423f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    const LinkerScript& script = m_Module.getScript();
424f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    LinkerScript::SymbolRenameMap::const_iterator renameSym =
425f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                script.renameMap().find(pName);
426f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (script.renameMap().end() != renameSym)
427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      name = renameSym.getEntry()->value();
428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
429d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
430a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  // Fix up the visibility if object has no export set.
431a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  if (pInput.noExport() && (pDesc != ResolveInfo::Undefined)) {
432a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    if ((pVis == ResolveInfo::Default) || (pVis == ResolveInfo::Protected)) {
433a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines      pVis = ResolveInfo::Hidden;
434a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines    }
435a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  }
436a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines
437d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (pInput.type()) {
438d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::Object: {
439d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
440d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      FragmentRef* frag = NULL;
441d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      if (NULL == pSection ||
442d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Undefined == pDesc ||
443d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Common    == pDesc ||
444d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          ResolveInfo::Absolute  == pBind ||
445d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Ignore   == pSection->kind() ||
446d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          LDFileFormat::Group    == pSection->kind())
447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Null();
448d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else
449d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Create(*pSection, pValue);
450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
451d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      LDSymbol* input_sym = addSymbolFromObject(name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
452d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pInput.context()->addSymbol(input_sym);
453d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return input_sym;
454d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
455d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::DynObj: {
4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      return addSymbolFromDynObj(pInput, name, pType, pDesc, pBind, pSize, pValue, pVis);
457d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
458d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default: {
459d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return NULL;
460d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      break;
461d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
462d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return NULL;
464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
465d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
468d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
470d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
471d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
472d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         FragmentRef* pFragmentRef,
473d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
474d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
475d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 1. calculate a Resolver::Result
476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
478d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ResolveInfo old_info; // used for arrange output symbols
479d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
480d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
481d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
482d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // resolve them.
483d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info     = m_Module.getNamePool().createSymbol(pName,
484d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   false,
485d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pType,
486d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pDesc,
487d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pBinding,
488d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pSize,
489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                                                   pVisibility);
490d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
491d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
492d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // into output symbol table. So, we let the existent false.
493d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.existent  = false;
494d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.overriden = true;
495d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
496d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else {
497d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
498d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
499f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                        pSize, pValue, pVisibility,
500d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                        &old_info, resolved_result);
501d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
502d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
503d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
504d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
505d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
506d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// Step 2. create an input LDSymbol.
507d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
508d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
509d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
510d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
511d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
512d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 3. Set up corresponding output LDSymbol
513d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
514d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  bool has_output_sym = (NULL != output_sym);
515d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
516d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
517d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(NULL == output_sym);
518d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
519d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (pType == ResolveInfo::Section) {
520d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
521d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = input_sym;
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    else {
524d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a new symbol, create a LDSymbol for the output
525d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = LDSymbol::Create(*resolved_result.info);
526d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
527d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
528d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
529d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // symbol can be overriden only if it exists.
532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(output_sym != NULL);
533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
534d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // should override output LDSymbol
535d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
536d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setValue(pValue);
537d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
538d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
539d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
540d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesLDSymbol* IRBuilder::addSymbolFromDynObj(Input& pInput,
5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         const std::string& pName,
543d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
545d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
546d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Visibility pVisibility)
549d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // We don't need sections of dynamic objects. So we ignore section symbols.
551d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType == ResolveInfo::Section)
552d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
553d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
554d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
555d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // visibility
556d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local ||
557d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Internal ||
558d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
559d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
560d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
561d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // A protected symbol in a shared library must be treated as a
562d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // normal symbol when viewed from outside the shared library.
563d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
564d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pVisibility = ResolveInfo::Default;
565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
566d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // insert symbol and resolve it immediately
567d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
568d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
569d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Module.getNamePool().insertSymbol(pName, true, pType, pDesc,
570f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                      pBinding, pSize, pValue, pVisibility,
571d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                      NULL, resolved_result);
572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
574d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  assert(NULL != resolved_result.info);
575d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (resolved_result.overriden || !resolved_result.existent)
5776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pInput.setNeeded();
5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
579d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
580d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
581d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(FragmentRef::Null());
582d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
583d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
584f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  // this symbol is seen in a dynamic object, set the InDyn flag
585f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  resolved_result.info->setInDyn();
586f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines
587d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent) {
588d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we get a new symbol, leave it as NULL
589d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
590d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
591d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
592d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
593d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
594d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddRelocation - add a relocation entry
595d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao///
596d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// All symbols should be read and resolved before calling this function.
597d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* IRBuilder::AddRelocation(LDSection& pSection,
598d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Type pType,
599d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     LDSymbol& pSym,
600d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     uint32_t pOffset,
601d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Address pAddend)
602d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao{
603d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
604d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
605d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
606d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
607f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  relocation->setSymInfo(pSym.resolveInfo());
608d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pSection.getRelocData()->append(*relocation);
609d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
610d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return relocation;
611d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
612d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           const llvm::StringRef& pName,
6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Type pType,
6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Desc pDesc,
6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Binding pBinding,
6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::SizeType pSize,
6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           LDSymbol::ValueType pValue,
6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           FragmentRef* pFragmentRef,
6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Visibility pVisibility)
6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = NULL;
6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info) {
6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is not in the pool, create a new one.
6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a ResolveInfo
6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    Resolver::Result result;
6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc,
632f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                        pBinding, pSize, pValue, pVisibility,
6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                        NULL, result);
6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(!result.existent);
6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
640f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    if (result.info->shouldForceLocal(m_Config))
6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().forceLocal(*output_sym);
6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is already in the pool, override it
6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ResolveInfo old_info;
6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    old_info.override(*info);
6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setRegular();
6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setType(pType);
6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setDesc(pDesc);
6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setBinding(pBinding);
6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setVisibility(pVisibility);
6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setIsSymbol(true);
6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSize(pSize);
6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = info->outSymbol();
6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (NULL != output_sym)
6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().arrange(*output_sym, old_info);
6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // create a output LDSymbol
6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      output_sym = LDSymbol::Create(*info);
6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      info->setSymPtr(output_sym);
6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != output_sym) {
6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
6736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
6746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
6796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           const llvm::StringRef& pName,
6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Type pType,
6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Desc pDesc,
6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Binding pBinding,
6856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::SizeType pSize,
6866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           LDSymbol::ValueType pValue,
6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           FragmentRef* pFragmentRef,
6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                           ResolveInfo::Visibility pVisibility)
6896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info || !(info->isUndef() || info->isDyn())) {
6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // the symbol is already in the pool, override it
6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  old_info.override(*info);
7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setRegular();
7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setType(pType);
7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setDesc(pDesc);
7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setBinding(pBinding);
7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setVisibility(pVisibility);
7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setIsSymbol(true);
7076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setSize(pSize);
7086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = info->outSymbol();
7106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL != output_sym) {
7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else {
7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*info);
7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSymPtr(output_sym);
7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and resolve it
7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// immediately
7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             const llvm::StringRef& pName,
7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Type pType,
7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Desc pDesc,
7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Binding pBinding,
7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::SizeType pSize,
7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             LDSymbol::ValueType pValue,
7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             FragmentRef* pFragmentRef,
7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                             ResolveInfo::Visibility pVisibility)
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Result is <info, existent, override>
7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Resolver::Result result;
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_Module.getNamePool().insertSymbol(pName, false, pType, pDesc, pBinding,
743f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines                                      pSize, pValue, pVisibility,
7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      &old_info, result);
7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = result.info->outSymbol();
7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  bool has_output_sym = (NULL != output_sym);
7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!result.existent || !has_output_sym) {
7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
7526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (result.overriden || !has_output_sym) {
7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // After symbol resolution, the visibility is changed to the most restrict.
7606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // arrange the output position
761f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (result.info->shouldForceLocal(m_Config))
7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().forceLocal(*output_sym);
7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (has_output_sym)
7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
7656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
7666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// defineSymbol - define an output symbol and resolve it immediately.
7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> LDSymbol*
7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesIRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            const llvm::StringRef& pName,
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Type pType,
7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Desc pDesc,
7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Binding pBinding,
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::SizeType pSize,
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            LDSymbol::ValueType pValue,
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            FragmentRef* pFragmentRef,
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                            ResolveInfo::Visibility pVisibility)
7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (NULL == info || !(info->isUndef() || info->isDyn())) {
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return AddSymbol<Force, Resolve>(pName,
7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pType,
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pDesc,
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pBinding,
7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pSize,
7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pValue,
7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pFragmentRef,
7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                   pVisibility);
7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
800