LLVM API Documentation
00001 //===-- InternalGlobalMapper.cpp - Mapping Info for Internal Globals ------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // InternalGlobalMapper is a pass that helps the runtime trace optimizer map 00011 // the names of internal GlobalValues (which may have mangled, 00012 // unreconstructible names in the executable) to pointers. If the name mangler 00013 // is changed at some point in the future to allow its results to be 00014 // reconstructible (for instance, by making the type mangling symbolic instead 00015 // of using a UniqueID) this pass should probably be phased out. 00016 // 00017 //===----------------------------------------------------------------------===// 00018 00019 #include "llvm/Constants.h" 00020 #include "llvm/Module.h" 00021 #include "llvm/Pass.h" 00022 #include "llvm/DerivedTypes.h" 00023 using namespace llvm; 00024 00025 typedef std::vector<Constant *> GVVectorTy; 00026 00027 namespace { 00028 struct InternalGlobalMapper : public ModulePass { 00029 bool runOnModule(Module &M); 00030 }; 00031 } 00032 00033 namespace llvm { 00034 ModulePass *createInternalGlobalMapperPass() { 00035 return new InternalGlobalMapper(); 00036 } 00037 } 00038 00039 static void maybeAddInternalValueToVector (GVVectorTy &Vector, GlobalValue &GV){ 00040 // If it's a GlobalValue with internal linkage and a name (i.e. it's going to 00041 // be mangled), then put the GV, casted to sbyte*, in the vector. Otherwise 00042 // add a null. 00043 if (GV.hasInternalLinkage () && GV.hasName ()) 00044 Vector.push_back(ConstantExpr::getCast(&GV, 00045 PointerType::get(Type::SByteTy))); 00046 else 00047 Vector.push_back (ConstantPointerNull::get (PointerType::get 00048 (Type::SByteTy))); 00049 } 00050 00051 bool InternalGlobalMapper::runOnModule(Module &M) { 00052 GVVectorTy gvvector; 00053 00054 // Populate the vector with internal global values and their names. 00055 for (Module::giterator i = M.gbegin (), e = M.gend (); i != e; ++i) 00056 maybeAddInternalValueToVector (gvvector, *i); 00057 // Add an extra global for _llvm_internalGlobals itself (null, 00058 // because it's not internal) 00059 gvvector.push_back (ConstantPointerNull::get 00060 (PointerType::get (Type::SByteTy))); 00061 for (Module::iterator i = M.begin (), e = M.end (); i != e; ++i) 00062 maybeAddInternalValueToVector (gvvector, *i); 00063 00064 // Convert the vector to a constant struct of type {Size, [Size x sbyte*]}. 00065 ArrayType *ATy = ArrayType::get (PointerType::get (Type::SByteTy), 00066 gvvector.size ()); 00067 std::vector<const Type *> FieldTypes; 00068 FieldTypes.push_back (Type::UIntTy); 00069 FieldTypes.push_back (ATy); 00070 StructType *STy = StructType::get (FieldTypes); 00071 std::vector<Constant *> FieldValues; 00072 FieldValues.push_back (ConstantUInt::get (Type::UIntTy, gvvector.size ())); 00073 FieldValues.push_back (ConstantArray::get (ATy, gvvector)); 00074 00075 // Add the constant struct to M as an external global symbol named 00076 // "_llvm_internalGlobals". 00077 new GlobalVariable (STy, true, GlobalValue::ExternalLinkage, 00078 ConstantStruct::get (STy, FieldValues), 00079 "_llvm_internalGlobals", &M); 00080 00081 return true; // Module was modified. 00082 }