IRObjectFile.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===//
221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//
321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//                     The LLVM Compiler Infrastructure
421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//
521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// This file is distributed under the University of Illinois Open Source
621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// License. See LICENSE.TXT for details.
721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//
821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===----------------------------------------------------------------------===//
921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//
1021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// Part of the IRObjectFile class implementation.
1121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//
1221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===----------------------------------------------------------------------===//
1321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
1421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Bitcode/ReaderWriter.h"
1521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/LLVMContext.h"
1621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/Mangler.h"
1721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/Module.h"
1821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Object/IRObjectFile.h"
1921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Support/raw_ostream.h"
2021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochusing namespace llvm;
2121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochusing namespace object;
2221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
2321efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochIRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC,
2421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch                           LLVMContext &Context, bool BufferOwned)
2521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    : SymbolicFile(Binary::ID_IR, Object, BufferOwned) {
2621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context);
2721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if ((EC = MOrErr.getError()))
2821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return;
2921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
3021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  M.reset(MOrErr.get());
3121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
3221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  // If we have a DataLayout, setup a mangler.
3321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const DataLayout *DL = M->getDataLayout();
3421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (!DL)
3521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return;
3621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
3721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Mang.reset(new Mangler(DL));
3821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
3921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
4021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic const GlobalValue &getGV(DataRefImpl &Symb) {
4121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
4221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
4321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
4421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
4521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (I == M.alias_end())
4621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return 3;
4721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue *GV = &*I;
4821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return reinterpret_cast<uintptr_t>(GV) | 2;
4921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
5021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
5121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
5221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (I == M.global_end())
5321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return skipEmpty(M.alias_begin(), M);
5421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue *GV = &*I;
5521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return reinterpret_cast<uintptr_t>(GV) | 1;
5621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
5721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
5821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
5921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (I == M.end())
6021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return skipEmpty(M.global_begin(), M);
6121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue *GV = &*I;
6221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return reinterpret_cast<uintptr_t>(GV) | 0;
6321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
6421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
6521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
6621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue *GV = &getGV(Symb);
6721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const Module &M = *GV->getParent();
6821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  uintptr_t Res;
6921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  switch (Symb.p & 3) {
7021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  case 0: {
7121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Module::const_iterator Iter(static_cast<const Function*>(GV));
7221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    ++Iter;
7321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res = skipEmpty(Iter, M);
7421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    break;
7521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  }
7621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  case 1: {
7721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
7821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    ++Iter;
7921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res = skipEmpty(Iter, M);
8021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    break;
8121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  }
8221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  case 2: {
8321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
8421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    ++Iter;
8521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res = skipEmpty(Iter, M);
8621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    break;
8721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  }
8821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  case 3:
8921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    llvm_unreachable("Invalid symbol reference");
9021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  }
9121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
9221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Symb.p = Res;
9321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
9421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
9521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdocherror_code IRObjectFile::printSymbolName(raw_ostream &OS,
9621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch                                         DataRefImpl Symb) const {
9721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue &GV = getGV(Symb);
9821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
9921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (Mang)
10021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Mang->getNameWithPrefix(OS, &GV, false);
10121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  else
10221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    OS << GV.getName();
10321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
10421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return object_error::success;
10521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
10621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
10721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochuint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
10821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue &GV = getGV(Symb);
10921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
11021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  uint32_t Res = BasicSymbolRef::SF_None;
11121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage())
11221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res |= BasicSymbolRef::SF_Undefined;
11321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (GV.hasPrivateLinkage())
11421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res |= BasicSymbolRef::SF_FormatSpecific;
11521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (!GV.hasLocalLinkage())
11621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res |= BasicSymbolRef::SF_Global;
11721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (GV.hasCommonLinkage())
11821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res |= BasicSymbolRef::SF_Common;
11921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage())
12021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    Res |= BasicSymbolRef::SF_Weak;
12121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
12221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return Res;
12321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
12421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
12521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochconst GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
12621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  const GlobalValue &GV = getGV(Symb);
12721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return GV;
12821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
12921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
13021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochbasic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
13121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Module::const_iterator I = M->begin();
13221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  DataRefImpl Ret;
13321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Ret.p = skipEmpty(I, *M);
13421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
13521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
13621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
13721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochbasic_symbol_iterator IRObjectFile::symbol_end_impl() const {
13821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  DataRefImpl Ret;
13921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  Ret.p = 3;
14021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return basic_symbol_iterator(BasicSymbolRef(Ret, this));
14121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
14221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch
14321efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile(
14421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) {
14521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  error_code EC;
14621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  std::unique_ptr<IRObjectFile> Ret(
14721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch      new IRObjectFile(Object, EC, Context, BufferOwned));
14821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  if (EC)
14921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch    return EC;
15021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch  return Ret.release();
15121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch}
15221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch