IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
: SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
Mang.reset(new Mangler());
+
+ for (Function &F : *M)
+ SymTab.push_back(&F);
+ for (GlobalVariable &GV : M->globals())
+ SymTab.push_back(&GV);
+ for (GlobalAlias &GA : M->aliases())
+ SymTab.push_back(&GA);
+
CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
[this](StringRef Name, BasicSymbolRef::Flags Flags) {
- AsmSymbols.emplace_back(Name, std::move(Flags));
+ SymTab.push_back(new (AsmSymbols.Allocate())
+ AsmSymbol(Name, Flags));
});
}
}
}
-IRObjectFile::~IRObjectFile() {
- }
-
-static GlobalValue *getGV(DataRefImpl &Symb) {
- if ((Symb.p & 3) == 3)
- return nullptr;
-
- return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
-}
-
-static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
- if (I == M.alias_end())
- return 3;
- const GlobalValue *GV = &*I;
- return reinterpret_cast<uintptr_t>(GV) | 2;
-}
-
-static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
- if (I == M.global_end())
- return skipEmpty(M.alias_begin(), M);
- const GlobalValue *GV = &*I;
- return reinterpret_cast<uintptr_t>(GV) | 1;
-}
-
-static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
- if (I == M.end())
- return skipEmpty(M.global_begin(), M);
- const GlobalValue *GV = &*I;
- return reinterpret_cast<uintptr_t>(GV) | 0;
-}
-
-static unsigned getAsmSymIndex(DataRefImpl Symb) {
- assert((Symb.p & uintptr_t(3)) == 3);
- uintptr_t Index = Symb.p & ~uintptr_t(3);
- Index >>= 2;
- return Index;
-}
+IRObjectFile::~IRObjectFile() {}
void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- const GlobalValue *GV = getGV(Symb);
- uintptr_t Res;
-
- switch (Symb.p & 3) {
- case 0: {
- Module::const_iterator Iter(static_cast<const Function*>(GV));
- ++Iter;
- Res = skipEmpty(Iter, *M);
- break;
- }
- case 1: {
- Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
- ++Iter;
- Res = skipEmpty(Iter, *M);
- break;
- }
- case 2: {
- Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
- ++Iter;
- Res = skipEmpty(Iter, *M);
- break;
- }
- case 3: {
- unsigned Index = getAsmSymIndex(Symb);
- assert(Index < AsmSymbols.size());
- ++Index;
- Res = (Index << 2) | 3;
- break;
- }
- default:
- llvm_unreachable("unreachable case");
- }
-
- Symb.p = Res;
+ Symb.p += sizeof(Sym);
}
std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const {
- const GlobalValue *GV = getGV(Symb);
- if (!GV) {
- unsigned Index = getAsmSymIndex(Symb);
- assert(Index <= AsmSymbols.size());
- OS << AsmSymbols[Index].first;
+ Sym S = getSym(Symb);
+ if (S.is<AsmSymbol *>()) {
+ OS << S.get<AsmSymbol *>()->first;
return std::error_code();
}
+ auto *GV = S.get<GlobalValue *>();
if (GV->hasDLLImportStorageClass())
OS << "__imp_";
}
uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
- const GlobalValue *GV = getGV(Symb);
+ Sym S = getSym(Symb);
+ if (S.is<AsmSymbol *>())
+ return S.get<AsmSymbol *>()->second;
- if (!GV) {
- unsigned Index = getAsmSymIndex(Symb);
- assert(Index <= AsmSymbols.size());
- return AsmSymbols[Index].second;
- }
+ auto *GV = S.get<GlobalValue *>();
uint32_t Res = BasicSymbolRef::SF_None;
if (GV->isDeclarationForLinker())
return Res;
}
-GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); }
+GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) {
+ return getSym(Symb).dyn_cast<GlobalValue *>();
+}
std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
basic_symbol_iterator IRObjectFile::symbol_begin() const {
- Module::const_iterator I = M->begin();
DataRefImpl Ret;
- Ret.p = skipEmpty(I, *M);
+ Ret.p = reinterpret_cast<uintptr_t>(SymTab.data());
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}
basic_symbol_iterator IRObjectFile::symbol_end() const {
DataRefImpl Ret;
- uint64_t NumAsm = AsmSymbols.size();
- NumAsm <<= 2;
- Ret.p = 3 | NumAsm;
+ Ret.p = reinterpret_cast<uintptr_t>(SymTab.data() + SymTab.size());
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
}