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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FragmentRef.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/DebugString.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFReader.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/ELF.h"
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h"
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// Helper Functions
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
3137b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDFileFormat::Kind GetELFSectionKind(uint32_t pType,
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     const char* pName,
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     uint32_t pFlag) {
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pFlag & llvm::ELF::SHF_EXCLUDE)
35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Exclude;
36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (pFlag & llvm::ELF::SHF_MASKPROC)
38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::Target;
39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // name rules
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::StringRef name(pName);
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (name.startswith(".debug") || name.startswith(".zdebug") ||
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      name.startswith(".line") || name.startswith(".stab")) {
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (name.startswith(".debug_str"))
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::DebugString;
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Debug;
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".comment"))
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::MetaData;
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".interp") || name.startswith(".dynamic"))
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::Note;
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame"))
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrame;
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".eh_frame_hdr"))
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::EhFrameHdr;
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".gcc_except_table"))
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::GCCExceptTable;
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (name.startswith(".note.GNU-stack"))
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return LDFileFormat::StackNote;
60f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (name.startswith(".gnu.linkonce"))
61f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return LDFileFormat::LinkOnce;
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // type rules
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  switch (pType) {
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_NULL:
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::Null;
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_INIT_ARRAY:
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_FINI_ARRAY:
6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_PREINIT_ARRAY:
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_PROGBITS: {
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if ((pFlag & llvm::ELF::SHF_EXECINSTR) != 0)
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        return LDFileFormat::TEXT;
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      else
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        return LDFileFormat::DATA;
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_SYMTAB:
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_DYNSYM:
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_STRTAB:
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_HASH:
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_DYNAMIC:
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_SYMTAB_SHNDX:
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::NamePool;
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_RELA:
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_REL:
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::Relocation;
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_NOBITS:
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::BSS;
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_NOTE:
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::Note;
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_GROUP:
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::Group;
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_GNU_versym:
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_GNU_verdef:
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_GNU_verneed:
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return LDFileFormat::Version;
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case llvm::ELF::SHT_SHLIB:
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      return LDFileFormat::Target;
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        return LDFileFormat::Target;
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      fatal(diag::err_unsupported_section) << pName << pType;
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return LDFileFormat::MetaData;
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// IRBuilder
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoIRBuilder::IRBuilder(Module& pModule, const LinkerConfig& pConfig)
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Module(pModule), m_Config(pConfig), m_InputBuilder(pConfig) {
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setCurrentTree(m_Module.getInputTree());
114f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
115f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // FIXME: where to set up Relocation?
116f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  Relocation::SetUp(m_Config);
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11937b74a387bb3993387029859c2d9d051c41c724eStephen HinesIRBuilder::~IRBuilder() {
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateInput - To create an input file and append it to the input tree.
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput* IRBuilder::CreateInput(const std::string& pName,
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                              const sys::fs::Path& pPath,
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                              Input::Type pType) {
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (Input::Unknown == pType)
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return ReadInput(pName, pPath);
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, pType);
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
13937b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput* IRBuilder::ReadInput(const std::string& pName,
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                            const sys::fs::Path& pPath) {
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_InputBuilder.createNode<InputTree::Positional>(
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pName, pPath, Input::Unknown);
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             FileHandle::Permission(FileHandle::System));
15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
15637b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput* IRBuilder::ReadInput(const std::string& pNameSpec) {
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const sys::fs::Path* path = NULL;
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // find out the real path of the namespec.
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.getConstraint().isSharedSystem()) {
16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system with shared object support, we can find both archive
16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // and shared object.
16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (m_InputBuilder.getAttributes().isStatic()) {
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // with --static, we must search an archive.
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // otherwise, with --Bdynamic, we can find either an archive or a
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // shared object.
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      path = m_Module.getScript().directories().find(pNameSpec, Input::DynObj);
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // In the system without shared object support, we only look for an archive
173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (path == NULL) {
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::err_cannot_find_namespec) << pNameSpec;
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>(pNameSpec, *path);
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasContext())
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input);
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!input->hasMemArea())
18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                             FileHandle::Permission(FileHandle::System));
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
19537b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput* IRBuilder::ReadInput(FileHandle& pFileHandle) {
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.createNode<InputTree::Positional>("file handler",
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                   pFileHandle.path());
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pFileHandle.path().empty()) {
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, false);
20237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_InputBuilder.setContext(*input, true);
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                           FileHandle::Permission(FileHandle::System));
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ReadInput - To read an input file and append it to the input tree.
21237b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput* IRBuilder::ReadInput(const std::string& pName,
21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                            void* pRawMemory,
21437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                            size_t pSize) {
21537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_InputBuilder.createNode<InputTree::Positional>(pName, sys::fs::Path("NAN"));
21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Input* input = *m_InputBuilder.getCurrentNode();
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setContext(*input, false);
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.setMemory(*input, pRawMemory, pSize);
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return input;
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool IRBuilder::StartGroup() {
22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_InputBuilder.isInGroup()) {
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_forbid_nest_group);
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return false;
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.enterGroup();
22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool IRBuilder::EndGroup() {
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.exitGroup();
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return true;
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::WholeArchive() {
23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setWholeArchive();
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::NoWholeArchive() {
24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetWholeArchive();
24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::AsNeeded() {
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAsNeeded();
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
24837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::NoAsNeeded() {
24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAsNeeded();
25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::CopyDTNeeded() {
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setAddNeeded();
25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
25637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::NoCopyDTNeeded() {
25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().unsetAddNeeded();
25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::AgainstShared() {
26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setDynamic();
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::AgainstStatic() {
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_InputBuilder.getAttributes().setStatic();
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoLDSection* IRBuilder::CreateELFHeader(Input& pInput,
26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      const std::string& pName,
27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pType,
27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                      uint32_t pFlag,
27237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      uint32_t pAlign) {
27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Create section header
274f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  LDFileFormat::Kind kind = GetELFSectionKind(pType, pName.c_str(), pFlag);
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDSection* header = LDSection::Create(pName, kind, pType, pFlag);
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  header->setAlign(pAlign);
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Append section header in input
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pInput.context()->appendSection(*header);
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return header;
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateSectionData - To create a section data for given pSection.
28437b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionData* IRBuilder::CreateSectionData(LDSection& pSection) {
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRelocData - To create a relocation data for given pSection.
29337b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocData* IRBuilder::CreateRelocData(LDSection& pSection) {
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasRelocData() && "pSection already has relocation data.");
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  RelocData* reloc_data = RelocData::Create(pSection);
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setRelocData(reloc_data);
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return reloc_data;
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateEhFrame - To create a eh_frame for given pSection
30237b74a387bb3993387029859c2d9d051c41c724eStephen HinesEhFrame* IRBuilder::CreateEhFrame(LDSection& pSection) {
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasEhFrame() && "pSection already has eh_frame.");
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  EhFrame* eh_frame = EhFrame::Create(pSection);
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setEhFrame(eh_frame);
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return eh_frame;
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines/// CreateDebugString - To create a DebugString for given pSection
31137b74a387bb3993387029859c2d9d051c41c724eStephen HinesDebugString* IRBuilder::CreateDebugString(LDSection& pSection) {
31237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(!pSection.hasDebugString() && "pSection already has debug_str.");
31337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DebugString* debug_str = DebugString::Create(pSection);
31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  pSection.setDebugString(debug_str);
31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return debug_str;
31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines
31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateBSS - To create a bss section for given pSection
32037b74a387bb3993387029859c2d9d051c41c724eStephen HinesSectionData* IRBuilder::CreateBSS(LDSection& pSection) {
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  assert(!pSection.hasSectionData() && "pSection already has section data.");
32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert((pSection.kind() == LDFileFormat::BSS) &&
32337b74a387bb3993387029859c2d9d051c41c724eStephen Hines         "pSection is not a BSS section.");
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData* sect_data = SectionData::Create(pSection);
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSection.setSectionData(sect_data);
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
32837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  /*  value, valsize, size*/
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FillFragment* frag = new FillFragment(0x0, 1, pSection.size());
33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ObjectBuilder::AppendFragment(*frag, *sect_data);
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return sect_data;
33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment in the input file.
33637b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* IRBuilder::CreateRegion(Input& pInput,
33737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  size_t pOffset,
33837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  size_t pLength) {
33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (!pInput.hasMemArea()) {
34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    fatal(diag::fatal_cannot_read_input) << pInput.path();
34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return NULL;
34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
34787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef region = pInput.memArea()->request(pOffset, pLength);
34887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return new RegionFragment(region);
34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// CreateRegion - To create a region fragment wrapping the given memory
35237b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragment* IRBuilder::CreateRegion(void* pMemory, size_t pLength) {
35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (0 == pLength)
35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return new FillFragment(0x0, 0, 0);
35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
35687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef region(reinterpret_cast<const char*>(pMemory), pLength);
35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return new RegionFragment(region);
35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendFragment - To append pFrag to the given SectionData pSD
36137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t IRBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD) {
36237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint64_t size =
36337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      ObjectBuilder::AppendFragment(pFrag, pSD, pSD.getSection().align());
36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pSD.getSection().setSize(pSD.getSection().size() + size);
36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendRelocation - To append an relocation to the given RelocData pRD.
36937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD) {
370d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pRD.append(pRelocation);
37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a fragment to EhFrame.
37437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t IRBuilder::AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame) {
37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint64_t size = ObjectBuilder::AppendFragment(
37637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pFrag, *pEhFrame.getSectionData(), pEhFrame.getSection().align());
37722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + size);
37822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return size;
37922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
38237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t IRBuilder::AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame) {
38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addFDE(pFDE);
38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pFDE.size());
38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pFDE.size();
38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
38937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t IRBuilder::AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame) {
39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.addCIE(pCIE);
39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pCIE.size());
39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return pCIE.size();
39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
395d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddSymbol - To add a symbol in the input file and resolve the symbol
396d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// immediately
397d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::AddSymbol(Input& pInput,
398d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               const std::string& pName,
399d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Type pType,
400d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Desc pDesc,
401d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::Binding pBind,
402d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               ResolveInfo::SizeType pSize,
403d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSymbol::ValueType pValue,
404d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                               LDSection* pSection,
40537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                               ResolveInfo::Visibility pVis) {
406d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // rename symbols
407d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  std::string name = pName;
408f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!m_Module.getScript().renameMap().empty() &&
409d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ResolveInfo::Undefined == pDesc) {
410d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // If the renameMap is not empty, some symbols should be renamed.
411d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // --wrap and --portable defines the symbol rename map.
412f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    const LinkerScript& script = m_Module.getScript();
413f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    LinkerScript::SymbolRenameMap::const_iterator renameSym =
41437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        script.renameMap().find(pName);
415f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    if (script.renameMap().end() != renameSym)
416d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      name = renameSym.getEntry()->value();
417d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
418d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
4190dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  // Fix up the visibility if object has no export set.
4200dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  if (pInput.noExport() && (pDesc != ResolveInfo::Undefined)) {
4210dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    if ((pVis == ResolveInfo::Default) || (pVis == ResolveInfo::Protected)) {
4220dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      pVis = ResolveInfo::Hidden;
4230dea6bc96bb52346737966839ac68644f7939f58Stephen Hines    }
4240dea6bc96bb52346737966839ac68644f7939f58Stephen Hines  }
4250dea6bc96bb52346737966839ac68644f7939f58Stephen Hines
426d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  switch (pInput.type()) {
427d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::Object: {
428d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      FragmentRef* frag = NULL;
42937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      if (pSection == NULL || ResolveInfo::Undefined == pDesc ||
43037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ResolveInfo::Common == pDesc || ResolveInfo::Absolute == pBind ||
43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          LDFileFormat::Ignore == pSection->kind() ||
43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          LDFileFormat::Group == pSection->kind())
433d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Null();
434d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      else
435d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        frag = FragmentRef::Create(*pSection, pValue);
436d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      LDSymbol* input_sym = addSymbolFromObject(
43837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
439d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pInput.context()->addSymbol(input_sym);
440d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return input_sym;
441d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
442d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    case Input::DynObj: {
44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      return addSymbolFromDynObj(
44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          pInput, name, pType, pDesc, pBind, pSize, pValue, pVis);
445d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
446d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    default: {
447d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      return NULL;
448d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      break;
449d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
450d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return NULL;
452d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
453d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
454d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoLDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
455d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
456d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
457d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
458d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
459d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
460d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         FragmentRef* pFragmentRef,
46137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         ResolveInfo::Visibility pVisibility) {
462d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 1. calculate a Resolver::Result
463d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
464d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
46537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ResolveInfo old_info;  // used for arrange output symbols
466d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
467d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pBinding == ResolveInfo::Local) {
468d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is a local symbol, create a LDSymbol for input, but do not
469d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // resolve them.
47037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    resolved_result.info = m_Module.getNamePool().createSymbol(
47137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        pName, false, pType, pDesc, pBinding, pSize, pVisibility);
472d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
473d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // No matter if there is a symbol with the same name, insert the symbol
474d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // into output symbol table. So, we let the existent false.
47537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    resolved_result.existent = false;
476d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.overriden = true;
47737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
478d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // if the symbol is not local, insert and resolve it immediately
47937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_Module.getNamePool().insertSymbol(pName,
48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        false,
48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pType,
48237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pDesc,
48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pBinding,
48437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pSize,
48537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pValue,
48637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pVisibility,
48737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        &old_info,
48837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        resolved_result);
489d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
490d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
491d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
49237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(resolved_result.info != NULL);
493d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
494d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  /// Step 2. create an input LDSymbol.
495d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
496d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
497d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(pFragmentRef);
498d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
499d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
500d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // Step 3. Set up corresponding output LDSymbol
501d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* output_sym = resolved_result.info->outSymbol();
50237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool has_output_sym = (output_sym != NULL);
503d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent || !has_output_sym) {
504d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // it is a new symbol, the output_sym should be NULL.
50537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    assert(output_sym == NULL);
506d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
507d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (pType == ResolveInfo::Section) {
508d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a section symbol, its output LDSymbol is the input LDSymbol.
509d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = input_sym;
51037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    } else {
511d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      // if it is a new symbol, create a LDSymbol for the output
512d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      output_sym = LDSymbol::Create(*resolved_result.info);
513d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    }
514d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(output_sym);
515d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
516d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
517d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (resolved_result.overriden || !has_output_sym) {
518d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // symbol can be overriden only if it exists.
519d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    assert(output_sym != NULL);
520d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
521d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // should override output LDSymbol
522d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setFragmentRef(pFragmentRef);
523d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    output_sym->setValue(pValue);
524d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
525d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
526d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
527d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesLDSymbol* IRBuilder::addSymbolFromDynObj(Input& pInput,
5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                         const std::string& pName,
530d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Type pType,
531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Desc pDesc,
532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::Binding pBinding,
533d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         ResolveInfo::SizeType pSize,
534d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                         LDSymbol::ValueType pValue,
53537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                         ResolveInfo::Visibility pVisibility) {
536d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // We don't need sections of dynamic objects. So we ignore section symbols.
537d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pType == ResolveInfo::Section)
538d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
539d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
540d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // ignore symbols with local binding or that have internal or hidden
541d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // visibility
54237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (pBinding == ResolveInfo::Local || pVisibility == ResolveInfo::Internal ||
543d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      pVisibility == ResolveInfo::Hidden)
544d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    return NULL;
545d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
546d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // A protected symbol in a shared library must be treated as a
547d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // normal symbol when viewed from outside the shared library.
548d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pVisibility == ResolveInfo::Protected)
549d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    pVisibility = ResolveInfo::Default;
550d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
551d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // insert symbol and resolve it immediately
552d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // resolved_result is a triple <resolved_info, existent, override>
553d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Resolver::Result resolved_result;
55437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Module.getNamePool().insertSymbol(pName,
55537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      true,
55637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pType,
55737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pDesc,
55837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pBinding,
55937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pSize,
56037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pValue,
56137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pVisibility,
56237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      NULL,
56337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      resolved_result);
564d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // the return ResolveInfo should not NULL
56637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(resolved_result.info != NULL);
567d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (resolved_result.overriden || !resolved_result.existent)
5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    pInput.setNeeded();
5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
571d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // create a LDSymbol for the input file.
572d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
573d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setFragmentRef(FragmentRef::Null());
574d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  input_sym->setValue(pValue);
575d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
57687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // this symbol is seen in a dynamic object, set the InDyn flag
57787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  resolved_result.info->setInDyn();
57887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
579d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (!resolved_result.existent) {
580d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    // we get a new symbol, leave it as NULL
581d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    resolved_result.info->setSymPtr(NULL);
582d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  }
583d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return input_sym;
584d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
585d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
586d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// AddRelocation - add a relocation entry
587d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao///
588d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// All symbols should be read and resolved before calling this function.
589d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoRelocation* IRBuilder::AddRelocation(LDSection& pSection,
590d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     Relocation::Type pType,
591d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     LDSymbol& pSym,
592d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                     uint32_t pOffset,
59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                     Relocation::Address pAddend) {
594d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
595d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
596d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
597d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
59887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  relocation->setSymInfo(pSym.resolveInfo());
599d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  pSection.getRelocData()->append(*relocation);
600d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
601d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return relocation;
602d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
603d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
604b0d0eb206527b43c771933602e147bbd7b471082Stephen HinesResolveInfo* IRBuilder::CreateLocalSymbol(FragmentRef& pFragRef) {
605b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  // Create and add symbol to the name pool.
606b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  ResolveInfo* resolveInfo =
607b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines      m_Module.getNamePool().createSymbol(/* pName */"",
608b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          /* pIsDyn */false,
609b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          ResolveInfo::Section,
610b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          ResolveInfo::Define,
611b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          ResolveInfo::Local,
612b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          /* pSize */0,
613b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                          ResolveInfo::Hidden);
614b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  if (resolveInfo == nullptr) {
615b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return nullptr;
616b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  }
617b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
618b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  // Create input symbol.
619b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  LDSymbol* inputSym = LDSymbol::Create(*resolveInfo);
620b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  if (inputSym == nullptr) {
621b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return nullptr;
622b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  }
623b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
624b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  inputSym->setFragmentRef(FragmentRef::Create(*pFragRef.frag(),
625b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                                               pFragRef.offset()));
626b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  inputSym->setValue(/* pValue */0);
627b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
628b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  // The output symbol is simply an alias to the input symbol.
629b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  resolveInfo->setSymPtr(inputSym);
630b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
631b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  return resolveInfo;
632b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines}
633b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
63537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
63637b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
63737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const llvm::StringRef& pName,
63837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Type pType,
63937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Desc pDesc,
64037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Binding pBinding,
64137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::SizeType pSize,
64237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    LDSymbol::ValueType pValue,
64337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    FragmentRef* pFragmentRef,
64437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Visibility pVisibility) {
6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = NULL;
64737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (info == NULL) {
6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is not in the pool, create a new one.
6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a ResolveInfo
6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    Resolver::Result result;
65137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_Module.getNamePool().insertSymbol(pName,
65237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        false,
65337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pType,
65437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pDesc,
65537b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pBinding,
65637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pSize,
65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pValue,
65837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        pVisibility,
65937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        NULL,
66037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                        result);
6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(!result.existent);
6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
66787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    if (result.info->shouldForceLocal(m_Config))
6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().forceLocal(*output_sym);
6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else
6706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
67137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // the symbol is already in the pool, override it
6736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    ResolveInfo old_info;
6746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    old_info.override(*info);
6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setRegular();
6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setType(pType);
6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setDesc(pDesc);
6796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setBinding(pBinding);
6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setVisibility(pVisibility);
6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setIsSymbol(true);
6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSize(pSize);
6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = info->outSymbol();
68537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (output_sym != NULL)
6866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().arrange(*output_sym, old_info);
6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    else {
6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      // create a output LDSymbol
6896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      output_sym = LDSymbol::Create(*info);
6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      info->setSymPtr(output_sym);
6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      m_Module.getSymbolTable().add(*output_sym);
6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    }
6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
69637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (output_sym != NULL) {
6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and override it immediately
70537b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
70637b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol* IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
70737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const llvm::StringRef& pName,
70837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Type pType,
70937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Desc pDesc,
71037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Binding pBinding,
71137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::SizeType pSize,
71237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    LDSymbol::ValueType pValue,
71337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    FragmentRef* pFragmentRef,
71437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Visibility pVisibility) {
7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
71737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (info == NULL || !(info->isUndef() || info->isDyn())) {
7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // the symbol is already in the pool, override it
7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  old_info.override(*info);
7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setRegular();
7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setType(pType);
7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setDesc(pDesc);
7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setBinding(pBinding);
7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setVisibility(pVisibility);
7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setIsSymbol(true);
7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  info->setSize(pSize);
7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = info->outSymbol();
73537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (output_sym != NULL) {
7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
73937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // create a output LDSymbol
7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*info);
7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    info->setSymPtr(output_sym);
7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// AddSymbol - define an output symbol and resolve it
7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// immediately
75237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
75337b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
75437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const llvm::StringRef& pName,
75537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Type pType,
75637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Desc pDesc,
75737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Binding pBinding,
75837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::SizeType pSize,
75937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    LDSymbol::ValueType pValue,
76037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    FragmentRef* pFragmentRef,
76137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Visibility pVisibility) {
7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // Result is <info, existent, override>
7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  Resolver::Result result;
7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo old_info;
76537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Module.getNamePool().insertSymbol(pName,
76637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      false,
76737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pType,
76837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pDesc,
76937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pBinding,
77037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pSize,
77137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pValue,
77237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      pVisibility,
77337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      &old_info,
77437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      result);
7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  LDSymbol* output_sym = result.info->outSymbol();
77737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool has_output_sym = (output_sym != NULL);
7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (!result.existent || !has_output_sym) {
7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym = LDSymbol::Create(*result.info);
7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    result.info->setSymPtr(output_sym);
7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (result.overriden || !has_output_sym) {
7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setFragmentRef(pFragmentRef);
7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    output_sym->setValue(pValue);
7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // After symbol resolution, the visibility is changed to the most restrict.
7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // arrange the output position
79187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (result.info->shouldForceLocal(m_Config))
7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().forceLocal(*output_sym);
7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else if (has_output_sym)
7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().arrange(*output_sym, old_info);
7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  else
7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_Module.getSymbolTable().add(*output_sym);
7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return output_sym;
7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// defineSymbol - define an output symbol and resolve it immediately.
80237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
80337b74a387bb3993387029859c2d9d051c41c724eStephen HinesLDSymbol* IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
80437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    const llvm::StringRef& pName,
80537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Type pType,
80637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Desc pDesc,
80737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Binding pBinding,
80837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::SizeType pSize,
80937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    LDSymbol::ValueType pValue,
81037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    FragmentRef* pFragmentRef,
81137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ResolveInfo::Visibility pVisibility) {
8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
81437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (info == NULL || !(info->isUndef() || info->isDyn())) {
8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    // only undefined symbol and dynamic symbol can make a reference.
8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return NULL;
8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
81937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return AddSymbol<Force, Resolve>(
82037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pName, pType, pDesc, pBinding, pSize, pValue, pFragmentRef, pVisibility);
8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
82337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
824