/// Given a specified llvm.global_ctors list, remove the listed elements.
static void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) {
  // Filter out the initializer elements to remove.
  ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer());
  SmallVector<Constant *, 10> CAList;
  for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I)
    if (!CtorsToRemove.test(I))
      CAList.push_back(OldCA->getOperand(I));

  // Create the new array initializer.
  ArrayType *ATy =
      ArrayType::get(OldCA->getType()->getElementType(), CAList.size());
  Constant *CA = ConstantArray::get(ATy, CAList);

  // If we didn't change the number of elements, don't create a new GV.
  if (CA->getType() == OldCA->getType()) {
    GCL->setInitializer(CA);
    return;
  }

  // Create the new global and insert it next to the existing list.
  GlobalVariable *NGV =
      new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(),
                         CA, "", GCL->getThreadLocalMode());
  GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV);
  NGV->takeName(GCL);

  // Nuke the old list, replacing any uses with the new one.
  if (!GCL->use_empty()) {
    Constant *V = NGV;
    if (V->getType() != GCL->getType())
      V = ConstantExpr::getBitCast(V, GCL->getType());
    GCL->replaceAllUsesWith(V);
  }
  GCL->eraseFromParent();
}
void Variables::changeGlobal(Change* change, Module &module) {

  GlobalValue* oldTarget = dyn_cast<GlobalValue>(change->getValue());
  Type* oldType = oldTarget->getType()->getElementType();
  Type* newType = change->getType()[0];
  errs() << "Changing the precision of variable \"" << oldTarget->getName() << "\" from " << *oldType << " to " << *newType << ".\n";

  if (diffTypes(oldType, newType)) {      
    Constant *initializer;
    GlobalVariable* newTarget;

    if (PointerType *newPointerType = dyn_cast<PointerType>(newType)) {
      initializer = ConstantPointerNull::get(newPointerType);
      newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, "");
    }
    else if (ArrayType * atype = dyn_cast<ArrayType>(newType)) {

      // preparing initializer
      Type *temp = Type::getFloatTy(module.getContext());
      vector<Constant*> operands;
      operands.push_back(ConstantFP::get(temp, 0));
      ArrayRef<Constant*> *arrayRef = new ArrayRef<Constant*>(operands);
      initializer = ConstantArray::get(atype, *arrayRef);

      newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, "");
    }
    else {
      initializer = ConstantFP::get(newType, 0);
      newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, "");
    }

    /*
    GlobalVariable* newTarget = new GlobalVariable(module, newType, false, GlobalValue::CommonLinkage, initializer, "");
    */

    unsigned alignment = getAlignment(newType);
    newTarget->setAlignment(alignment);

    newTarget->takeName(oldTarget);
    
    // iterating through instructions using old AllocaInst
    Value::use_iterator it = oldTarget->use_begin();
    for(; it != oldTarget->use_end(); it++) {
      Transformer::transform(it, newTarget, oldTarget, newType, oldType, alignment);
    }	  
    //oldTarget->eraseFromParent();
  }
  else {
    errs() << "No changes required.\n";
  }
  return;
}
bool XCoreLowerThreadLocal::lowerGlobal(GlobalVariable *GV) {
  Module *M = GV->getParent();
  LLVMContext &Ctx = M->getContext();
  if (!GV->isThreadLocal())
    return false;

  // Skip globals that we can't lower and leave it for the backend to error.
  if (!rewriteNonInstructionUses(GV, this) ||
      !GV->getType()->isSized() || isZeroLengthArray(GV->getType()))
    return false;

  // Create replacement global.
  ArrayType *NewType = createLoweredType(GV->getType()->getElementType());
  Constant *NewInitializer = nullptr;
  if (GV->hasInitializer())
    NewInitializer = createLoweredInitializer(NewType,
                                              GV->getInitializer());
  GlobalVariable *NewGV =
    new GlobalVariable(*M, NewType, GV->isConstant(), GV->getLinkage(),
                       NewInitializer, "", nullptr,
                       GlobalVariable::NotThreadLocal,
                       GV->getType()->getAddressSpace(),
                       GV->isExternallyInitialized());

  // Update uses.
  SmallVector<User *, 16> Users(GV->user_begin(), GV->user_end());
  for (unsigned I = 0, E = Users.size(); I != E; ++I) {
    User *U = Users[I];
    Instruction *Inst = cast<Instruction>(U);
    IRBuilder<> Builder(Inst);
    Function *GetID = Intrinsic::getDeclaration(GV->getParent(),
                                                Intrinsic::xcore_getid);
    Value *ThreadID = Builder.CreateCall(GetID);
    SmallVector<Value *, 2> Indices;
    Indices.push_back(Constant::getNullValue(Type::getInt64Ty(Ctx)));
    Indices.push_back(ThreadID);
    Value *Addr =
        Builder.CreateInBoundsGEP(NewGV->getValueType(), NewGV, Indices);
    U->replaceUsesOfWith(GV, Addr);
  }

  // Remove old global.
  NewGV->takeName(GV);
  GV->eraseFromParent();
  return true;
}
// This function replaces all global variables with new variables that have
// trailing redzones. It also creates a function that poisons
// redzones and inserts this function into llvm.global_ctors.
bool AddressSanitizer::insertGlobalRedzones(Module &M) {
  SmallVector<GlobalVariable *, 16> GlobalsToChange;

  for (Module::GlobalListType::iterator G = M.global_begin(),
       E = M.global_end(); G != E; ++G) {
    if (ShouldInstrumentGlobal(G))
      GlobalsToChange.push_back(G);
  }

  size_t n = GlobalsToChange.size();
  if (n == 0) return false;

  // A global is described by a structure
  //   size_t beg;
  //   size_t size;
  //   size_t size_with_redzone;
  //   const char *name;
  //   size_t has_dynamic_init;
  // We initialize an array of such structures and pass it to a run-time call.
  StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy,
                                               IntptrTy, IntptrTy,
                                               IntptrTy, NULL);
  SmallVector<Constant *, 16> Initializers(n), DynamicInit;

  IRBuilder<> IRB(CtorInsertBefore);

  if (ClInitializers)
    FindDynamicInitializers(M);

  // The addresses of the first and last dynamically initialized globals in
  // this TU.  Used in initialization order checking.
  Value *FirstDynamic = 0, *LastDynamic = 0;

  for (size_t i = 0; i < n; i++) {
    GlobalVariable *G = GlobalsToChange[i];
    PointerType *PtrTy = cast<PointerType>(G->getType());
    Type *Ty = PtrTy->getElementType();
    uint64_t SizeInBytes = TD->getTypeAllocSize(Ty);
    uint64_t RightRedzoneSize = RedzoneSize +
        (RedzoneSize - (SizeInBytes % RedzoneSize));
    Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);
    // Determine whether this global should be poisoned in initialization.
    bool GlobalHasDynamicInitializer = HasDynamicInitializer(G);
    // Don't check initialization order if this global is blacklisted.
    GlobalHasDynamicInitializer &= !BL->isInInit(*G);

    StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL);
    Constant *NewInitializer = ConstantStruct::get(
        NewTy, G->getInitializer(),
        Constant::getNullValue(RightRedZoneTy), NULL);

    SmallString<2048> DescriptionOfGlobal = G->getName();
    DescriptionOfGlobal += " (";
    DescriptionOfGlobal += M.getModuleIdentifier();
    DescriptionOfGlobal += ")";
    GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal);

    // Create a new global variable with enough space for a redzone.
    GlobalVariable *NewGlobal = new GlobalVariable(
        M, NewTy, G->isConstant(), G->getLinkage(),
        NewInitializer, "", G, G->getThreadLocalMode());
    NewGlobal->copyAttributesFrom(G);
    NewGlobal->setAlignment(RedzoneSize);

    Value *Indices2[2];
    Indices2[0] = IRB.getInt32(0);
    Indices2[1] = IRB.getInt32(0);

    G->replaceAllUsesWith(
        ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
    NewGlobal->takeName(G);
    G->eraseFromParent();

    Initializers[i] = ConstantStruct::get(
        GlobalStructTy,
        ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
        ConstantInt::get(IntptrTy, SizeInBytes),
        ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
        ConstantExpr::getPointerCast(Name, IntptrTy),
        ConstantInt::get(IntptrTy, GlobalHasDynamicInitializer),
        NULL);

    // Populate the first and last globals declared in this TU.
    if (ClInitializers && GlobalHasDynamicInitializer) {
      LastDynamic = ConstantExpr::getPointerCast(NewGlobal, IntptrTy);
      if (FirstDynamic == 0)
        FirstDynamic = LastDynamic;
    }

    DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal);
  }

  ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
  GlobalVariable *AllGlobals = new GlobalVariable(
      M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage,
      ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");

  // Create calls for poisoning before initializers run and unpoisoning after.
  if (ClInitializers && FirstDynamic && LastDynamic)
    createInitializerPoisonCalls(M, FirstDynamic, LastDynamic);

  Function *AsanRegisterGlobals = checkInterfaceFunction(M.getOrInsertFunction(
      kAsanRegisterGlobalsName, IRB.getVoidTy(),
      IntptrTy, IntptrTy, NULL));
  AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);

  IRB.CreateCall2(AsanRegisterGlobals,
                  IRB.CreatePointerCast(AllGlobals, IntptrTy),
                  ConstantInt::get(IntptrTy, n));

  // We also need to unregister globals at the end, e.g. when a shared library
  // gets closed.
  Function *AsanDtorFunction = Function::Create(
      FunctionType::get(Type::getVoidTy(*C), false),
      GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
  BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
  IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
  Function *AsanUnregisterGlobals =
      checkInterfaceFunction(M.getOrInsertFunction(
          kAsanUnregisterGlobalsName,
          IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
  AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);

  IRB_Dtor.CreateCall2(AsanUnregisterGlobals,
                       IRB.CreatePointerCast(AllGlobals, IntptrTy),
                       ConstantInt::get(IntptrTy, n));
  appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority);

  DEBUG(dbgs() << M);
  return true;
}
Exemple #5
0
// This function replaces all global variables with new variables that have
// trailing redzones. It also creates a function that poisons
// redzones and inserts this function into llvm.global_ctors.
bool AddressSanitizer::insertGlobalRedzones(Module &M) {
  SmallVector<GlobalVariable *, 16> GlobalsToChange;

  for (Module::GlobalListType::iterator G = M.getGlobalList().begin(),
       E = M.getGlobalList().end(); G != E; ++G) {
    Type *Ty = cast<PointerType>(G->getType())->getElementType();
    DEBUG(dbgs() << "GLOBAL: " << *G);

    if (!Ty->isSized()) continue;
    if (!G->hasInitializer()) continue;
    // Touch only those globals that will not be defined in other modules.
    // Don't handle ODR type linkages since other modules may be built w/o asan.
    if (G->getLinkage() != GlobalVariable::ExternalLinkage &&
        G->getLinkage() != GlobalVariable::PrivateLinkage &&
        G->getLinkage() != GlobalVariable::InternalLinkage)
      continue;
    // Two problems with thread-locals:
    //   - The address of the main thread's copy can't be computed at link-time.
    //   - Need to poison all copies, not just the main thread's one.
    if (G->isThreadLocal())
      continue;
    // For now, just ignore this Alloca if the alignment is large.
    if (G->getAlignment() > RedzoneSize) continue;

    // Ignore all the globals with the names starting with "\01L_OBJC_".
    // Many of those are put into the .cstring section. The linker compresses
    // that section by removing the spare \0s after the string terminator, so
    // our redzones get broken.
    if ((G->getName().find("\01L_OBJC_") == 0) ||
        (G->getName().find("\01l_OBJC_") == 0)) {
      DEBUG(dbgs() << "Ignoring \\01L_OBJC_* global: " << *G);
      continue;
    }

    if (G->hasSection()) {
      StringRef Section(G->getSection());
      // Ignore the globals from the __OBJC section. The ObjC runtime assumes
      // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to
      // them.
      if ((Section.find("__OBJC,") == 0) ||
          (Section.find("__DATA, __objc_") == 0)) {
        DEBUG(dbgs() << "Ignoring ObjC runtime global: " << *G);
        continue;
      }
      // See http://code.google.com/p/address-sanitizer/issues/detail?id=32
      // Constant CFString instances are compiled in the following way:
      //  -- the string buffer is emitted into
      //     __TEXT,__cstring,cstring_literals
      //  -- the constant NSConstantString structure referencing that buffer
      //     is placed into __DATA,__cfstring
      // Therefore there's no point in placing redzones into __DATA,__cfstring.
      // Moreover, it causes the linker to crash on OS X 10.7
      if (Section.find("__DATA,__cfstring") == 0) {
        DEBUG(dbgs() << "Ignoring CFString: " << *G);
        continue;
      }
    }

    GlobalsToChange.push_back(G);
  }

  size_t n = GlobalsToChange.size();
  if (n == 0) return false;

  // A global is described by a structure
  //   size_t beg;
  //   size_t size;
  //   size_t size_with_redzone;
  //   const char *name;
  // We initialize an array of such structures and pass it to a run-time call.
  StructType *GlobalStructTy = StructType::get(IntptrTy, IntptrTy,
                                               IntptrTy, IntptrTy, NULL);
  SmallVector<Constant *, 16> Initializers(n);

  IRBuilder<> IRB(CtorInsertBefore);

  for (size_t i = 0; i < n; i++) {
    GlobalVariable *G = GlobalsToChange[i];
    PointerType *PtrTy = cast<PointerType>(G->getType());
    Type *Ty = PtrTy->getElementType();
    uint64_t SizeInBytes = TD->getTypeStoreSizeInBits(Ty) / 8;
    uint64_t RightRedzoneSize = RedzoneSize +
        (RedzoneSize - (SizeInBytes % RedzoneSize));
    Type *RightRedZoneTy = ArrayType::get(IRB.getInt8Ty(), RightRedzoneSize);

    StructType *NewTy = StructType::get(Ty, RightRedZoneTy, NULL);
    Constant *NewInitializer = ConstantStruct::get(
        NewTy, G->getInitializer(),
        Constant::getNullValue(RightRedZoneTy), NULL);

    SmallString<2048> DescriptionOfGlobal = G->getName();
    DescriptionOfGlobal += " (";
    DescriptionOfGlobal += M.getModuleIdentifier();
    DescriptionOfGlobal += ")";
    GlobalVariable *Name = createPrivateGlobalForString(M, DescriptionOfGlobal);

    // Create a new global variable with enough space for a redzone.
    GlobalVariable *NewGlobal = new GlobalVariable(
        M, NewTy, G->isConstant(), G->getLinkage(),
        NewInitializer, "", G, G->isThreadLocal());
    NewGlobal->copyAttributesFrom(G);
    NewGlobal->setAlignment(RedzoneSize);

    Value *Indices2[2];
    Indices2[0] = IRB.getInt32(0);
    Indices2[1] = IRB.getInt32(0);

    G->replaceAllUsesWith(
        ConstantExpr::getGetElementPtr(NewGlobal, Indices2, true));
    NewGlobal->takeName(G);
    G->eraseFromParent();

    Initializers[i] = ConstantStruct::get(
        GlobalStructTy,
        ConstantExpr::getPointerCast(NewGlobal, IntptrTy),
        ConstantInt::get(IntptrTy, SizeInBytes),
        ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
        ConstantExpr::getPointerCast(Name, IntptrTy),
        NULL);
    DEBUG(dbgs() << "NEW GLOBAL:\n" << *NewGlobal);
  }

  ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
  GlobalVariable *AllGlobals = new GlobalVariable(
      M, ArrayOfGlobalStructTy, false, GlobalVariable::PrivateLinkage,
      ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");

  Function *AsanRegisterGlobals = cast<Function>(M.getOrInsertFunction(
      kAsanRegisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
  AsanRegisterGlobals->setLinkage(Function::ExternalLinkage);

  IRB.CreateCall2(AsanRegisterGlobals,
                  IRB.CreatePointerCast(AllGlobals, IntptrTy),
                  ConstantInt::get(IntptrTy, n));

  // We also need to unregister globals at the end, e.g. when a shared library
  // gets closed.
  Function *AsanDtorFunction = Function::Create(
      FunctionType::get(Type::getVoidTy(*C), false),
      GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
  BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
  IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
  Function *AsanUnregisterGlobals = cast<Function>(M.getOrInsertFunction(
      kAsanUnregisterGlobalsName, IRB.getVoidTy(), IntptrTy, IntptrTy, NULL));
  AsanUnregisterGlobals->setLinkage(Function::ExternalLinkage);

  IRB_Dtor.CreateCall2(AsanUnregisterGlobals,
                       IRB.CreatePointerCast(AllGlobals, IntptrTy),
                       ConstantInt::get(IntptrTy, n));
  appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndCtorPriority);

  DEBUG(dbgs() << M);
  return true;
}
// make_decl_llvm - Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL
// should have static storage duration.  In other words, it should not be an
// automatic variable, including PARM_DECLs.
//
// There is, however, one exception: this function handles variables explicitly
// placed in a particular register by the user.
//
// This function corresponds to make_decl_rtl in varasm.c, and is implicitly
// called by DECL_LLVM if a decl doesn't have an LLVM set.
//
void make_decl_llvm(tree decl) {
#ifdef ENABLE_CHECKING
  // Check that we are not being given an automatic variable.
  // A weak alias has TREE_PUBLIC set but not the other bits.
  if (TREE_CODE(decl) == PARM_DECL || TREE_CODE(decl) == RESULT_DECL
      || (TREE_CODE(decl) == VAR_DECL && !TREE_STATIC(decl) &&
          !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) && !DECL_REGISTER(decl)))
    abort();
  // And that we were not given a type or a label.  */
  else if (TREE_CODE(decl) == TYPE_DECL || TREE_CODE(decl) == LABEL_DECL)
    abort ();
#endif
  
  // For a duplicate declaration, we can be called twice on the
  // same DECL node.  Don't discard the LLVM already made.
  if (DECL_LLVM_SET_P(decl)) return;

  if (errorcount || sorrycount)
    return;  // Do not process broken code.
  
  
  // Global register variable with asm name, e.g.:
  // register unsigned long esp __asm__("ebp");
  if (TREE_CODE(decl) != FUNCTION_DECL && DECL_REGISTER(decl)) {
    // This  just verifies that the variable is ok.  The actual "load/store"
    // code paths handle accesses to the variable.
    ValidateRegisterVariable(decl);
    return;
  }
  
  timevar_push(TV_LLVM_GLOBALS);

  const char *Name = "";
  if (DECL_NAME(decl))
    if (tree AssemblerName = DECL_ASSEMBLER_NAME(decl))
      Name = IDENTIFIER_POINTER(AssemblerName);
  
  // Now handle ordinary static variables and functions (in memory).
  // Also handle vars declared register invalidly.
  if (Name[0] == 1) {
#ifdef REGISTER_PREFIX
    if (strlen (REGISTER_PREFIX) != 0) {
      int reg_number = decode_reg_name(Name);
      if (reg_number >= 0 || reg_number == -3)
        error("%Jregister name given for non-register variable %qD",
              decl, decl);
    }
#endif
  }
  
  // Specifying a section attribute on a variable forces it into a
  // non-.bss section, and thus it cannot be common.
  if (TREE_CODE(decl) == VAR_DECL && DECL_SECTION_NAME(decl) != NULL_TREE &&
      DECL_INITIAL(decl) == NULL_TREE && DECL_COMMON(decl))
    DECL_COMMON(decl) = 0;
  
  // Variables can't be both common and weak.
  if (TREE_CODE(decl) == VAR_DECL && DECL_WEAK(decl))
    DECL_COMMON(decl) = 0;
  
  // Okay, now we need to create an LLVM global variable or function for this
  // object.  Note that this is quite possibly a forward reference to the
  // object, so its type may change later.
  if (TREE_CODE(decl) == FUNCTION_DECL) {
    assert(Name[0] && "Function with empty name!");
    // If this function has already been created, reuse the decl.  This happens
    // when we have something like __builtin_memset and memset in the same file.
    Function *FnEntry = TheModule->getFunction(Name);
    if (FnEntry == 0) {
      unsigned CC;
      const FunctionType *Ty = 
        TheTypeConverter->ConvertFunctionType(TREE_TYPE(decl), decl, NULL, CC);
      FnEntry = new Function(Ty, Function::ExternalLinkage, Name, TheModule);
      FnEntry->setCallingConv(CC);

      // Check for external weak linkage
      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
        FnEntry->setLinkage(Function::ExternalWeakLinkage);
      
#ifdef TARGET_ADJUST_LLVM_LINKAGE
      TARGET_ADJUST_LLVM_LINKAGE(FnEntry,decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

      // Handle visibility style
      if (TREE_PUBLIC(decl)) {
        if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
          FnEntry->setVisibility(GlobalValue::HiddenVisibility);
        else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
          FnEntry->setVisibility(GlobalValue::ProtectedVisibility);
      }

      assert(FnEntry->getName() == Name &&"Preexisting fn with the same name!");
    }
    SET_DECL_LLVM(decl, FnEntry);
  } else {
    assert((TREE_CODE(decl) == VAR_DECL ||
            TREE_CODE(decl) == CONST_DECL) && "Not a function or var decl?");
    const Type *Ty = ConvertType(TREE_TYPE(decl));
    GlobalVariable *GV ;

    // If we have "extern void foo", make the global have type {} instead of
    // type void.
    if (Ty == Type::VoidTy) 
      Ty = StructType::get(std::vector<const Type*>(), false);
    
    if (Name[0] == 0) {   // Global has no name.
      GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0,
                              "", TheModule);

      // Check for external weak linkage
      if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
        GV->setLinkage(GlobalValue::ExternalWeakLinkage);
      
#ifdef TARGET_ADJUST_LLVM_LINKAGE
      TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

      // Handle visibility style
      if (TREE_PUBLIC(decl)) {
        if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
          GV->setVisibility(GlobalValue::HiddenVisibility);
        else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
          GV->setVisibility(GlobalValue::ProtectedVisibility);
      }

    } else {
      // If the global has a name, prevent multiple vars with the same name from
      // being created.
      GlobalVariable *GVE = TheModule->getGlobalVariable(Name);
    
      if (GVE == 0) {
        GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage,0,
                                Name, TheModule);

        // Check for external weak linkage
        if (DECL_EXTERNAL(decl) && DECL_WEAK(decl))
          GV->setLinkage(GlobalValue::ExternalWeakLinkage);
        
#ifdef TARGET_ADJUST_LLVM_LINKAGE
        TARGET_ADJUST_LLVM_LINKAGE(GV,decl);
#endif /* TARGET_ADJUST_LLVM_LINKAGE */

        // Handle visibility style
        if (TREE_PUBLIC(decl)) {
          if (DECL_VISIBILITY(decl) == VISIBILITY_HIDDEN)
            GV->setVisibility(GlobalValue::HiddenVisibility);
          else if (DECL_VISIBILITY(decl) == VISIBILITY_PROTECTED)
            GV->setVisibility(GlobalValue::ProtectedVisibility);
        }

        // If GV got renamed, then there is already an object with this name in
        // the symbol table.  If this happens, the old one must be a forward
        // decl, just replace it with a cast of the new one.
        if (GV->getName() != Name) {
          Function *F = TheModule->getFunction(Name);
          assert(F && F->isDeclaration() && "A function turned into a global?");
          
          // Replace any uses of "F" with uses of GV.
          Value *FInNewType = ConstantExpr::getBitCast(GV, F->getType());
          F->replaceAllUsesWith(FInNewType);
          
          // Update the decl that points to F.
          changeLLVMValue(F, FInNewType);

          // Now we can give GV the proper name.
          GV->takeName(F);
          
          // F is now dead, nuke it.
          F->eraseFromParent();
        }
        
      } else {
        GV = GVE;  // Global already created, reuse it.
      }
    }
    
    if ((TREE_READONLY(decl) && !TREE_SIDE_EFFECTS(decl)) || 
        TREE_CODE(decl) == CONST_DECL) {
      if (DECL_EXTERNAL(decl)) {
        // Mark external globals constant even though they could be marked
        // non-constant in the defining translation unit.  The definition of the
        // global determines whether the global is ultimately constant or not,
        // marking this constant will allow us to do some extra (legal)
        // optimizations that we would otherwise not be able to do.  (In C++,
        // any global that is 'C++ const' may not be readonly: it could have a
        // dynamic initializer.
        //
        GV->setConstant(true);
      } else {
        // Mark readonly globals with constant initializers constant.
        if (DECL_INITIAL(decl) != error_mark_node && // uninitialized?
            DECL_INITIAL(decl) &&
            (TREE_CONSTANT(DECL_INITIAL(decl)) ||
             TREE_CODE(DECL_INITIAL(decl)) == STRING_CST))
          GV->setConstant(true);
      }
    }

    // Set thread local (TLS)
    if (TREE_CODE(decl) == VAR_DECL && DECL_THREAD_LOCAL(decl))
      GV->setThreadLocal(true);

    SET_DECL_LLVM(decl, GV);
  }
  timevar_pop(TV_LLVM_GLOBALS);
}