diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index ca79d9dcaf8..ff41338ce9f 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -497,32 +497,21 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) {
       EmitGlobalConstant(CP->getOperand(I), GblS);
     return;
   } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
-    switch (CE->getOpcode()) {
-    case Instruction::BitCast: {
-      EmitGlobalConstant(CE->getOperand(0), GblS);
-      return;
-    }
-    case Instruction::GetElementPtr: {
-      const Constant *ptrVal = CE->getOperand(0);
-      SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
-      int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
-                                            idxVec.size());
-      EmitGlobalDataRelocation(cast<const GlobalValue>(ptrVal), 
-                               TD->getTypeAllocSize(ptrVal->getType()), 
-                               GblS, Offset);
-      return;
-    }
-    case Instruction::IntToPtr: {
-      Constant *Op = CE->getOperand(0);
-      Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(), false/*ZExt*/);
+    // Resolve a constant expression which returns a (Constant, Offset)
+    // pair. If 'Res.first' is a GlobalValue, emit a relocation with 
+    // the offset 'Res.second', otherwise emit a global constant like
+    // it is always done for not contant expression types.
+    CstExprResTy Res = ResolveConstantExpr(CE);
+    const Constant *Op = Res.first;
+
+    if (isa<GlobalValue>(Op))
+      EmitGlobalDataRelocation(cast<const GlobalValue>(Op), 
+                               TD->getTypeAllocSize(Op->getType()), 
+                               GblS, Res.second);
+    else
       EmitGlobalConstant(Op, GblS);
-      return;
-    }
-    }
-    std::string msg(CE->getOpcodeName());
-    raw_string_ostream ErrorMsg(msg);
-    ErrorMsg << ": Unsupported ConstantExpr type";
-    llvm_report_error(ErrorMsg.str());
+
+    return;
   } else if (CV->getType()->getTypeID() == Type::PointerTyID) {
     // Fill the data entry with zeros or emit a relocation entry
     if (isa<ConstantPointerNull>(CV))
@@ -544,8 +533,77 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) {
   llvm_report_error(ErrorMsg.str());
 }
 
+// ResolveConstantExpr - Resolve the constant expression until it stop
+// yielding other constant expressions.
+CstExprResTy ELFWriter::ResolveConstantExpr(const Constant *CV) {
+  const TargetData *TD = TM.getTargetData();
+  
+  // There ins't constant expression inside others anymore
+  if (!isa<ConstantExpr>(CV))
+    return std::make_pair(CV, 0);
+
+  const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
+  switch (CE->getOpcode()) {
+  case Instruction::BitCast:
+    return ResolveConstantExpr(CE->getOperand(0));
+  
+  case Instruction::GetElementPtr: {
+    const Constant *ptrVal = CE->getOperand(0);
+    SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
+    int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
+                                          idxVec.size());
+    return std::make_pair(ptrVal, Offset);
+  }
+  case Instruction::IntToPtr: {
+    Constant *Op = CE->getOperand(0);
+    Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(), false/*ZExt*/);
+    return ResolveConstantExpr(Op);
+  }
+  case Instruction::PtrToInt: {
+    Constant *Op = CE->getOperand(0);
+    const Type *Ty = CE->getType();
+
+    // We can emit the pointer value into this slot if the slot is an
+    // integer slot greater or equal to the size of the pointer.
+    if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType()))
+      return ResolveConstantExpr(Op);
+
+    llvm_unreachable("Integer size less then pointer size");
+  }
+  case Instruction::Add:
+  case Instruction::Sub: {
+    // Only handle cases where there's a constant expression with GlobalValue
+    // as first operand and ConstantInt as second, which are the cases we can
+    // solve direclty using a relocation entry. GlobalValue=Op0, CstInt=Op1
+    // 1)  Instruction::Add  => (global) + CstInt
+    // 2)  Instruction::Sub  => (global) + -CstInt
+    const Constant *Op0 = CE->getOperand(0); 
+    const Constant *Op1 = CE->getOperand(1); 
+    assert(isa<ConstantInt>(Op1) && "Op1 must be a ConstantInt");
+
+    CstExprResTy Res = ResolveConstantExpr(Op0);
+    assert(isa<GlobalValue>(Res.first) && "Op0 must be a GlobalValue");
+
+    const APInt &RHS = cast<ConstantInt>(Op1)->getValue();
+    switch (CE->getOpcode()) {
+    case Instruction::Add: 
+      return std::make_pair(Res.first, RHS.getSExtValue());
+    case Instruction::Sub:
+      return std::make_pair(Res.first, (-RHS).getSExtValue());
+    }
+  }
+  }
+
+  std::string msg(CE->getOpcodeName());
+  raw_string_ostream ErrorMsg(msg);
+  ErrorMsg << ": Unsupported ConstantExpr type";
+  llvm_report_error(ErrorMsg.str());
+
+  return std::make_pair(CV, 0); // silence warning
+}
+
 void ELFWriter::EmitGlobalDataRelocation(const GlobalValue *GV, unsigned Size,
-                                         ELFSection &GblS, uint64_t Offset) {
+                                         ELFSection &GblS, int64_t Offset) {
   // Create the relocation entry for the global value
   MachineRelocation MR =
     MachineRelocation::getGV(GblS.getCurrentPCOffset(),
@@ -868,7 +926,6 @@ void ELFWriter::EmitStringTable(const std::string &ModuleName) {
 
     std::string Name;
     if (Sym.isGlobalValue())
-      // Use the name mangler to uniquify the LLVM symbol.
       Name.append(Mang->getMangledName(Sym.getGlobalValue()));
     else if (Sym.isExternalSym())
       Name.append(Sym.getExternalSymbol());
diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h
index 362c278472d..ae14313db6a 100644
--- a/lib/CodeGen/ELFWriter.h
+++ b/lib/CodeGen/ELFWriter.h
@@ -43,6 +43,7 @@ namespace llvm {
   typedef std::vector<ELFSection*>::iterator ELFSectionIter;
   typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter;
   typedef SetVector<const char *>::const_iterator PendingExtsIter;
+  typedef std::pair<const Constant *, int64_t> CstExprResTy;
 
   /// ELFWriter - This class implements the common target-independent code for
   /// writing ELF files.  Targets should derive a class from this to
@@ -251,7 +252,7 @@ namespace llvm {
                                   ELFSection &GblS);
     void EmitGlobalConstantLargeInt(const ConstantInt *CI, ELFSection &S);
     void EmitGlobalDataRelocation(const GlobalValue *GV, unsigned Size, 
-                                  ELFSection &GblS, uint64_t Offset = 0);
+                                  ELFSection &GblS, int64_t Offset = 0);
     bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
     void EmitXXStructorList(Constant *List, ELFSection &Xtor);
     void EmitRelocations();
@@ -265,6 +266,7 @@ namespace llvm {
     void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value,
                        unsigned Size);
     unsigned SortSymbols();
+    CstExprResTy ResolveConstantExpr(const Constant *CV);
   };
 }