[llvm-branch-commits] [lldb] r183468 - Update platform branch with top of tree.

Greg Clayton gclayton at apple.com
Thu Jun 6 17:08:11 PDT 2013


Modified: lldb/branches/lldb-platform-work/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/IRForTarget.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Expression/IRForTarget.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/IRForTarget.cpp Thu Jun  6 19:06:43 2013
@@ -10,22 +10,26 @@
 #include "lldb/Expression/IRForTarget.h"
 
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Constants.h"
-#include "llvm/InstrTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Module.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/ValueSymbolTable.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/IR/ValueSymbolTable.h"
 
 #include "clang/AST/ASTContext.h"
 
-#include "lldb/Core/ConstString.h"
 #include "lldb/Core/dwarf.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRInterpreter.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -36,32 +40,42 @@ using namespace llvm;
 
 static char ID;
 
-IRForTarget::StaticDataAllocator::StaticDataAllocator()
+IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
+    m_execution_unit(execution_unit),
+    m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()),
+    m_allocation(LLDB_INVALID_ADDRESS)
 {
 }
 
-IRForTarget::StaticDataAllocator::~StaticDataAllocator()
+lldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
 {
+    lldb_private::Error err;
+    
+    if (m_allocation != LLDB_INVALID_ADDRESS)
+    {
+        m_execution_unit.FreeNow(m_allocation);
+        m_allocation = LLDB_INVALID_ADDRESS;
+    }
+    
+    m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
+
+    return m_allocation;
 }
 
 IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
                           bool resolve_vars,
-                          lldb_private::ExecutionPolicy execution_policy,
-                          lldb::ClangExpressionVariableSP &const_result,
-                          StaticDataAllocator *data_allocator,
+                          lldb_private::IRExecutionUnit &execution_unit,
                           lldb_private::Stream *error_stream,
                           const char *func_name) :
     ModulePass(ID),
     m_resolve_vars(resolve_vars),
-    m_execution_policy(execution_policy),
-    m_interpret_success(false),
     m_func_name(func_name),
     m_module(NULL),
     m_decl_map(decl_map),
-    m_data_allocator(data_allocator),
+    m_data_allocator(execution_unit),
+    m_memory_map(execution_unit),
     m_CFStringCreateWithBytes(NULL),
     m_sel_registerName(NULL),
-    m_const_result(const_result),
     m_error_stream(error_stream),
     m_has_side_effects(false),
     m_result_store(NULL),
@@ -76,11 +90,14 @@ static std::string
 PrintValue(const Value *value, bool truncate = false)
 {
     std::string s;
-    raw_string_ostream rso(s);
-    value->print(rso);
-    rso.flush();
-    if (truncate)
-        s.resize(s.length() - 1);
+    if (value)
+    {
+        raw_string_ostream rso(s);
+        value->print(rso);
+        rso.flush();
+        if (truncate)
+            s.resize(s.length() - 1);
+    }
     return s;
 }
 
@@ -103,8 +120,6 @@ IRForTarget::~IRForTarget()
 bool
 IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
     llvm_function.setLinkage(GlobalValue::ExternalLinkage);
     
     std::string name = llvm_function.getName().str();
@@ -179,7 +194,7 @@ IRForTarget::GetFunctionAddress (llvm::F
                                  lldb_private::ConstString &name,
                                  Constant **&value_ptr)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     fun_addr = LLDB_INVALID_ADDRESS;
     name.Clear();
@@ -236,7 +251,7 @@ IRForTarget::GetFunctionAddress (llvm::F
                 // Check for an alternate mangling for "std::basic_string<char>"
                 // that is part of the itanium C++ name mangling scheme
                 const char *name_cstr = name.GetCString();
-                if (strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0)
+                if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0)
                 {
                     std::string alternate_mangling("_ZNKSs");
                     alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE"));
@@ -266,6 +281,10 @@ IRForTarget::GetFunctionAddress (llvm::F
                         m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n",
                                                mangled_name.GetName().GetCString(),
                                                alt_mangled_name.GetName().GetCString());
+                    else if (mangled_name.GetMangledName())
+                        m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n",
+                                               mangled_name.GetName().GetCString(),
+                                               mangled_name.GetMangledName().GetCString());
                     else
                         m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
                                                mangled_name.GetName().GetCString());
@@ -289,7 +308,7 @@ IRForTarget::GetFunctionAddress (llvm::F
     }
     
     if (log)
-        log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), fun_addr);
+        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
     
     return true;
 }
@@ -310,8 +329,6 @@ IRForTarget::RegisterFunctionMetadata(LL
                                       llvm::Value *function_ptr, 
                                       const char *name)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
     for (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end();
          i != e;
          ++i)
@@ -320,12 +337,10 @@ IRForTarget::RegisterFunctionMetadata(LL
                 
         if (Instruction *user_inst = dyn_cast<Instruction>(user))
         {
-            Constant *name_array = ConstantDataArray::getString(context, StringRef(name));
-            
-            ArrayRef<Value *> md_values(name_array);
-            
-            MDNode *metadata = MDNode::get(context, md_values);
-            
+            MDString* md_name = MDString::get(context, StringRef(name));
+
+            MDNode *metadata = MDNode::get(context, md_name);
+
             user_inst->setMetadata("lldb.call.realName", metadata);
         }
         else
@@ -339,7 +354,7 @@ bool
 IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module,
                                      llvm::Function &llvm_function)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     for (llvm::Module::iterator fi = llvm_module.begin();
          fi != llvm_module.end();
@@ -385,8 +400,6 @@ IRForTarget::ResolveFunctionPointers(llv
 clang::NamedDecl *
 IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
     NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
     
     if (!named_metadata)
@@ -429,98 +442,10 @@ IRForTarget::DeclForGlobal (GlobalValue
     return DeclForGlobal(global_val, m_module);
 }
 
-void 
-IRForTarget::MaybeSetConstantResult (llvm::Constant *initializer,
-                                     const lldb_private::ConstString &name,
-                                     lldb_private::TypeFromParser type)
-{
-    if (llvm::ConstantExpr *init_expr = dyn_cast<llvm::ConstantExpr>(initializer))
-    {
-        switch (init_expr->getOpcode())
-        {
-        default:
-            return;
-        case Instruction::IntToPtr:
-            MaybeSetConstantResult (init_expr->getOperand(0), name, type);
-            return;
-        }
-    }
-    else if (llvm::ConstantInt *init_int = dyn_cast<llvm::ConstantInt>(initializer))
-    {
-        m_const_result = m_decl_map->BuildIntegerVariable(name, type, init_int->getValue());
-    }
-}
-
-void
-IRForTarget::MaybeSetCastResult (lldb_private::TypeFromParser type)
-{
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
-    if (!m_result_store)
-        return;
-    
-    LoadInst *original_load = NULL;
-        
-    for (llvm::Value *current_value = m_result_store->getValueOperand(), *next_value;
-         current_value != NULL;
-         current_value = next_value)
-    {
-        CastInst *cast_inst = dyn_cast<CastInst>(current_value);
-        LoadInst *load_inst = dyn_cast<LoadInst>(current_value);
-        
-        if (cast_inst)
-        {
-            next_value = cast_inst->getOperand(0);
-        }
-        else if (load_inst)
-        {
-            if (isa<LoadInst>(load_inst->getPointerOperand()))
-            {
-                next_value = load_inst->getPointerOperand();
-            }
-            else
-            {
-                original_load = load_inst;
-                break;
-            }
-        }
-        else
-        {
-            return;
-        }
-    }
-    
-    Value *loaded_value = original_load->getPointerOperand();
-    GlobalVariable *loaded_global = dyn_cast<GlobalVariable>(loaded_value);
-    
-    if (!loaded_global)
-        return;
-    
-    clang::NamedDecl *loaded_decl = DeclForGlobal(loaded_global);
-    
-    if (!loaded_decl)
-        return;
-    
-    clang::VarDecl *loaded_var = dyn_cast<clang::VarDecl>(loaded_decl);
-    
-    if (!loaded_var)
-        return;
-    
-    if (log)
-    {
-        lldb_private::StreamString type_desc_stream;
-        type.DumpTypeDescription(&type_desc_stream);
-        
-        log->Printf("Type to cast variable to: \"%s\"", type_desc_stream.GetString().c_str());
-    }
-    
-    m_const_result = m_decl_map->BuildCastVariable(m_result_name, loaded_var, type);
-}
-
 bool 
 IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (!m_resolve_vars)
         return true;
@@ -540,7 +465,7 @@ IRForTarget::CreateResultVariable (llvm:
         const char *value_name = result_name_str.c_str();
         
         if (strstr(value_name, "$__lldb_expr_result_ptr") &&
-            !strstr(value_name, "GV"))
+            strncmp(value_name, "_ZGV", 4))
         {
             result_name = value_name;
             m_result_is_pointer = true;
@@ -548,7 +473,7 @@ IRForTarget::CreateResultVariable (llvm:
         }
         
         if (strstr(value_name, "$__lldb_expr_result") &&
-            !strstr(value_name, "GV")) 
+            strncmp(value_name, "_ZGV", 4))
         {
             result_name = value_name;
             m_result_is_pointer = false;
@@ -696,10 +621,10 @@ IRForTarget::CreateResultVariable (llvm:
         log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
     }
     
-    m_result_name = m_decl_map->GetPersistentResultName();
+    m_result_name = lldb_private::ConstString("$RESULT_NAME");
     
     if (log)
-        log->Printf("Creating a new result global: \"%s\" with size 0x%x", 
+        log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
                     m_result_name.GetCString(),
                     m_result_type.GetClangTypeBitWidth() / 8);
         
@@ -788,22 +713,21 @@ IRForTarget::CreateResultVariable (llvm:
         
         result_global->replaceAllUsesWith(new_result_global);
     }
-    
-    if (!m_const_result)
-        if (!m_decl_map->AddPersistentVariable(result_decl, 
-                                               m_result_name, 
-                                               m_result_type,
-                                               true,
-                                               m_result_is_pointer))
-            return false;
         
+    if (!m_decl_map->AddPersistentVariable(result_decl,
+                                           m_result_name, 
+                                           m_result_type,
+                                           true,
+                                           m_result_is_pointer))
+        return false;
+    
     result_global->eraseFromParent();
     
     return true;
 }
 
 #if 0
-static void DebugUsers(lldb::LogSP &log, Value *value, uint8_t depth)
+static void DebugUsers(Log *log, Value *value, uint8_t depth)
 {    
     if (!depth)
         return;
@@ -832,13 +756,14 @@ IRForTarget::RewriteObjCConstString (llv
                                      llvm::GlobalVariable *cstr,
                                      Instruction *FirstEntryInstruction)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     Type *ns_str_ty = ns_str->getType();
     
     Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
-                                                   (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
+                                                   (m_module->getPointerSize()
+                                                    == Module::Pointer64) ? 64 : 32);
     Type *i32_ty = Type::getInt32Ty(m_module->getContext());
     Type *i8_ty = Type::getInt8Ty(m_module->getContext());
     
@@ -860,7 +785,7 @@ IRForTarget::RewriteObjCConstString (llv
         }
             
         if (log)
-            log->Printf("Found CFStringCreateWithBytes at 0x%llx", CFStringCreateWithBytes_addr);
+            log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
         
         // Build the function type:
         //
@@ -944,7 +869,7 @@ IRForTarget::RewriteObjCConstString (llv
 bool
 IRForTarget::RewriteObjCConstStrings(Function &llvm_function)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
     
@@ -1187,7 +1112,7 @@ static bool IsObjCSelectorRef (Value *va
 bool 
 IRForTarget::RewriteObjCSelector (Instruction* selector_load)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     LoadInst *load = dyn_cast<LoadInst>(selector_load);
     
@@ -1253,7 +1178,7 @@ IRForTarget::RewriteObjCSelector (Instru
             return false;
         
         if (log)
-            log->Printf("Found sel_registerName at 0x%llx", sel_registerName_addr);
+            log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
         
         // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
         
@@ -1303,7 +1228,7 @@ IRForTarget::RewriteObjCSelector (Instru
 bool
 IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     BasicBlock::iterator ii;
     
@@ -1348,7 +1273,7 @@ IRForTarget::RewriteObjCSelectors (Basic
 bool 
 IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
     
@@ -1419,7 +1344,7 @@ IRForTarget::RewritePersistentAllocs(llv
     if (!m_resolve_vars)
         return true;
     
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     BasicBlock::iterator ii;
     
@@ -1484,7 +1409,7 @@ IRForTarget::MaterializeInitializer (uin
     if (!initializer)
         return true;
     
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     if (log && log->GetVerbose())
         log->Printf("  MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());
@@ -1538,6 +1463,11 @@ IRForTarget::MaterializeInitializer (uin
         }
         return true;
     }
+    else if (isa<ConstantAggregateZero>(initializer))
+    {
+        memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
+        return true;
+    }
     return false;
 }
 
@@ -1550,7 +1480,7 @@ IRForTarget::MaterializeInternalVariable
     if (global_variable == m_reloc_placeholder)
         return true;
     
-    uint64_t offset = m_data_allocator->GetStream().GetSize();
+    uint64_t offset = m_data_allocator.GetStream().GetSize();
     
     llvm::Type *variable_type = global_variable->getType();
     
@@ -1563,7 +1493,7 @@ IRForTarget::MaterializeInternalVariable
     
     const size_t mask = (align - 1);
     uint64_t aligned_offset = (offset + mask) & ~mask;
-    m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+    m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
     offset = aligned_offset;
     
     lldb_private::DataBufferHeap data(size, '\0');
@@ -1572,7 +1502,7 @@ IRForTarget::MaterializeInternalVariable
         if (!MaterializeInitializer(data.GetBytes(), initializer))
             return false;
     
-    m_data_allocator->GetStream().Write(data.GetBytes(), data.GetByteSize());
+    m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
     
     Constant *new_pointer = BuildRelocation(variable_type, offset);
         
@@ -1587,7 +1517,7 @@ IRForTarget::MaterializeInternalVariable
 bool 
 IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (log)
         log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
@@ -1665,11 +1595,11 @@ IRForTarget::MaybeHandleVariable (Value
             value_type = global_variable->getType();
         }
                 
-        size_t value_size = (ast_context->getTypeSize(qual_type) + 7) / 8;
-        off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7) / 8;
+        uint64_t value_size = (ast_context->getTypeSize(qual_type) + 7ull) / 8ull;
+        off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7ull) / 8ull;
         
         if (log)
-            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %lu, align %lld]", 
+            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
                         name.c_str(), 
                         qual_type.getAsString().c_str(), 
                         PrintType(value_type).c_str(), 
@@ -1685,6 +1615,8 @@ IRForTarget::MaybeHandleVariable (Value
         {
             if (!global_variable->hasExternalLinkage())
                 return true;
+            else if (HandleSymbol (global_variable))
+                return true;
             else
                 return false;
         }
@@ -1704,7 +1636,7 @@ IRForTarget::MaybeHandleVariable (Value
 bool
 IRForTarget::HandleSymbol (Value *symbol)
 {    
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     lldb_private::ConstString name(symbol->getName().str().c_str());
     
@@ -1719,10 +1651,9 @@ IRForTarget::HandleSymbol (Value *symbol
     }
 
     if (log)
-        log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), symbol_addr);
+        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
     
     Type *symbol_type = symbol->getType();
-    
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                              (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
     
@@ -1741,7 +1672,7 @@ IRForTarget::HandleSymbol (Value *symbol
 bool
 IRForTarget::MaybeHandleCallArguments (CallInst *Old)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (log)
         log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
@@ -1763,7 +1694,7 @@ IRForTarget::MaybeHandleCallArguments (C
 bool
 IRForTarget::HandleObjCClass(Value *classlist_reference)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
     
@@ -1791,28 +1722,33 @@ IRForTarget::HandleObjCClass(Value *clas
     if (global_variable->use_begin() == global_variable->use_end())
         return false;
     
-    LoadInst *load_instruction = NULL;
-    
+    SmallVector<LoadInst *, 2> load_instructions;
+        
     for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end();
          i != e;
          ++i)
     {
-        if ((load_instruction = dyn_cast<LoadInst>(*i)))
-            break;
+        if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i))
+            load_instructions.push_back(load_instruction);
     }
     
-    if (!load_instruction)
+    if (load_instructions.empty())
         return false;
     
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
-                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
+                                             (m_module->getPointerSize()
+                                              == Module::Pointer64) ? 64 : 32);
     
     Constant *class_addr = ConstantInt::get(intptr_ty, (uint64_t)class_ptr);
-    Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
     
-    load_instruction->replaceAllUsesWith(class_bitcast);
+    for (LoadInst *load_instruction : load_instructions)
+    {
+        Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
     
-    load_instruction->eraseFromParent();
+        load_instruction->replaceAllUsesWith(class_bitcast);
+    
+        load_instruction->eraseFromParent();
+    }
     
     return true;
 }
@@ -1890,7 +1826,7 @@ IRForTarget::ResolveCalls(BasicBlock &ba
 bool
 IRForTarget::ResolveExternals (Function &llvm_function)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     for (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end();
          global != end;
@@ -1931,6 +1867,16 @@ IRForTarget::ResolveExternals (Function
                 return false;
             }
         }
+        else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
+        {
+            if (!HandleObjCClass(global))
+            {
+                if (m_error_stream)
+                    m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
+                
+                return false;
+            }
+        }
         else if (DeclForGlobal(global))
         {
             if (!MaybeHandleVariable (global))
@@ -1949,10 +1895,7 @@ IRForTarget::ResolveExternals (Function
 bool
 IRForTarget::ReplaceStrings ()
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
-    if (!m_data_allocator)
-        return true; // hope for the best; some clients may not want static allocation!
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     typedef std::map <GlobalVariable *, size_t> OffsetsTy;
     
@@ -2005,9 +1948,9 @@ IRForTarget::ReplaceStrings ()
             str = gc_array->getAsString();
         }
             
-        offsets[gv] = m_data_allocator->GetStream().GetSize();
+        offsets[gv] = m_data_allocator.GetStream().GetSize();
         
-        m_data_allocator->GetStream().Write(str.c_str(), str.length() + 1);
+        m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
     }
     
     Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
@@ -2073,10 +2016,7 @@ IRForTarget::ReplaceStrings ()
 bool 
 IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-        
-    if (!m_data_allocator)
-        return true;
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     typedef SmallVector <Value*, 2> ConstantList;
     typedef SmallVector <llvm::Instruction*, 2> UserList;
@@ -2119,10 +2059,11 @@ IRForTarget::ReplaceStaticLiterals (llvm
         llvm::Instruction *inst = *user_iter;
 
         ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
-        Type *operand_type = operand_constant_fp->getType();
         
         if (operand_constant_fp)
         {
+            Type *operand_type = operand_constant_fp->getType();
+
             APFloat operand_apfloat = operand_constant_fp->getValueAPF();
             APInt operand_apint = operand_apfloat.bitcastToAPInt();
             
@@ -2147,7 +2088,7 @@ IRForTarget::ReplaceStaticLiterals (llvm
             
             lldb_private::DataBufferHeap data(operand_data_size, 0);
             
-            if (lldb::endian::InlHostByteOrder() != m_data_allocator->GetStream().GetByteOrder())
+            if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
             {
                 uint8_t *data_bytes = data.GetBytes();
                 
@@ -2163,20 +2104,20 @@ IRForTarget::ReplaceStaticLiterals (llvm
                 memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
             }
             
-            uint64_t offset = m_data_allocator->GetStream().GetSize();
+            uint64_t offset = m_data_allocator.GetStream().GetSize();
             
             size_t align = m_target_data->getPrefTypeAlignment(operand_type);
             
             const size_t mask = (align - 1);
             uint64_t aligned_offset = (offset + mask) & ~mask;
-            m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+            m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
             offset = aligned_offset;
             
-            m_data_allocator->GetStream().Write(data.GetBytes(), operand_data_size);
+            m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
             
             llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
             
-            Constant *new_pointer = BuildRelocation(fp_ptr_ty, offset);
+            Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset);
             
             llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst);
             
@@ -2290,7 +2231,7 @@ IRForTarget::RemoveGuards(BasicBlock &ba
 bool
 IRForTarget::UnfoldConstant(Constant *old_constant, Value *new_constant, Instruction *first_entry_inst)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     Value::use_iterator ui;
     
@@ -2396,7 +2337,7 @@ IRForTarget::ReplaceVariables (Function
     if (!m_resolve_vars)
         return true;
     
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
     m_decl_map->DoStructLayout();
     
@@ -2520,7 +2461,7 @@ IRForTarget::ReplaceVariables (Function
         }
             
         if (log)
-            log->Printf("  \"%s\" (\"%s\") placed at %lld",
+            log->Printf("  \"%s\" (\"%s\") placed at %" PRId64,
                         name.GetCString(),
                         decl->getNameAsString().c_str(),
                         offset);
@@ -2564,17 +2505,14 @@ IRForTarget::ReplaceVariables (Function
     }
     
     if (log)
-        log->Printf("Total structure [align %lld, size %lu]", alignment, size);
+        log->Printf("Total structure [align %" PRId64 ", size %lu]", alignment, size);
     
     return true;
 }
 
 llvm::Constant *
-IRForTarget::BuildRelocation(llvm::Type *type, 
-                             uint64_t offset)
+IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
                                              (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
     
@@ -2594,16 +2532,13 @@ IRForTarget::BuildRelocation(llvm::Type
 
 bool 
 IRForTarget::CompleteDataAllocation ()
-{
-    if (!m_data_allocator)
-        return true;
-    
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+{    
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
-    if (!m_data_allocator->GetStream().GetSize())
+    if (!m_data_allocator.GetStream().GetSize())
         return true;
     
-    lldb::addr_t allocation = m_data_allocator->Allocate();
+    lldb::addr_t allocation = m_data_allocator.Allocate();
     
     if (log)
     {
@@ -2613,7 +2548,7 @@ IRForTarget::CompleteDataAllocation ()
             log->Printf("Failed to allocate static data");
     }
     
-    if (!allocation)
+    if (!allocation || allocation == LLDB_INVALID_ADDRESS)
         return false;
     
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
@@ -2630,12 +2565,62 @@ IRForTarget::CompleteDataAllocation ()
 }
 
 bool
+IRForTarget::StripAllGVs (Module &llvm_module)
+{
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    std::vector<GlobalVariable *> global_vars;
+    std::set<GlobalVariable *>erased_vars;
+    
+    bool erased = true;
+    
+    while (erased)
+    {
+        erased = false;
+        
+        for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
+             gi != ge;
+             ++gi)
+        {
+            GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
+        
+            global_var->removeDeadConstantUsers();
+            
+            if (global_var->use_empty())
+            {
+                if (log)
+                    log->Printf("Did remove %s",
+                                PrintValue(global_var).c_str());
+                global_var->eraseFromParent();
+                erased = true;
+                break;
+            }
+        }
+    }
+    
+    for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
+         gi != ge;
+         ++gi)
+    {
+        GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
+
+        GlobalValue::use_iterator ui = global_var->use_begin();
+        
+        if (log)
+            log->Printf("Couldn't remove %s because of %s",
+                        PrintValue(global_var).c_str(),
+                        PrintValue(*ui).c_str());
+    }
+    
+    return true;
+}
+
+bool
 IRForTarget::runOnModule (Module &llvm_module)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     m_module = &llvm_module;
-    m_target_data.reset(new TargetData(m_module));
+    m_target_data.reset(new DataLayout(m_module));
     
     Function* function = m_module->getFunction(StringRef(m_func_name.c_str()));
     
@@ -2674,12 +2659,12 @@ IRForTarget::runOnModule (Module &llvm_m
     
     m_reloc_placeholder = new llvm::GlobalVariable((*m_module), 
                                                    intptr_ty,
-                                                   false /* isConstant */,
+                                                   false /* IsConstant */,
                                                    GlobalVariable::InternalLinkage,
                                                    Constant::getNullValue(intptr_ty),
                                                    "reloc_placeholder",
                                                    NULL /* InsertBefore */,
-                                                   false /* ThreadLocal */,
+                                                   GlobalVariable::NotThreadLocal /* ThreadLocal */,
                                                    0 /* AddressSpace */);
         
     Function::iterator bbi;
@@ -2699,12 +2684,6 @@ IRForTarget::runOnModule (Module &llvm_m
         
         return false;
     }
-        
-    if (m_const_result && m_execution_policy != lldb_private::eExecutionPolicyAlways)
-    {
-        m_interpret_success = true;
-        return true;
-    }
     
     for (bbi = function->begin();
          bbi != function->end();
@@ -2741,23 +2720,6 @@ IRForTarget::runOnModule (Module &llvm_m
         }
     }
     
-    if (m_decl_map && m_execution_policy != lldb_private::eExecutionPolicyAlways)
-    {
-        IRInterpreter interpreter (*m_decl_map,
-                                   m_error_stream);
-
-        interpreter.maybeRunOnFunction(m_const_result, m_result_name, m_result_type, *function, llvm_module, m_interpreter_error);
-        
-        if (m_interpreter_error.Success())
-            return true;
-    }
-    
-    if (m_execution_policy == lldb_private::eExecutionPolicyNever) {
-        if (m_result_name)
-            m_decl_map->RemoveResultVariable(m_result_name);
-        return false;
-    }
-    
     if (log && log->GetVerbose())
     {
         std::string s;
@@ -2876,6 +2838,12 @@ IRForTarget::runOnModule (Module &llvm_m
         return false;
     }
     
+    if (!StripAllGVs(llvm_module))
+    {
+        if (log)
+            log->Printf("StripAllGVs() failed");
+    }
+    
     if (log && log->GetVerbose())
     {
         std::string s;

Modified: lldb/branches/lldb-platform-work/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/IRInterpreter.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Expression/IRInterpreter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/IRInterpreter.cpp Thu Jun  6 19:06:43 2013
@@ -7,38 +7,25 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/Core/DataEncoder.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
-#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Expression/ClangExpressionDeclMap.h"
-#include "lldb/Expression/ClangExpressionVariable.h"
-#include "lldb/Expression/IRForTarget.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Expression/IRMemoryMap.h"
 #include "lldb/Expression/IRInterpreter.h"
 
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetData.h"
 
 #include <map>
 
 using namespace llvm;
 
-IRInterpreter::IRInterpreter(lldb_private::ClangExpressionDeclMap &decl_map,
-                                           lldb_private::Stream *error_stream) :
-    m_decl_map(decl_map),
-    m_error_stream(error_stream)
-{
-    
-}
-
-IRInterpreter::~IRInterpreter()
-{
-    
-}
-
 static std::string 
 PrintValue(const Value *value, bool truncate = false)
 {
@@ -70,362 +57,42 @@ PrintType(const Type *type, bool truncat
     return s;
 }
 
-typedef STD_SHARED_PTR(lldb_private::DataEncoder) DataEncoderSP;
-typedef STD_SHARED_PTR(lldb_private::DataExtractor) DataExtractorSP;
-
-class Memory
-{
-public:
-    typedef uint32_t                    index_t;
-    
-    struct Allocation
-    {
-        // m_virtual_address is always the address of the variable in the virtual memory
-        // space provided by Memory.
-        //
-        // m_origin is always non-NULL and describes the source of the data (possibly
-        // m_data if this allocation is the authoritative source).
-        //
-        // Possible value configurations:
-        //
-        // Allocation type  getValueType()          getContextType()            m_origin->GetScalar()       m_data
-        // =========================================================================================================================
-        // FileAddress      eValueTypeFileAddress   eContextTypeInvalid         A location in a binary      NULL
-        //                                                                      image
-        //                                                      
-        // LoadAddress      eValueTypeLoadAddress   eContextTypeInvalid         A location in the target's  NULL
-        //                                                                      virtual memory
-        //
-        // Alloca           eValueTypeHostAddress   eContextTypeInvalid         == m_data->GetBytes()       Deleted at end of 
-        //                                                                                                  execution
-        //
-        // PersistentVar    eValueTypeHostAddress   eContextTypeClangType       A persistent variable's     NULL
-        //                                                                      location in LLDB's memory
-        //
-        // Register         [ignored]               eContextTypeRegister        [ignored]                   Flushed to the register
-        //                                                                                                  at the end of execution
-        
-        lldb::addr_t        m_virtual_address;
-        size_t              m_extent;
-        lldb_private::Value m_origin;
-        lldb::DataBufferSP  m_data;
-        
-        Allocation (lldb::addr_t virtual_address,
-                    size_t extent,
-                    lldb::DataBufferSP data) :
-            m_virtual_address(virtual_address),
-            m_extent(extent),
-            m_data(data)
-        {
-        }
-        
-        Allocation (const Allocation &allocation) :
-            m_virtual_address(allocation.m_virtual_address),
-            m_extent(allocation.m_extent),
-            m_origin(allocation.m_origin),
-            m_data(allocation.m_data)
-        {
-        }
-    };
-    
-    typedef STD_SHARED_PTR(Allocation)  AllocationSP;
-    
-    struct Region
-    {
-        AllocationSP m_allocation;
-        uint64_t m_base;
-        uint64_t m_extent;
-        
-        Region () :
-            m_allocation(),
-            m_base(0),
-            m_extent(0)
-        {
-        }
-        
-        Region (AllocationSP allocation, uint64_t base, uint64_t extent) :
-            m_allocation(allocation),
-            m_base(base),
-            m_extent(extent)
-        {
-        }
-        
-        Region (const Region &region) :
-            m_allocation(region.m_allocation),
-            m_base(region.m_base),
-            m_extent(region.m_extent)
-        {
-        }
-        
-        bool IsValid ()
-        {
-            return (bool) m_allocation;
-        }
-        
-        bool IsInvalid ()
-        {
-            return !m_allocation;
-        }
-    };
-    
-    typedef std::vector <AllocationSP>          MemoryMap;
-
-private:
-    lldb::addr_t        m_addr_base;
-    lldb::addr_t        m_addr_max;
-    MemoryMap           m_memory;
-    lldb::ByteOrder     m_byte_order;
-    lldb::addr_t        m_addr_byte_size;
-    TargetData         &m_target_data;
-    
-    lldb_private::ClangExpressionDeclMap   &m_decl_map;
-    
-    MemoryMap::iterator LookupInternal (lldb::addr_t addr)
-    {
-        for (MemoryMap::iterator i = m_memory.begin(), e = m_memory.end();
-             i != e;
-             ++i)
-        {
-            if ((*i)->m_virtual_address <= addr &&
-                (*i)->m_virtual_address + (*i)->m_extent > addr)
-                return i;
-        }
-        
-        return m_memory.end();
-    }
-    
-public:
-    Memory (TargetData &target_data,
-            lldb_private::ClangExpressionDeclMap &decl_map,
-            lldb::addr_t alloc_start,
-            lldb::addr_t alloc_max) :
-        m_addr_base(alloc_start),
-        m_addr_max(alloc_max),
-        m_target_data(target_data),
-        m_decl_map(decl_map)
-    {
-        m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
-        m_addr_byte_size = (target_data.getPointerSize());
-    }
-    
-    Region Malloc (size_t size, size_t align)
-    {
-        lldb::DataBufferSP data(new lldb_private::DataBufferHeap(size, 0));
-        
-        if (data)
-        {
-            index_t index = m_memory.size();
-            
-            const size_t mask = (align - 1);
-            
-            m_addr_base += mask;
-            m_addr_base &= ~mask;
-            
-            if (m_addr_base + size < m_addr_base ||
-                m_addr_base + size > m_addr_max)
-                return Region();
-            
-            uint64_t base = m_addr_base;
-                        
-            m_memory.push_back(AllocationSP(new Allocation(base, size, data)));
-            
-            m_addr_base += size;
-            
-            AllocationSP alloc = m_memory[index];
-            
-            alloc->m_origin.GetScalar() = (unsigned long long)data->GetBytes();
-            alloc->m_origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
-            alloc->m_origin.SetValueType(lldb_private::Value::eValueTypeHostAddress);
-            
-            return Region(alloc, base, size);
-        }
-        
-        return Region();
-    }
-    
-    Region Malloc (Type *type)
-    {
-        return Malloc (m_target_data.getTypeAllocSize(type),
-                       m_target_data.getPrefTypeAlignment(type));
-    }
-    
-    Region Place (Type *type, lldb::addr_t base, lldb_private::Value &value)
-    {
-        index_t index = m_memory.size();
-        size_t size = m_target_data.getTypeAllocSize(type);
-        
-        m_memory.push_back(AllocationSP(new Allocation(base, size, lldb::DataBufferSP())));
-        
-        AllocationSP alloc = m_memory[index];
-        
-        alloc->m_origin = value;
-        
-        return Region(alloc, base, size);
-    }
-    
-    void Free (lldb::addr_t addr)
-    {
-        MemoryMap::iterator i = LookupInternal (addr);
-        
-        if (i != m_memory.end())
-            m_memory.erase(i);
-    }
-    
-    Region Lookup (lldb::addr_t addr, Type *type)
-    {
-        MemoryMap::iterator i = LookupInternal(addr);
-        
-        if (i == m_memory.end() || !type->isSized())
-            return Region();
-    
-        size_t size = m_target_data.getTypeStoreSize(type);
-                
-        return Region(*i, addr, size);
-    }
-        
-    DataEncoderSP GetEncoder (Region region)
-    {
-        if (region.m_allocation->m_origin.GetValueType() != lldb_private::Value::eValueTypeHostAddress)
-            return DataEncoderSP();
-        
-        lldb::DataBufferSP buffer = region.m_allocation->m_data;
-        
-        if (!buffer)
-            return DataEncoderSP();
-        
-        size_t base_offset = (size_t)(region.m_base - region.m_allocation->m_virtual_address);
-                
-        return DataEncoderSP(new lldb_private::DataEncoder(buffer->GetBytes() + base_offset, region.m_extent, m_byte_order, m_addr_byte_size));
-    }
-    
-    DataExtractorSP GetExtractor (Region region)
-    {
-        if (region.m_allocation->m_origin.GetValueType() != lldb_private::Value::eValueTypeHostAddress)
-            return DataExtractorSP();
-        
-        lldb::DataBufferSP buffer = region.m_allocation->m_data;
-        size_t base_offset = (size_t)(region.m_base - region.m_allocation->m_virtual_address);
-
-        if (buffer)
-            return DataExtractorSP(new lldb_private::DataExtractor(buffer->GetBytes() + base_offset, region.m_extent, m_byte_order, m_addr_byte_size));
-        else
-            return DataExtractorSP(new lldb_private::DataExtractor((uint8_t*)region.m_allocation->m_origin.GetScalar().ULongLong() + base_offset, region.m_extent, m_byte_order, m_addr_byte_size));
-    }
-    
-    lldb_private::Value GetAccessTarget(lldb::addr_t addr)
-    {
-        MemoryMap::iterator i = LookupInternal(addr);
-        
-        if (i == m_memory.end())
-            return lldb_private::Value();
-        
-        lldb_private::Value target = (*i)->m_origin;
-        
-        if (target.GetContextType() == lldb_private::Value::eContextTypeRegisterInfo)
-        {
-            target.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
-            target.SetValueType(lldb_private::Value::eValueTypeHostAddress);
-            target.GetScalar() = (unsigned long long)(*i)->m_data->GetBytes();
-        }
-        
-        target.GetScalar() += (addr - (*i)->m_virtual_address);
-        
-        return target;
-    }
-    
-    bool Write (lldb::addr_t addr, const uint8_t *data, size_t length)
-    {
-        lldb_private::Value target = GetAccessTarget(addr);
-        
-        return m_decl_map.WriteTarget(target, data, length);
-    }
-    
-    bool Read (uint8_t *data, lldb::addr_t addr, size_t length)
-    {
-        lldb_private::Value source = GetAccessTarget(addr);
-        
-        return m_decl_map.ReadTarget(data, source, length);
-    }
-    
-    bool WriteToRawPtr (lldb::addr_t addr, const uint8_t *data, size_t length)
-    {
-        lldb_private::Value target = m_decl_map.WrapBareAddress(addr);
-        
-        return m_decl_map.WriteTarget(target, data, length);
-    }
-    
-    bool ReadFromRawPtr (uint8_t *data, lldb::addr_t addr, size_t length)
-    {
-        lldb_private::Value source = m_decl_map.WrapBareAddress(addr);
-        
-        return m_decl_map.ReadTarget(data, source, length);
-    }
-    
-    std::string PrintData (lldb::addr_t addr, size_t length)
-    {
-        lldb_private::Value target = GetAccessTarget(addr);
-        
-        lldb_private::DataBufferHeap buf(length, 0);
-        
-        if (!m_decl_map.ReadTarget(buf.GetBytes(), target, length))
-            return std::string("<couldn't read data>");
-        
-        lldb_private::StreamString ss;
-        
-        for (size_t i = 0; i < length; i++)
-        {
-            if ((!(i & 0xf)) && i)
-                ss.Printf("%02hhx - ", buf.GetBytes()[i]);
-            else
-                ss.Printf("%02hhx ", buf.GetBytes()[i]);
-        }
-        
-        return ss.GetString();
-    }
-    
-    std::string SummarizeRegion (Region &region)
-    {
-        lldb_private::StreamString ss;
-
-        lldb_private::Value base = GetAccessTarget(region.m_base);
-        
-        ss.Printf("%llx [%s - %s %llx]",
-                  region.m_base,
-                  lldb_private::Value::GetValueTypeAsCString(base.GetValueType()),
-                  lldb_private::Value::GetContextTypeAsCString(base.GetContextType()),
-                  base.GetScalar().ULongLong());
-        
-        ss.Printf(" %s", PrintData(region.m_base, region.m_extent).c_str());
-        
-        return ss.GetString();
-    }
-};
-
 class InterpreterStackFrame
 {
 public:
-    typedef std::map <const Value*, Memory::Region> ValueMap;
-
+    typedef std::map <const Value*, lldb::addr_t> ValueMap;
+    
     ValueMap                                m_values;
-    Memory                                 &m_memory;
-    TargetData                             &m_target_data;
-    lldb_private::ClangExpressionDeclMap   &m_decl_map;
+    DataLayout                             &m_target_data;
+    lldb_private::IRMemoryMap              &m_memory_map;
     const BasicBlock                       *m_bb;
     BasicBlock::const_iterator              m_ii;
     BasicBlock::const_iterator              m_ie;
     
+    lldb::addr_t                            m_frame_process_address;
+    size_t                                  m_frame_size;
+    lldb::addr_t                            m_stack_pointer;
+    
     lldb::ByteOrder                         m_byte_order;
     size_t                                  m_addr_byte_size;
     
-    InterpreterStackFrame (TargetData &target_data,
-                           Memory &memory,
-                           lldb_private::ClangExpressionDeclMap &decl_map) :
-        m_memory (memory),
+    InterpreterStackFrame (DataLayout &target_data,
+                           lldb_private::IRMemoryMap &memory_map,
+                           lldb::addr_t stack_frame_bottom,
+                           lldb::addr_t stack_frame_top) :
         m_target_data (target_data),
-        m_decl_map (decl_map)
+        m_memory_map (memory_map)
     {
         m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
-        m_addr_byte_size = (target_data.getPointerSize());
+        m_addr_byte_size = (target_data.getPointerSize(0));
+                        
+        m_frame_process_address = stack_frame_bottom;
+        m_frame_size = stack_frame_top - stack_frame_bottom;
+        m_stack_pointer = stack_frame_top;
+    }
+    
+    ~InterpreterStackFrame ()
+    {
     }
     
     void Jump (const BasicBlock *bb)
@@ -435,14 +102,6 @@ public:
         m_ie = m_bb->end();
     }
     
-    bool Cache (Memory::AllocationSP allocation, Type *type)
-    {
-        if (allocation->m_origin.GetContextType() != lldb_private::Value::eContextTypeRegisterInfo)
-            return false;
-        
-        return m_decl_map.ReadTarget(allocation->m_data->GetBytes(), allocation->m_origin, allocation->m_data->GetByteSize());
-    }
-    
     std::string SummarizeValue (const Value *value)
     {
         lldb_private::StreamString ss;
@@ -453,9 +112,9 @@ public:
 
         if (i != m_values.end())
         {
-            Memory::Region region = i->second;
+            lldb::addr_t addr = i->second;
             
-            ss.Printf(" %s", m_memory.SummarizeRegion(region).c_str());
+            ss.Printf(" 0x%llx", (unsigned long long)addr);
         }
         
         return ss.GetString();
@@ -492,25 +151,32 @@ public:
         
         if (constant)
         {
-            if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
-            {                
-                return AssignToMatchType(scalar, constant_int->getLimitedValue(), value->getType());
-            }
+            APInt value_apint;
+            
+            if (!ResolveConstantValue(value_apint, constant))
+                return false;
+            
+            return AssignToMatchType(scalar, value_apint.getLimitedValue(), value->getType());
         }
         else
         {
-            Memory::Region region = ResolveValue(value, module);
-            DataExtractorSP value_extractor = m_memory.GetExtractor(region);
+            lldb::addr_t process_address = ResolveValue(value, module);
+            size_t value_size = m_target_data.getTypeStoreSize(value->getType());
+        
+            lldb_private::DataExtractor value_extractor;
+            lldb_private::Error extract_error;
             
-            if (!value_extractor)
+            m_memory_map.GetMemoryData(value_extractor, process_address, value_size, extract_error);
+            
+            if (!extract_error.Success())
                 return false;
             
-            size_t value_size = m_target_data.getTypeStoreSize(value->getType());
-                        
-            uint32_t offset = 0;
-            uint64_t u64value = value_extractor->GetMaxU64(&offset, value_size);
-                    
-            return AssignToMatchType(scalar, u64value, value->getType());
+            lldb::offset_t offset = 0;
+            if (value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8)
+            {
+                uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
+                return AssignToMatchType(scalar, u64value, value->getType());
+            }
         }
         
         return false;
@@ -518,415 +184,251 @@ public:
     
     bool AssignValue (const Value *value, lldb_private::Scalar &scalar, Module &module)
     {
-        Memory::Region region = ResolveValue (value, module);
+        lldb::addr_t process_address = ResolveValue (value, module);
+        
+        if (process_address == LLDB_INVALID_ADDRESS)
+            return false;
     
         lldb_private::Scalar cast_scalar;
         
         if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
             return false;
+                
+        size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
         
-        lldb_private::DataBufferHeap buf(cast_scalar.GetByteSize(), 0);
+        lldb_private::DataBufferHeap buf(value_byte_size, 0);
         
-        lldb_private::Error err;
+        lldb_private::Error get_data_error;
         
-        if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, err))
+        if (!cast_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error))
             return false;
         
-        DataEncoderSP region_encoder = m_memory.GetEncoder(region);
+        lldb_private::Error write_error;
         
-        memcpy(region_encoder->GetDataStart(), buf.GetBytes(), buf.GetByteSize());
+        m_memory_map.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error);
         
-        return true;
+        return write_error.Success();
     }
     
     bool ResolveConstantValue (APInt &value, const Constant *constant)
     {
-        if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
-        {
-            value = constant_int->getValue();
-            return true;
-        }
-        else if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant))
-        {
-            value = constant_fp->getValueAPF().bitcastToAPInt();
-            return true;
-        }
-        else if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
+        switch (constant->getValueID())
         {
-            switch (constant_expr->getOpcode())
+        default:
+            break;
+        case Value::ConstantIntVal:
+            if (const ConstantInt *constant_int = dyn_cast<ConstantInt>(constant))
             {
-                default:
-                    return false;
-                case Instruction::IntToPtr:
-                case Instruction::BitCast:
-                    return ResolveConstantValue(value, constant_expr->getOperand(0));
-                case Instruction::GetElementPtr:
-                {
-                    ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
-                    ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
-                                    
-                    Constant *base = dyn_cast<Constant>(*op_cursor);
-                    
-                    if (!base)
-                        return false;
-                    
-                    if (!ResolveConstantValue(value, base))
+                value = constant_int->getValue();
+                return true;
+            }
+            break;
+        case Value::ConstantFPVal:
+            if (const ConstantFP *constant_fp = dyn_cast<ConstantFP>(constant))
+            {
+                value = constant_fp->getValueAPF().bitcastToAPInt();
+                return true;
+            }
+            break;
+        case Value::ConstantExprVal:
+            if (const ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
+            {
+                switch (constant_expr->getOpcode())
+                {
+                    default:
                         return false;
-                    
-                    op_cursor++;
-                    
-                    if (op_cursor == op_end)
-                        return true; // no offset to apply!
-                    
-                    SmallVector <Value *, 8> indices (op_cursor, op_end);
-                    
-                    uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices);
-                    
-                    const bool is_signed = true;
-                    value += APInt(value.getBitWidth(), offset, is_signed);
-                    
-                    return true;
+                    case Instruction::IntToPtr:
+                    case Instruction::PtrToInt:
+                    case Instruction::BitCast:
+                        return ResolveConstantValue(value, constant_expr->getOperand(0));
+                    case Instruction::GetElementPtr:
+                    {
+                        ConstantExpr::const_op_iterator op_cursor = constant_expr->op_begin();
+                        ConstantExpr::const_op_iterator op_end = constant_expr->op_end();
+                        
+                        Constant *base = dyn_cast<Constant>(*op_cursor);
+                        
+                        if (!base)
+                            return false;
+                        
+                        if (!ResolveConstantValue(value, base))
+                            return false;
+                        
+                        op_cursor++;
+                        
+                        if (op_cursor == op_end)
+                            return true; // no offset to apply!
+                        
+                        SmallVector <Value *, 8> indices (op_cursor, op_end);
+                        
+                        uint64_t offset = m_target_data.getIndexedOffset(base->getType(), indices);
+                        
+                        const bool is_signed = true;
+                        value += APInt(value.getBitWidth(), offset, is_signed);
+                        
+                        return true;
+                    }
                 }
             }
+            break;
+        case Value::ConstantPointerNullVal:
+            if (isa<ConstantPointerNull>(constant))
+            {
+                value = APInt(m_target_data.getPointerSizeInBits(), 0);
+                return true;
+            }
+            break;
         }
-        
         return false;
     }
     
-    bool ResolveConstant (Memory::Region &region, const Constant *constant)
+    bool MakeArgument(const Argument *value, uint64_t address)
     {
-        APInt resolved_value;
+        lldb::addr_t data_address = Malloc(value->getType());
         
-        if (!ResolveConstantValue(resolved_value, constant))
+        if (data_address == LLDB_INVALID_ADDRESS)
             return false;
         
-        const uint64_t *raw_data = resolved_value.getRawData();
-            
-        size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
-        return m_memory.Write(region.m_base, (const uint8_t*)raw_data, constant_size);
-    }
+        lldb_private::Error write_error;
         
-    Memory::Region ResolveValue (const Value *value, Module &module)
-    {
-        ValueMap::iterator i = m_values.find(value);
+        m_memory_map.WritePointerToMemory(data_address, address, write_error);
         
-        if (i != m_values.end())
-            return i->second;
+        if (!write_error.Success())
+        {
+            lldb_private::Error free_error;
+            m_memory_map.Free(data_address, free_error);
+            return false;
+        }
         
-        const GlobalValue *global_value = dyn_cast<GlobalValue>(value);
+        m_values[value] = data_address;
         
-        // If the variable is indirected through the argument
-        // array then we need to build an extra level of indirection
-        // for it.  This is the default; only magic arguments like
-        // "this", "self", and "_cmd" are direct.
-        bool indirect_variable = true; 
-        
-        // Attempt to resolve the value using the program's data.
-        // If it is, the values to be created are:
-        //
-        // data_region - a region of memory in which the variable's data resides.
-        // ref_region - a region of memory in which its address (i.e., &var) resides.
-        //   In the JIT case, this region would be a member of the struct passed in.
-        // pointer_region - a region of memory in which the address of the pointer
-        //   resides.  This is an IR-level variable.
-        do
-        {
-            lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-            lldb_private::Value resolved_value;
-            lldb_private::ClangExpressionVariable::FlagType flags = 0;
-            
-            if (global_value)
-            {            
-                clang::NamedDecl *decl = IRForTarget::DeclForGlobal(global_value, &module);
-
-                if (!decl)
-                    break;
-                
-                if (isa<clang::FunctionDecl>(decl))
-                {
-                    if (log)
-                        log->Printf("The interpreter does not handle function pointers at the moment");
-                    
-                    return Memory::Region();
-                }
-                
-                resolved_value = m_decl_map.LookupDecl(decl, flags);
-            }
-            else
-            {
-                // Special-case "this", "self", and "_cmd"
-                
-                std::string name_str = value->getName().str();
-                
-                if (name_str == "this" ||
-                    name_str == "self" ||
-                    name_str == "_cmd")
-                    resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
-                
-                indirect_variable = false;
-            }
-            
-            if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
-            {
-                if (resolved_value.GetContextType() == lldb_private::Value::eContextTypeRegisterInfo)
-                {
-                    bool bare_register = (flags & lldb_private::ClangExpressionVariable::EVBareRegister);
+        lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
-                    if (bare_register)
-                        indirect_variable = false;
-                    
-                    Memory::Region data_region = m_memory.Malloc(value->getType());
-                    data_region.m_allocation->m_origin = resolved_value;
-                    Memory::Region ref_region = m_memory.Malloc(value->getType());
-                    Memory::Region pointer_region;
-                    
-                    if (indirect_variable)
-                        pointer_region = m_memory.Malloc(value->getType());
-                    
-                    if (!Cache(data_region.m_allocation, value->getType()))
-                        return Memory::Region();
-
-                    if (ref_region.IsInvalid())
-                        return Memory::Region();
-                    
-                    if (pointer_region.IsInvalid() && indirect_variable)
-                        return Memory::Region();
-                    
-                    DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
-                    
-                    if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
-                        return Memory::Region();
-                    
-                    if (log)
-                    {
-                        log->Printf("Made an allocation for register variable %s", PrintValue(value).c_str());
-                        log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
-                        log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
-                        log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
-                        if (indirect_variable)
-                            log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
-                    }
-                    
-                    if (indirect_variable)
-                    {
-                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-                        
-                        if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
-                            return Memory::Region();
-                        
-                        m_values[value] = pointer_region;
-                        return pointer_region;
-                    }
-                    else
-                    {
-                        m_values[value] = ref_region;
-                        return ref_region;
-                    }
-                }
-                else
-                {
-                    Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
-                    Memory::Region ref_region = m_memory.Malloc(value->getType());
-                    Memory::Region pointer_region;
-                    
-                    if (indirect_variable)
-                        pointer_region = m_memory.Malloc(value->getType());
-                           
-                    if (ref_region.IsInvalid())
-                        return Memory::Region();
-                    
-                    if (pointer_region.IsInvalid() && indirect_variable)
-                        return Memory::Region();
-                    
-                    DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
-                    
-                    if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
-                        return Memory::Region();
-                    
-                    if (indirect_variable)
-                    {
-                        DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
-                    
-                        if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
-                            return Memory::Region();
-                        
-                        m_values[value] = pointer_region;
-                    }
-                    
-                    if (log)
-                    {
-                        log->Printf("Made an allocation for %s", PrintValue(value).c_str());
-                        log->Printf("  Data contents  : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
-                        log->Printf("  Data region    : %llx", (unsigned long long)data_region.m_base);
-                        log->Printf("  Ref region     : %llx", (unsigned long long)ref_region.m_base);
-                        if (indirect_variable)
-                            log->Printf("  Pointer region : %llx", (unsigned long long)pointer_region.m_base);
-                    }
-                    
-                    if (indirect_variable)
-                        return pointer_region;
-                    else 
-                        return ref_region;
-                }
-            }
+        if (log)
+        {
+            log->Printf("Made an allocation for argument %s", PrintValue(value).c_str());
+            log->Printf("  Data region    : %llx", (unsigned long long)address);
+            log->Printf("  Ref region     : %llx", (unsigned long long)data_address);
         }
-        while(0);
         
-        // Fall back and allocate space [allocation type Alloca]
+        return true;
+    }
+    
+    bool ResolveConstant (lldb::addr_t process_address, const Constant *constant)
+    {
+        APInt resolved_value;
         
-        Type *type = value->getType();
+        if (!ResolveConstantValue(resolved_value, constant))
+            return false;
         
-        lldb::ValueSP backing_value(new lldb_private::Value);
-                
-        Memory::Region data_region = m_memory.Malloc(type);
-        data_region.m_allocation->m_origin.GetScalar() = (unsigned long long)data_region.m_allocation->m_data->GetBytes();
-        data_region.m_allocation->m_origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
-        data_region.m_allocation->m_origin.SetValueType(lldb_private::Value::eValueTypeHostAddress);
+        const uint64_t *raw_data = resolved_value.getRawData();
+            
+        size_t constant_size = m_target_data.getTypeStoreSize(constant->getType());
         
-        const Constant *constant = dyn_cast<Constant>(value);
+        lldb_private::Error write_error;
         
-        do
-        {
-            if (!constant)
-                break;
-            
-            if (!ResolveConstant (data_region, constant))
-                return Memory::Region();
-        }
-        while(0);
+        m_memory_map.WriteMemory(process_address, (uint8_t*)raw_data, constant_size, write_error);
         
-        m_values[value] = data_region;
-        return data_region;
+        return write_error.Success();
     }
     
-    bool ConstructResult (lldb::ClangExpressionVariableSP &result,
-                          const GlobalValue *result_value,
-                          const lldb_private::ConstString &result_name,
-                          lldb_private::TypeFromParser result_type,
-                          Module &module)
+    lldb::addr_t Malloc (size_t size, uint8_t byte_alignment)
     {
-        // The result_value resolves to P, a pointer to a region R containing the result data.
-        // If the result variable is a reference, the region R contains a pointer to the result R_final in the original process.
+        lldb::addr_t ret = m_stack_pointer;
         
-        if (!result_value)
-            return true; // There was no slot for a result – the expression doesn't return one.
+        ret -= size;
+        ret -= (ret % byte_alignment);
         
-        ValueMap::iterator i = m_values.find(result_value);
-
-        if (i == m_values.end())
-            return false; // There was a slot for the result, but we didn't write into it.
+        if (ret < m_frame_process_address)
+            return LLDB_INVALID_ADDRESS;
         
-        Memory::Region P = i->second;
-        DataExtractorSP P_extractor = m_memory.GetExtractor(P);
+        m_stack_pointer = ret;
+        return ret;
+    }
         
-        if (!P_extractor)
-            return false;
+    lldb::addr_t MallocPointer ()
+    {
+        return Malloc(m_target_data.getPointerSize(), m_target_data.getPointerPrefAlignment());
+    }
+    
+    lldb::addr_t Malloc (llvm::Type *type)
+    {
+        lldb_private::Error alloc_error;
         
-        Type *pointer_ty = result_value->getType();
-        PointerType *pointer_ptr_ty = dyn_cast<PointerType>(pointer_ty);
-        if (!pointer_ptr_ty)
-            return false;
-        Type *R_ty = pointer_ptr_ty->getElementType();
-                
-        uint32_t offset = 0;
-        lldb::addr_t pointer = P_extractor->GetAddress(&offset);
+        return Malloc(m_target_data.getTypeAllocSize(type), m_target_data.getPrefTypeAlignment(type));
+    }
+    
+    std::string PrintData (lldb::addr_t addr, llvm::Type *type)
+    {
+        size_t length = m_target_data.getTypeStoreSize(type);
         
-        Memory::Region R = m_memory.Lookup(pointer, R_ty);
+        lldb_private::DataBufferHeap buf(length, 0);
         
-        if (R.m_allocation->m_origin.GetValueType() != lldb_private::Value::eValueTypeHostAddress ||
-            !R.m_allocation->m_data)
-            return false;
+        lldb_private::Error read_error;
         
-        lldb_private::Value base;
+        m_memory_map.ReadMemory(buf.GetBytes(), addr, length, read_error);
+        
+        if (!read_error.Success())
+            return std::string("<couldn't read data>");
         
-        bool transient = false;
-        bool maybe_make_load = false;
+        lldb_private::StreamString ss;
         
-        if (m_decl_map.ResultIsReference(result_name))
+        for (size_t i = 0; i < length; i++)
         {
-            PointerType *R_ptr_ty = dyn_cast<PointerType>(R_ty);           
-            if (!R_ptr_ty)
-                return false;
-            Type *R_final_ty = R_ptr_ty->getElementType();
-            
-            DataExtractorSP R_extractor = m_memory.GetExtractor(R);
-            
-            if (!R_extractor)
-                return false;
-            
-            offset = 0;
-            lldb::addr_t R_pointer = R_extractor->GetAddress(&offset);
-            
-            Memory::Region R_final = m_memory.Lookup(R_pointer, R_final_ty);
-            
-            if (R_final.m_allocation)
-            {            
-                if (R_final.m_allocation->m_data)
-                    transient = true; // this is a stack allocation
-            
-                base = R_final.m_allocation->m_origin;
-                base.GetScalar() += (R_final.m_base - R_final.m_allocation->m_virtual_address);
-            }
+            if ((!(i & 0xf)) && i)
+                ss.Printf("%02hhx - ", buf.GetBytes()[i]);
             else
+                ss.Printf("%02hhx ", buf.GetBytes()[i]);
+        }
+        
+        return ss.GetString();
+    }
+    
+    lldb::addr_t ResolveValue (const Value *value, Module &module)
+    {
+        ValueMap::iterator i = m_values.find(value);
+        
+        if (i != m_values.end())
+            return i->second;
+        
+        // Fall back and allocate space [allocation type Alloca]
+        
+        lldb::addr_t data_address = Malloc(value->getType());
+        
+        if (const Constant *constant = dyn_cast<Constant>(value))
+        {
+            if (!ResolveConstant (data_address, constant))
             {
-                // We got a bare pointer.  We are going to treat it as a load address
-                // or a file address, letting decl_map make the choice based on whether
-                // or not a process exists.
-                
-                base.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
-                base.SetValueType(lldb_private::Value::eValueTypeFileAddress);
-                base.GetScalar() = (unsigned long long)R_pointer;
-                maybe_make_load = true;
+                lldb_private::Error free_error;
+                m_memory_map.Free(data_address, free_error);
+                return LLDB_INVALID_ADDRESS;
             }
         }
-        else
-        {
-            base.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
-            base.SetValueType(lldb_private::Value::eValueTypeHostAddress);
-            base.GetScalar() = (unsigned long long)R.m_allocation->m_data->GetBytes() + (R.m_base - R.m_allocation->m_virtual_address);
-        }                     
-                        
-        return m_decl_map.CompleteResultVariable (result, base, result_name, result_type, transient, maybe_make_load);
+        
+        m_values[value] = data_address;
+        return data_address;
     }
 };
 
-bool
-IRInterpreter::maybeRunOnFunction (lldb::ClangExpressionVariableSP &result,
-                                   const lldb_private::ConstString &result_name,
-                                   lldb_private::TypeFromParser result_type,
-                                   Function &llvm_function,
-                                   Module &llvm_module,
-                                   lldb_private::Error &err)
-{
-    if (supportsFunction (llvm_function, err))
-        return runOnFunction(result,
-                             result_name, 
-                             result_type, 
-                             llvm_function,
-                             llvm_module,
-                             err);
-    else
-        return false;
-}
-
 static const char *unsupported_opcode_error         = "Interpreter doesn't handle one of the expression's opcodes";
-static const char *interpreter_initialization_error = "Interpreter couldn't be initialized";
+static const char *unsupported_operand_error        = "Interpreter doesn't handle one of the expression's operands";
+//static const char *interpreter_initialization_error = "Interpreter couldn't be initialized";
 static const char *interpreter_internal_error       = "Interpreter encountered an internal error";
 static const char *bad_value_error                  = "Interpreter couldn't resolve a value during execution";
 static const char *memory_allocation_error          = "Interpreter couldn't allocate memory";
 static const char *memory_write_error               = "Interpreter couldn't write to memory";
 static const char *memory_read_error                = "Interpreter couldn't read from memory";
 static const char *infinite_loop_error              = "Interpreter ran for too many cycles";
-static const char *bad_result_error                 = "Result of expression is in bad memory";
+//static const char *bad_result_error                 = "Result of expression is in bad memory";
 
 bool
-IRInterpreter::supportsFunction (Function &llvm_function, 
-                                 lldb_private::Error &err)
+IRInterpreter::CanInterpret (llvm::Module &module,
+                             llvm::Function &function,
+                             lldb_private::Error &error)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    for (Function::iterator bbi = llvm_function.begin(), bbe = llvm_function.end();
+    for (Function::iterator bbi = function.begin(), bbe = function.end();
          bbi != bbe;
          ++bbi)
     {
@@ -940,8 +442,8 @@ IRInterpreter::supportsFunction (Functio
                 {
                     if (log)
                         log->Printf("Unsupported instruction: %s", PrintValue(ii).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(unsupported_opcode_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(unsupported_opcode_error);
                     return false;
                 }
             case Instruction::Add:
@@ -956,22 +458,22 @@ IRInterpreter::supportsFunction (Functio
                     
                     if (!icmp_inst)
                     {
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(interpreter_internal_error);
+                        error.SetErrorToGenericError();
+                        error.SetErrorString(interpreter_internal_error);
                         return false;
                     }
                     
                     switch (icmp_inst->getPredicate())
                     {
                     default:
-                        {
-                            if (log)
-                                log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str());
-                            
-                            err.SetErrorToGenericError();
-                            err.SetErrorString(unsupported_opcode_error);
-                            return false;
-                        }
+                    {
+                        if (log)
+                            log->Printf("Unsupported ICmp predicate: %s", PrintValue(ii).c_str());
+                        
+                        error.SetErrorToGenericError();
+                        error.SetErrorString(unsupported_opcode_error);
+                        return false;
+                    }
                     case CmpInst::ICMP_EQ:
                     case CmpInst::ICMP_NE:
                     case CmpInst::ICMP_UGT:
@@ -986,81 +488,106 @@ IRInterpreter::supportsFunction (Functio
                     }
                 }
                 break;
+            case Instruction::And:
+            case Instruction::AShr:
             case Instruction::IntToPtr:
+            case Instruction::PtrToInt:
             case Instruction::Load:
+            case Instruction::LShr:
             case Instruction::Mul:
+            case Instruction::Or:
             case Instruction::Ret:
             case Instruction::SDiv:
+            case Instruction::SExt:
+            case Instruction::Shl:
+            case Instruction::SRem:
             case Instruction::Store:
             case Instruction::Sub:
             case Instruction::UDiv:
+            case Instruction::URem:
+            case Instruction::Xor:
             case Instruction::ZExt:
                 break;
             }
+            
+            for (int oi = 0, oe = ii->getNumOperands();
+                 oi != oe;
+                 ++oi)
+            {
+                Value *operand = ii->getOperand(oi);
+                Type *operand_type = operand->getType();
+                
+                switch (operand_type->getTypeID())
+                {
+                default:
+                    break;
+                case Type::VectorTyID:
+                    {
+                        if (log)
+                            log->Printf("Unsupported operand type: %s", PrintType(operand_type).c_str());
+                        error.SetErrorString(unsupported_operand_error);
+                        return false;
+                    }
+                }
+            }
         }
+        
     }
     
-    return true;
-}
+    return true;}
 
-bool 
-IRInterpreter::runOnFunction (lldb::ClangExpressionVariableSP &result,
-                              const lldb_private::ConstString &result_name,
-                              lldb_private::TypeFromParser result_type,
-                              Function &llvm_function,
-                              Module &llvm_module,
-                              lldb_private::Error &err)
+bool
+IRInterpreter::Interpret (llvm::Module &module,
+                          llvm::Function &function,
+                          llvm::ArrayRef<lldb::addr_t> args,
+                          lldb_private::IRMemoryMap &memory_map,
+                          lldb_private::Error &error,
+                          lldb::addr_t stack_frame_bottom,
+                          lldb::addr_t stack_frame_top)
 {
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    lldb_private::ClangExpressionDeclMap::TargetInfo target_info = m_decl_map.GetTargetInfo();
-    
-    if (!target_info.IsValid())
+    if (log)
     {
-        err.SetErrorToGenericError();
-        err.SetErrorString(interpreter_initialization_error);
-        return false;
+        std::string s;
+        raw_string_ostream oss(s);
+        
+        module.print(oss, NULL);
+        
+        oss.flush();
+        
+        log->Printf("Module as passed in to IRInterpreter::Interpret: \n\"%s\"", s.c_str());
     }
     
-    lldb::addr_t alloc_min;
-    lldb::addr_t alloc_max;
+    DataLayout data_layout(&module);
     
-    switch (target_info.address_byte_size)
-    {
-    default:
-        err.SetErrorToGenericError();
-        err.SetErrorString(interpreter_initialization_error);
-        return false;    
-    case 4:
-        alloc_min = 0x00001000llu;
-        alloc_max = 0x0000ffffllu;
-        break;
-    case 8:
-        alloc_min = 0x0000000000001000llu;
-        alloc_max = 0x000000000000ffffllu;
-        break;
-    }
+    InterpreterStackFrame frame(data_layout, memory_map, stack_frame_bottom, stack_frame_top);
     
-    TargetData target_data(&llvm_module);
-    if (target_data.getPointerSize() != target_info.address_byte_size)
+    if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
     {
-        err.SetErrorToGenericError();
-        err.SetErrorString(interpreter_initialization_error);
-        return false;
+        error.SetErrorString("Couldn't allocate stack frame");
     }
-    if (target_data.isLittleEndian() != (target_info.byte_order == lldb::eByteOrderLittle))
+    
+    int arg_index = 0;
+    
+    for (llvm::Function::arg_iterator ai = function.arg_begin(), ae = function.arg_end();
+         ai != ae;
+         ++ai, ++arg_index)
     {
-        err.SetErrorToGenericError();
-        err.SetErrorString(interpreter_initialization_error);
-        return false;
+        if (args.size() < arg_index)
+        {
+            error.SetErrorString ("Not enough arguments passed in to function");
+            return false;
+        }
+        
+        lldb::addr_t ptr = args[arg_index];
+
+        frame.MakeArgument(ai, ptr);
     }
     
-    Memory memory(target_data, m_decl_map, alloc_min, alloc_max);
-    InterpreterStackFrame frame(target_data, memory, m_decl_map);
-
     uint32_t num_insts = 0;
     
-    frame.Jump(llvm_function.begin());
+    frame.Jump(function.begin());
     
     while (frame.m_ii != frame.m_ie && (++num_insts < 4096))
     {
@@ -1071,13 +598,21 @@ IRInterpreter::runOnFunction (lldb::Clan
         
         switch (inst->getOpcode())
         {
-        default:
-            break;
-        case Instruction::Add:
-        case Instruction::Sub:
-        case Instruction::Mul:
-        case Instruction::SDiv:
-        case Instruction::UDiv:
+            default:
+                break;
+            case Instruction::Add:
+            case Instruction::Sub:
+            case Instruction::Mul:
+            case Instruction::SDiv:
+            case Instruction::UDiv:
+            case Instruction::SRem:
+            case Instruction::URem:
+            case Instruction::Shl:
+            case Instruction::LShr:
+            case Instruction::AShr:
+            case Instruction::And:
+            case Instruction::Or:
+            case Instruction::Xor:
             {
                 const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
                 
@@ -1085,9 +620,9 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns %s, but instruction is not a BinaryOperator", inst->getOpcodeName());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
-                    return false;                
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
+                    return false;
                 }
                 
                 Value *lhs = inst->getOperand(0);
@@ -1096,21 +631,21 @@ IRInterpreter::runOnFunction (lldb::Clan
                 lldb_private::Scalar L;
                 lldb_private::Scalar R;
                 
-                if (!frame.EvaluateValue(L, lhs, llvm_module))
+                if (!frame.EvaluateValue(L, lhs, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                if (!frame.EvaluateValue(R, rhs, llvm_module))
+                if (!frame.EvaluateValue(R, rhs, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);                 
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
@@ -1118,26 +653,55 @@ IRInterpreter::runOnFunction (lldb::Clan
                 
                 switch (inst->getOpcode())
                 {
-                default:
-                    break;
-                case Instruction::Add:
-                    result = L + R;
-                    break;
-                case Instruction::Mul:
-                    result = L * R;
-                    break;
-                case Instruction::Sub:
-                    result = L - R;
-                    break;
-                case Instruction::SDiv:
-                    result = L / R;
-                    break;
-                case Instruction::UDiv:
-                    result = L.GetRawBits64(0) / R.GetRawBits64(1);
-                    break;
+                    default:
+                        break;
+                    case Instruction::Add:
+                        result = L + R;
+                        break;
+                    case Instruction::Mul:
+                        result = L * R;
+                        break;
+                    case Instruction::Sub:
+                        result = L - R;
+                        break;
+                    case Instruction::SDiv:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = L / R;
+                        break;
+                    case Instruction::UDiv:
+                        result = L.GetRawBits64(0) / R.GetRawBits64(1);
+                        break;
+                    case Instruction::SRem:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = L % R;
+                        break;
+                    case Instruction::URem:
+                        result = L.GetRawBits64(0) % R.GetRawBits64(1);
+                        break;
+                    case Instruction::Shl:
+                        result = L << R;
+                        break;
+                    case Instruction::AShr:
+                        result = L >> R;
+                        break;
+                    case Instruction::LShr:
+                        result = L;
+                        result.ShiftRightLogical(R);
+                        break;
+                    case Instruction::And:
+                        result = L & R;
+                        break;
+                    case Instruction::Or:
+                        result = L | R;
+                        break;
+                    case Instruction::Xor:
+                        result = L ^ R;
+                        break;
                 }
-                                
-                frame.AssignValue(inst, result, llvm_module);
+                
+                frame.AssignValue(inst, result, module);
                 
                 if (log)
                 {
@@ -1147,8 +711,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                     log->Printf("  = : %s", frame.SummarizeValue(inst).c_str());
                 }
             }
-            break;
-        case Instruction::Alloca:
+                break;
+            case Instruction::Alloca:
             {
                 const AllocaInst *alloca_inst = dyn_cast<AllocaInst>(inst);
                 
@@ -1156,8 +720,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns Alloca, but instruction is not an AllocaInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1165,8 +729,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("AllocaInsts are not handled if isArrayAllocation() is true");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(unsupported_opcode_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(unsupported_opcode_error);
                     return false;
                 }
                 
@@ -1178,36 +742,41 @@ IRInterpreter::runOnFunction (lldb::Clan
                 Type *T = alloca_inst->getAllocatedType();
                 Type *Tptr = alloca_inst->getType();
                 
-                Memory::Region R = memory.Malloc(T);
+                lldb::addr_t R = frame.Malloc(T);
                 
-                if (R.IsInvalid())
+                if (R == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("Couldn't allocate memory for an AllocaInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(memory_allocation_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_allocation_error);
                     return false;
                 }
                 
-                Memory::Region P = memory.Malloc(Tptr);
+                lldb::addr_t P = frame.Malloc(Tptr);
                 
-                if (P.IsInvalid())
+                if (P == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("Couldn't allocate the result pointer for an AllocaInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(memory_allocation_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_allocation_error);
                     return false;
                 }
                 
-                DataEncoderSP P_encoder = memory.GetEncoder(P);
+                lldb_private::Error write_error;
+                
+                memory_map.WritePointerToMemory(P, R, write_error);
                 
-                if (P_encoder->PutAddress(0, R.m_base) == UINT32_MAX)
+                if (!write_error.Success())
                 {
                     if (log)
                         log->Printf("Couldn't write the result pointer for an AllocaInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(memory_write_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_write_error);
+                    lldb_private::Error free_error;
+                    memory_map.Free(P, free_error);
+                    memory_map.Free(R, free_error);
                     return false;
                 }
                 
@@ -1216,13 +785,13 @@ IRInterpreter::runOnFunction (lldb::Clan
                 if (log)
                 {
                     log->Printf("Interpreted an AllocaInst");
-                    log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
-                    log->Printf("  P : %s", frame.SummarizeValue(alloca_inst).c_str());
+                    log->Printf("  R : 0x%" PRIx64, R);
+                    log->Printf("  P : 0x%" PRIx64, P);
                 }
             }
-            break;
-        case Instruction::BitCast:
-        case Instruction::ZExt:
+                break;
+            case Instruction::BitCast:
+            case Instruction::ZExt:
             {
                 const CastInst *cast_inst = dyn_cast<CastInst>(inst);
                 
@@ -1230,8 +799,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1239,19 +808,52 @@ IRInterpreter::runOnFunction (lldb::Clan
                 
                 lldb_private::Scalar S;
                 
-                if (!frame.EvaluateValue(S, source, llvm_module))
+                if (!frame.EvaluateValue(S, source, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                frame.AssignValue(inst, S, llvm_module);
+                frame.AssignValue(inst, S, module);
             }
-            break;
-        case Instruction::Br:
+                break;
+            case Instruction::SExt:
+            {
+                const CastInst *cast_inst = dyn_cast<CastInst>(inst);
+                
+                if (!cast_inst)
+                {
+                    if (log)
+                        log->Printf("getOpcode() returns %s, but instruction is not a BitCastInst", cast_inst->getOpcodeName());
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
+                    return false;
+                }
+                
+                Value *source = cast_inst->getOperand(0);
+                
+                lldb_private::Scalar S;
+                
+                if (!frame.EvaluateValue(S, source, module))
+                {
+                    if (log)
+                        log->Printf("Couldn't evaluate %s", PrintValue(source).c_str());
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
+                    return false;
+                }
+                
+                S.MakeSigned();
+                
+                lldb_private::Scalar S_signextend(S.SLongLong());
+                
+                frame.AssignValue(inst, S_signextend, module);
+            }
+                break;
+            case Instruction::Br:
             {
                 const BranchInst *br_inst = dyn_cast<BranchInst>(inst);
                 
@@ -1259,8 +861,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns Br, but instruction is not a BranchInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1270,15 +872,15 @@ IRInterpreter::runOnFunction (lldb::Clan
                     
                     lldb_private::Scalar C;
                     
-                    if (!frame.EvaluateValue(C, condition, llvm_module))
+                    if (!frame.EvaluateValue(C, condition, module))
                     {
                         if (log)
                             log->Printf("Couldn't evaluate %s", PrintValue(condition).c_str());
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(bad_value_error);
+                        error.SetErrorToGenericError();
+                        error.SetErrorString(bad_value_error);
                         return false;
                     }
-                
+                    
                     if (C.GetRawBits64(0))
                         frame.Jump(br_inst->getSuccessor(0));
                     else
@@ -1300,8 +902,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                     }
                 }
             }
-            continue;
-        case Instruction::GetElementPtr:
+                continue;
+            case Instruction::GetElementPtr:
             {
                 const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst);
                 
@@ -1309,25 +911,25 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns GetElementPtr, but instruction is not a GetElementPtrInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
-             
+                
                 const Value *pointer_operand = gep_inst->getPointerOperand();
                 Type *pointer_type = pointer_operand->getType();
                 
                 lldb_private::Scalar P;
                 
-                if (!frame.EvaluateValue(P, pointer_operand, llvm_module))
+                if (!frame.EvaluateValue(P, pointer_operand, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(pointer_operand).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
-                    
+                
                 typedef SmallVector <Value *, 8> IndexVector;
                 typedef IndexVector::iterator IndexIterator;
                 
@@ -1346,12 +948,12 @@ IRInterpreter::runOnFunction (lldb::Clan
                     {
                         lldb_private::Scalar I;
                         
-                        if (!frame.EvaluateValue(I, *ii, llvm_module))
+                        if (!frame.EvaluateValue(I, *ii, module))
                         {
                             if (log)
                                 log->Printf("Couldn't evaluate %s", PrintValue(*ii).c_str());
-                            err.SetErrorToGenericError();
-                            err.SetErrorString(bad_value_error);
+                            error.SetErrorToGenericError();
+                            error.SetErrorString(bad_value_error);
                             return false;
                         }
                         
@@ -1364,11 +966,11 @@ IRInterpreter::runOnFunction (lldb::Clan
                     const_indices.push_back(constant_index);
                 }
                 
-                uint64_t offset = target_data.getIndexedOffset(pointer_type, const_indices);
+                uint64_t offset = data_layout.getIndexedOffset(pointer_type, const_indices);
                 
                 lldb_private::Scalar Poffset = P + offset;
                 
-                frame.AssignValue(inst, Poffset, llvm_module);
+                frame.AssignValue(inst, Poffset, module);
                 
                 if (log)
                 {
@@ -1377,8 +979,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                     log->Printf("  Poffset : %s", frame.SummarizeValue(inst).c_str());
                 }
             }
-            break;
-        case Instruction::ICmp:
+                break;
+            case Instruction::ICmp:
             {
                 const ICmpInst *icmp_inst = dyn_cast<ICmpInst>(inst);
                 
@@ -1386,8 +988,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns ICmp, but instruction is not an ICmpInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1399,63 +1001,71 @@ IRInterpreter::runOnFunction (lldb::Clan
                 lldb_private::Scalar L;
                 lldb_private::Scalar R;
                 
-                if (!frame.EvaluateValue(L, lhs, llvm_module))
+                if (!frame.EvaluateValue(L, lhs, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(lhs).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                if (!frame.EvaluateValue(R, rhs, llvm_module))
+                if (!frame.EvaluateValue(R, rhs, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(rhs).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
                 lldb_private::Scalar result;
-
+                
                 switch (predicate)
                 {
-                default:
-                    return false;
-                case CmpInst::ICMP_EQ:
-                    result = (L == R);
-                    break;
-                case CmpInst::ICMP_NE:
-                    result = (L != R);
-                    break;    
-                case CmpInst::ICMP_UGT:
-                    result = (L.GetRawBits64(0) > R.GetRawBits64(0));
-                    break;
-                case CmpInst::ICMP_UGE:
-                    result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
-                    break;
-                case CmpInst::ICMP_ULT:
-                    result = (L.GetRawBits64(0) < R.GetRawBits64(0));
-                    break;
-                case CmpInst::ICMP_ULE:
-                    result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
-                    break;
-                case CmpInst::ICMP_SGT:
-                    result = (L > R);
-                    break;
-                case CmpInst::ICMP_SGE:
-                    result = (L >= R);
-                    break;
-                case CmpInst::ICMP_SLT:
-                    result = (L < R);
-                    break;
-                case CmpInst::ICMP_SLE:
-                    result = (L <= R);
-                    break;
+                    default:
+                        return false;
+                    case CmpInst::ICMP_EQ:
+                        result = (L == R);
+                        break;
+                    case CmpInst::ICMP_NE:
+                        result = (L != R);
+                        break;
+                    case CmpInst::ICMP_UGT:
+                        result = (L.GetRawBits64(0) > R.GetRawBits64(0));
+                        break;
+                    case CmpInst::ICMP_UGE:
+                        result = (L.GetRawBits64(0) >= R.GetRawBits64(0));
+                        break;
+                    case CmpInst::ICMP_ULT:
+                        result = (L.GetRawBits64(0) < R.GetRawBits64(0));
+                        break;
+                    case CmpInst::ICMP_ULE:
+                        result = (L.GetRawBits64(0) <= R.GetRawBits64(0));
+                        break;
+                    case CmpInst::ICMP_SGT:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = (L > R);
+                        break;
+                    case CmpInst::ICMP_SGE:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = (L >= R);
+                        break;
+                    case CmpInst::ICMP_SLT:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = (L < R);
+                        break;
+                    case CmpInst::ICMP_SLE:
+                        L.MakeSigned();
+                        R.MakeSigned();
+                        result = (L <= R);
+                        break;
                 }
                 
-                frame.AssignValue(inst, result, llvm_module);
+                frame.AssignValue(inst, result, module);
                 
                 if (log)
                 {
@@ -1465,8 +1075,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                     log->Printf("  = : %s", frame.SummarizeValue(inst).c_str());
                 }
             }
-            break;
-        case Instruction::IntToPtr:
+                break;
+            case Instruction::IntToPtr:
             {
                 const IntToPtrInst *int_to_ptr_inst = dyn_cast<IntToPtrInst>(inst);
                 
@@ -1474,8 +1084,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns IntToPtr, but instruction is not an IntToPtrInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1483,26 +1093,62 @@ IRInterpreter::runOnFunction (lldb::Clan
                 
                 lldb_private::Scalar I;
                 
-                if (!frame.EvaluateValue(I, src_operand, llvm_module))
+                if (!frame.EvaluateValue(I, src_operand, module))
                 {
                     if (log)
                         log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                frame.AssignValue(inst, I, llvm_module);
+                frame.AssignValue(inst, I, module);
                 
                 if (log)
                 {
                     log->Printf("Interpreted an IntToPtr");
                     log->Printf("  Src : %s", frame.SummarizeValue(src_operand).c_str());
-                    log->Printf("  =   : %s", frame.SummarizeValue(inst).c_str()); 
+                    log->Printf("  =   : %s", frame.SummarizeValue(inst).c_str());
                 }
             }
-            break;
-        case Instruction::Load:
+                break;
+            case Instruction::PtrToInt:
+            {
+                const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
+                
+                if (!ptr_to_int_inst)
+                {
+                    if (log)
+                        log->Printf("getOpcode() returns PtrToInt, but instruction is not an PtrToIntInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
+                    return false;
+                }
+                
+                Value *src_operand = ptr_to_int_inst->getOperand(0);
+                
+                lldb_private::Scalar I;
+                
+                if (!frame.EvaluateValue(I, src_operand, module))
+                {
+                    if (log)
+                        log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
+                    return false;
+                }
+                
+                frame.AssignValue(inst, I, module);
+                
+                if (log)
+                {
+                    log->Printf("Interpreted a PtrToInt");
+                    log->Printf("  Src : %s", frame.SummarizeValue(src_operand).c_str());
+                    log->Printf("  =   : %s", frame.SummarizeValue(inst).c_str());
+                }
+            }
+                break;
+            case Instruction::Load:
             {
                 const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
                 
@@ -1510,8 +1156,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns Load, but instruction is not a LoadInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1520,7 +1166,7 @@ IRInterpreter::runOnFunction (lldb::Clan
                 //   Resolve the region P containing a pointer
                 //   Dereference P to get the region R that the data should be loaded from
                 //   Transfer a unit of type type(D) from R to D
-                                
+                
                 const Value *pointer_operand = load_inst->getPointerOperand();
                 
                 Type *pointer_ty = pointer_operand->getType();
@@ -1529,95 +1175,85 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getPointerOperand()->getType() is not a PointerType");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 Type *target_ty = pointer_ptr_ty->getElementType();
                 
-                Memory::Region D = frame.ResolveValue(load_inst, llvm_module);
-                Memory::Region P = frame.ResolveValue(pointer_operand, llvm_module);
+                lldb::addr_t D = frame.ResolveValue(load_inst, module);
+                lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
                 
-                if (D.IsInvalid())
+                if (D == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("LoadInst's value doesn't resolve to anything");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                if (P.IsInvalid())
+                if (P == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("LoadInst's pointer doesn't resolve to anything");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                DataExtractorSP P_extractor(memory.GetExtractor(P));
-                DataEncoderSP D_encoder(memory.GetEncoder(D));
-
-                uint32_t offset = 0;
-                lldb::addr_t pointer = P_extractor->GetAddress(&offset);
+                lldb::addr_t R;
+                lldb_private::Error read_error;
+                memory_map.ReadPointerFromMemory(&R, P, read_error);
                 
-                Memory::Region R = memory.Lookup(pointer, target_ty);
+                if (!read_error.Success())
+                {
+                    if (log)
+                        log->Printf("Couldn't read the address to be loaded for a LoadInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_read_error);
+                    return false;
+                }
                 
-                if (R.IsValid())
+                size_t target_size = data_layout.getTypeStoreSize(target_ty);
+                lldb_private::DataBufferHeap buffer(target_size, 0);
+                
+                read_error.Clear();
+                memory_map.ReadMemory(buffer.GetBytes(), R, buffer.GetByteSize(), read_error);
+                if (!read_error.Success())
                 {
-                    if (!memory.Read(D_encoder->GetDataStart(), R.m_base, target_data.getTypeStoreSize(target_ty)))
-                    {
-                        if (log)
-                            log->Printf("Couldn't read from a region on behalf of a LoadInst");
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(memory_read_error);
-                        return false;
-                    }
+                    if (log)
+                        log->Printf("Couldn't read from a region on behalf of a LoadInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_read_error);
+                    return false;
                 }
-                else
+                
+                lldb_private::Error write_error;
+                memory_map.WriteMemory(D, buffer.GetBytes(), buffer.GetByteSize(), write_error);
+                if (!write_error.Success())
                 {
-                    if (!memory.ReadFromRawPtr(D_encoder->GetDataStart(), pointer, target_data.getTypeStoreSize(target_ty)))
-                    {
-                        if (log)
-                            log->Printf("Couldn't read from a raw pointer on behalf of a LoadInst");
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(memory_read_error);
-                        return false;
-                    }
+                    if (log)
+                        log->Printf("Couldn't write to a region on behalf of a LoadInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_read_error);
+                    return false;
                 }
                 
                 if (log)
                 {
                     log->Printf("Interpreted a LoadInst");
-                    log->Printf("  P : %s", frame.SummarizeValue(pointer_operand).c_str());
-                    if (R.IsValid())
-                        log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
-                    else
-                        log->Printf("  R : raw pointer 0x%llx", (unsigned long long)pointer);
-                    log->Printf("  D : %s", frame.SummarizeValue(load_inst).c_str());
+                    log->Printf("  P : 0x%" PRIx64, P);
+                    log->Printf("  R : 0x%" PRIx64, R);
+                    log->Printf("  D : 0x%" PRIx64, D);
                 }
             }
-            break;
-        case Instruction::Ret:
+                break;
+            case Instruction::Ret:
             {
-                if (result_name.IsEmpty())
-                    return true;
-                
-                GlobalValue *result_value = llvm_module.getNamedValue(result_name.GetCString());
-                
-                if (!frame.ConstructResult(result, result_value, result_name, result_type, llvm_module))
-                {
-                    if (log)
-                        log->Printf("Couldn't construct the expression's result");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_result_error);
-                    return false;
-                }
-                
                 return true;
             }
-        case Instruction::Store:
+            case Instruction::Store:
             {
                 const StoreInst *store_inst = dyn_cast<StoreInst>(inst);
                 
@@ -1625,8 +1261,8 @@ IRInterpreter::runOnFunction (lldb::Clan
                 {
                     if (log)
                         log->Printf("getOpcode() returns Store, but instruction is not a StoreInst");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(interpreter_internal_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(interpreter_internal_error);
                     return false;
                 }
                 
@@ -1645,71 +1281,74 @@ IRInterpreter::runOnFunction (lldb::Clan
                     return false;
                 Type *target_ty = pointer_ptr_ty->getElementType();
                 
-                Memory::Region D = frame.ResolveValue(value_operand, llvm_module);
-                Memory::Region P = frame.ResolveValue(pointer_operand, llvm_module);
+                lldb::addr_t D = frame.ResolveValue(value_operand, module);
+                lldb::addr_t P = frame.ResolveValue(pointer_operand, module);
                 
-                if (D.IsInvalid())
+                if (D == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("StoreInst's value doesn't resolve to anything");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                if (P.IsInvalid())
+                if (P == LLDB_INVALID_ADDRESS)
                 {
                     if (log)
                         log->Printf("StoreInst's pointer doesn't resolve to anything");
-                    err.SetErrorToGenericError();
-                    err.SetErrorString(bad_value_error);
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(bad_value_error);
                     return false;
                 }
                 
-                DataExtractorSP P_extractor(memory.GetExtractor(P));
-                DataExtractorSP D_extractor(memory.GetExtractor(D));
-
-                if (!P_extractor || !D_extractor)
-                    return false;
+                lldb::addr_t R;
+                lldb_private::Error read_error;
+                memory_map.ReadPointerFromMemory(&R, P, read_error);
                 
-                uint32_t offset = 0;
-                lldb::addr_t pointer = P_extractor->GetAddress(&offset);
+                if (!read_error.Success())
+                {
+                    if (log)
+                        log->Printf("Couldn't read the address to be loaded for a LoadInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_read_error);
+                    return false;
+                }
                 
-                Memory::Region R = memory.Lookup(pointer, target_ty);
+                size_t target_size = data_layout.getTypeStoreSize(target_ty);
+                lldb_private::DataBufferHeap buffer(target_size, 0);
                 
-                if (R.IsValid())
+                read_error.Clear();
+                memory_map.ReadMemory(buffer.GetBytes(), D, buffer.GetByteSize(), read_error);
+                if (!read_error.Success())
                 {
-                    if (!memory.Write(R.m_base, D_extractor->GetDataStart(), target_data.getTypeStoreSize(target_ty)))
-                    {
-                        if (log)
-                            log->Printf("Couldn't write to a region on behalf of a LoadInst");
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(memory_write_error);
-                        return false;
-                    }
+                    if (log)
+                        log->Printf("Couldn't read from a region on behalf of a StoreInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_read_error);
+                    return false;
                 }
-                else
+                
+                lldb_private::Error write_error;
+                memory_map.WriteMemory(R, buffer.GetBytes(), buffer.GetByteSize(), write_error);
+                if (!write_error.Success())
                 {
-                    if (!memory.WriteToRawPtr(pointer, D_extractor->GetDataStart(), target_data.getTypeStoreSize(target_ty)))
-                    {
-                        if (log)
-                            log->Printf("Couldn't write to a raw pointer on behalf of a LoadInst");
-                        err.SetErrorToGenericError();
-                        err.SetErrorString(memory_write_error);
-                        return false;
-                    }
+                    if (log)
+                        log->Printf("Couldn't write to a region on behalf of a StoreInst");
+                    error.SetErrorToGenericError();
+                    error.SetErrorString(memory_write_error);
+                    return false;
                 }
                 
-                
                 if (log)
                 {
                     log->Printf("Interpreted a StoreInst");
-                    log->Printf("  D : %s", frame.SummarizeValue(value_operand).c_str());
-                    log->Printf("  P : %s", frame.SummarizeValue(pointer_operand).c_str());
-                    log->Printf("  R : %s", memory.SummarizeRegion(R).c_str());
+                    log->Printf("  D : 0x%" PRIx64, D);
+                    log->Printf("  P : 0x%" PRIx64, P);
+                    log->Printf("  R : 0x%" PRIx64, R);
                 }
             }
-            break;
+                break;
         }
         
         ++frame.m_ii;
@@ -1717,10 +1356,10 @@ IRInterpreter::runOnFunction (lldb::Clan
     
     if (num_insts >= 4096)
     {
-        err.SetErrorToGenericError();
-        err.SetErrorString(infinite_loop_error);
+        error.SetErrorToGenericError();
+        error.SetErrorString(infinite_loop_error);
         return false;
     }
-        
-    return false; 
+    
+    return false;
 }

Copied: lldb/branches/lldb-platform-work/source/Expression/IRMemoryMap.cpp (from r182522, lldb/trunk/source/Expression/IRMemoryMap.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/IRMemoryMap.cpp?p2=lldb/branches/lldb-platform-work/source/Expression/IRMemoryMap.cpp&p1=lldb/trunk/source/Expression/IRMemoryMap.cpp&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRMemoryMap.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/IRMemoryMap.cpp Thu Jun  6 19:06:43 2013
@@ -38,7 +38,10 @@ IRMemoryMap::~IRMemoryMap ()
         while ((iter = m_allocations.begin()) != m_allocations.end())
         {
             err.Clear();
-            Free(iter->first, err);
+            if (iter->second.m_leak)
+                m_allocations.erase(iter);
+            else
+                Free(iter->first, err);
         }
     }
 }
@@ -357,7 +360,7 @@ IRMemoryMap::Malloc (size_t size, uint8_
             break;
         }
         
-        log->Printf("IRMemoryMap::Malloc (%llu, 0x%llx, 0x%llx, %s) -> 0x%llx",
+        log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
                     (uint64_t)allocation_size,
                     (uint64_t)alignment,
                     (uint64_t)permissions,
@@ -369,6 +372,25 @@ IRMemoryMap::Malloc (size_t size, uint8_
 }
 
 void
+IRMemoryMap::Leak (lldb::addr_t process_address, Error &error)
+{
+    error.Clear();
+    
+    AllocationMap::iterator iter = m_allocations.find(process_address);
+    
+    if (iter == m_allocations.end())
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString("Couldn't leak: allocation doesn't exist");
+        return;
+    }
+    
+    Allocation &allocation = iter->second;
+
+    allocation.m_leak = true;
+}
+
+void
 IRMemoryMap::Free (lldb::addr_t process_address, Error &error)
 {
     error.Clear();
@@ -411,7 +433,7 @@ IRMemoryMap::Free (lldb::addr_t process_
     
     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
     {        
-        log->Printf("IRMemoryMap::Free (0x%llx) freed [0x%llx..0x%llx)",
+        log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")",
                     (uint64_t)process_address,
                     iter->second.m_process_start,
                     iter->second.m_process_start + iter->second.m_size);
@@ -492,7 +514,7 @@ IRMemoryMap::WriteMemory (lldb::addr_t p
     
     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
     {        
-        log->Printf("IRMemoryMap::WriteMemory (0x%llx, 0x%llx, 0x%lld) went to [0x%llx..0x%llx)",
+        log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")",
                     (uint64_t)process_address,
                     (uint64_t)bytes,
                     (uint64_t)size,
@@ -625,7 +647,7 @@ IRMemoryMap::ReadMemory (uint8_t *bytes,
     
     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
     {
-        log->Printf("IRMemoryMap::ReadMemory (0x%llx, 0x%llx, 0x%lld) came from [0x%llx..0x%llx)",
+        log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")",
                     (uint64_t)process_address,
                     (uint64_t)bytes,
                     (uint64_t)size,
@@ -655,7 +677,7 @@ IRMemoryMap::ReadScalarFromMemory (Scala
         {
         default:
             error.SetErrorToGenericError();
-            error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
+            error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size);
             return;
         case 1: scalar = extractor.GetU8(&offset);  break;
         case 2: scalar = extractor.GetU16(&offset); break;
@@ -699,7 +721,7 @@ IRMemoryMap::GetMemoryData (DataExtracto
         if (iter == m_allocations.end())
         {
             error.SetErrorToGenericError();
-            error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%llx..0x%llx)", (unsigned long long)process_address, (unsigned long long)(process_address + size));
+            error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
             return;
         }
         

Copied: lldb/branches/lldb-platform-work/source/Expression/Materializer.cpp (from r182522, lldb/trunk/source/Expression/Materializer.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/Materializer.cpp?p2=lldb/branches/lldb-platform-work/source/Expression/Materializer.cpp&p1=lldb/trunk/source/Expression/Materializer.cpp&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/source/Expression/Materializer.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/Materializer.cpp Thu Jun  6 19:06:43 2013
@@ -109,7 +109,11 @@ public:
         // Clear the flag if the variable will never be deallocated.
         
         if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
+        {
+            Error leak_error;
+            map.Leak(mem, leak_error);
             m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation;
+        }
         
         // Write the contents of the variable to the area.
         
@@ -148,7 +152,7 @@ public:
 
         if (log)
         {
-            log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
+            log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
                         (uint64_t)process_address,
                         m_persistent_variable_sp->GetName().AsCString(),
                         m_persistent_variable_sp->m_flags);
@@ -192,7 +196,7 @@ public:
         
         if (log)
         {
-            log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
+            log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]",
                         (uint64_t)process_address,
                         m_persistent_variable_sp->GetName().AsCString(),
                         m_persistent_variable_sp->m_flags);
@@ -314,7 +318,7 @@ public:
         
         Error err;
         
-        dump_stream.Printf("0x%llx: EntityPersistentVariable (%s)\n", (unsigned long long)process_address + m_offset, m_persistent_variable_sp->GetName().AsCString());
+        dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", process_address + m_offset, m_persistent_variable_sp->GetName().AsCString());
         
         {
             dump_stream.Printf("Pointer:\n");
@@ -411,7 +415,7 @@ public:
         
         if (log)
         {
-            log->Printf("EntityVariable::Materialize [process_address = 0x%llx, m_variable_sp = %s]",
+            log->Printf("EntityVariable::Materialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]",
                         (uint64_t)process_address,
                         m_variable_sp->GetName().AsCString());
         }
@@ -532,7 +536,7 @@ public:
 
         if (log)
         {
-            log->Printf("EntityVariable::Dematerialize [process_address = 0x%llx, m_variable_sp = %s]",
+            log->Printf("EntityVariable::Dematerialize [process_address = 0x%" PRIx64 ", m_variable_sp = %s]",
                         (uint64_t)process_address,
                         m_variable_sp->GetName().AsCString());
         }
@@ -593,7 +597,7 @@ public:
     {
         StreamString dump_stream;
         
-        dump_stream.Printf("0x%llx: EntityVariable\n", (unsigned long long)process_address + m_offset);
+        dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", process_address + m_offset);
         
         Error err;
                 
@@ -850,7 +854,7 @@ public:
     {
         StreamString dump_stream;
                 
-        dump_stream.Printf("0x%llx: EntityResultVariable\n", (unsigned long long)process_address + m_offset);
+        dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", process_address + m_offset);
         
         Error err;
         
@@ -967,7 +971,7 @@ public:
 
         if (log)
         {
-            log->Printf("EntitySymbol::Materialize [process_address = 0x%llx, m_symbol = %s]",
+            log->Printf("EntitySymbol::Materialize [process_address = 0x%" PRIx64 ", m_symbol = %s]",
                         (uint64_t)process_address,
                         m_symbol.GetName().AsCString());
         }
@@ -1010,7 +1014,7 @@ public:
 
         if (log)
         {
-            log->Printf("EntitySymbol::Dematerialize [process_address = 0x%llx, m_symbol = %s]",
+            log->Printf("EntitySymbol::Dematerialize [process_address = 0x%" PRIx64 ", m_symbol = %s]",
                         (uint64_t)process_address,
                         m_symbol.GetName().AsCString());
         }
@@ -1024,7 +1028,7 @@ public:
         
         Error err;
         
-        dump_stream.Printf("0x%llx: EntitySymbol (%s)\n", (unsigned long long)process_address + m_offset, m_symbol.GetName().AsCString());
+        dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", process_address + m_offset, m_symbol.GetName().AsCString());
         
         {
             dump_stream.Printf("Pointer:\n");
@@ -1085,7 +1089,7 @@ public:
         
         if (log)
         {
-            log->Printf("EntityRegister::Materialize [process_address = 0x%llx, m_register_info = %s]",
+            log->Printf("EntityRegister::Materialize [process_address = 0x%" PRIx64 ", m_register_info = %s]",
                         (uint64_t)process_address,
                         m_register_info.name);
         }
@@ -1138,7 +1142,7 @@ public:
         
         if (log)
         {
-            log->Printf("EntityRegister::Dematerialize [process_address = 0x%llx, m_register_info = %s]",
+            log->Printf("EntityRegister::Dematerialize [process_address = 0x%" PRIx64 ", m_register_info = %s]",
                         (uint64_t)process_address,
                         m_register_info.name);
         }
@@ -1178,7 +1182,7 @@ public:
         
         Error err;
         
-        dump_stream.Printf("0x%llx: EntityRegister (%s)\n", (unsigned long long)process_address + m_offset, m_register_info.name);
+        dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", process_address + m_offset, m_register_info.name);
         
         {
             dump_stream.Printf("Value:\n");
@@ -1271,7 +1275,7 @@ Materializer::Materialize (lldb::StackFr
     
     if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
     {
-        log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%llx) materialized:", frame_sp.get(), process_address);
+        log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64 ") materialized:", frame_sp.get(), process_address);
         for (EntityUP &entity_up : m_entities)
             entity_up->DumpToLog(map, process_address, log);
     }
@@ -1303,7 +1307,7 @@ Materializer::Dematerializer::Dematerial
     {
         if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
         {
-            log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%llx) about to dematerialize:", frame_sp.get(), m_process_address);
+            log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%" PRIx64 ") about to dematerialize:", frame_sp.get(), m_process_address);
             for (EntityUP &entity_up : m_materializer->m_entities)
                 entity_up->DumpToLog(*m_map, m_process_address, log);
         }

Removed: lldb/branches/lldb-platform-work/source/Expression/ProcessDataAllocator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/ProcessDataAllocator.cpp?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Expression/ProcessDataAllocator.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/ProcessDataAllocator.cpp (removed)
@@ -1,43 +0,0 @@
-//===-- ProcessDataAllocator.cpp --------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Expression/ProcessDataAllocator.h"
-
-using namespace lldb_private;
-
-void
-ProcessDataAllocator::Dump(Stream &stream)
-{
-    size_t data_size = m_stream_string.GetSize();
-    
-    if (!m_allocation)
-        return;
-    
-    lldb::DataBufferSP data(new DataBufferHeap(data_size, 0));    
-    
-    Error error;
-    if (m_process.ReadMemory (m_allocation, data->GetBytes(), data_size, error) != data_size)
-        return;
-    
-    DataExtractor extractor(data, m_process.GetByteOrder(), m_process.GetAddressByteSize());
-    
-    extractor.Dump(&stream,                         // stream
-                   0,                               // offset
-                   lldb::eFormatBytesWithASCII,     // format
-                   1,                               // byte size of individual entries
-                   data_size,                       // number of entries
-                   16,                              // entries per line
-                   m_allocation,                    // address to print
-                   0,                               // bit size (bitfields only; 0 means ignore)
-                   0);                              // bit alignment (bitfields only; 0 means ignore)
-    
-    stream.PutChar('\n');
-}

Removed: lldb/branches/lldb-platform-work/source/Expression/RecordingMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Expression/RecordingMemoryManager.cpp?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Expression/RecordingMemoryManager.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Expression/RecordingMemoryManager.cpp (removed)
@@ -1,340 +0,0 @@
-//===-- RecordingMemoryManager.cpp ------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-// Project includes
-#include "lldb/Expression/RecordingMemoryManager.h"
-
-using namespace lldb_private;
-
-RecordingMemoryManager::RecordingMemoryManager () :
-    llvm::JITMemoryManager(),
-    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
-    m_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
-{
-}
-
-RecordingMemoryManager::~RecordingMemoryManager ()
-{
-}
-
-void
-RecordingMemoryManager::setMemoryWritable ()
-{
-    m_default_mm_ap->setMemoryWritable();
-}
-
-void
-RecordingMemoryManager::setMemoryExecutable ()
-{
-    m_default_mm_ap->setMemoryExecutable();
-}
-
-
-uint8_t *
-RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
-                     uintptr_t &ActualSize)
-{
-    return m_default_mm_ap->startFunctionBody(F, ActualSize);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
-                unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = StubSize;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
-                      F, StubSize, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-void
-RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
-               uint8_t *FunctionEnd)
-{
-    m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%llu, Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    allocation.m_section_id = SectionID;
-    allocation.m_executable = true;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    allocation.m_section_id = SectionID;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value; 
-}
-
-uint8_t *
-RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%llx, Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-
-    return return_value;
-}
-
-void
-RecordingMemoryManager::deallocateFunctionBody(void *Body)
-{
-    m_default_mm_ap->deallocateFunctionBody(Body);
-}
-
-uint8_t*
-RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
-                       uintptr_t &ActualSize)
-{
-    return m_default_mm_ap->startExceptionTable(F, ActualSize);
-}
-
-void
-RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
-                 uint8_t *TableEnd, uint8_t* FrameRegister)
-{
-    m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
-}
-
-void
-RecordingMemoryManager::deallocateExceptionTable(void *ET)
-{
-    m_default_mm_ap->deallocateExceptionTable (ET);
-}
-
-lldb::addr_t
-RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return ai->m_remote_start + (local_address - ai->m_local_start);
-    }
-
-    return LLDB_INVALID_ADDRESS;
-}
-
-RecordingMemoryManager::AddrRange
-RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return AddrRange(ai->m_remote_start, ai->m_size);
-    }
-    
-    return AddrRange (0, 0);
-}
-
-bool
-RecordingMemoryManager::CommitAllocations (Process &process)
-{
-    bool ret = true;
-    
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (ai->m_allocated)
-            continue;
-        
-        lldb_private::Error err;
-        
-        size_t allocation_size = (ai->m_size ? ai->m_size : 1) + ai->m_alignment - 1;
-        
-        if (allocation_size == 0)
-            allocation_size = 1;
-        
-        ai->m_remote_allocation = process.AllocateMemory(
-            allocation_size,
-            ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable) 
-                             : (lldb::ePermissionsReadable | lldb::ePermissionsWritable), 
-            err);
-        
-        uint64_t mask = ai->m_alignment - 1;
-        
-        ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
-        
-        if (!err.Success())
-        {
-            ret = false;
-            break;
-        }
-        
-        ai->m_allocated = true;
-        
-        if (m_log)
-        {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
-            ai->dump(m_log);
-        }
-    }
-    
-    if (!ret)
-    {
-        for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
-             ai != ae;
-             ++ai)
-        {
-            if (ai->m_allocated)
-                process.DeallocateMemory(ai->m_remote_start);
-        }
-    }
-    
-    return ret;
-}
-
-void
-RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (!ai->m_allocated)
-            continue;
-        
-        engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
-    }
-}
-
-bool
-RecordingMemoryManager::WriteData (Process &process)
-{    
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (!ai->m_allocated)
-            return false;
-        
-        lldb_private::Error err;
-        
-        if (process.WriteMemory(ai->m_remote_start, 
-                                (void*)ai->m_local_start, 
-                                ai->m_size, 
-                                err) != ai->m_size ||
-            !err.Success())
-            return false;
-        
-        if (m_log)
-        {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
-            ai->dump(m_log);
-        }
-    }
-    
-    return true;
-}
-
-void 
-RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
-{
-    if (!log)
-        return;
-    
-    log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
-                (unsigned long long)m_local_start,
-                (unsigned long long)m_size,
-                (unsigned long long)m_remote_start,
-                (unsigned)m_alignment,
-                (unsigned)m_section_id);
-}

Modified: lldb/branches/lldb-platform-work/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/File.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/File.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/File.cpp Thu Jun  6 19:06:43 2013
@@ -89,9 +89,7 @@ File::File (const FileSpec& filespec,
 {
     if (filespec)
     {
-        std::string path;
-        filespec.GetPath(path);
-        Open (path.c_str(), options, permissions);
+        Open (filespec.GetPath().c_str(), options, permissions);
     }
 }
 
@@ -263,6 +261,53 @@ File::Open (const char *path, uint32_t o
     return error;
 }
 
+uint32_t
+File::GetPermissions (const char *path, Error &error)
+{
+    if (path && path[0])
+    {
+        struct stat file_stats;
+        if (::stat (path, &file_stats) == -1)
+            error.SetErrorToErrno();
+        else
+        {
+            error.Clear();
+            return file_stats.st_mode; // All bits from lldb_private::File::Permissions match those in POSIX mode bits
+        }
+    }
+    else
+    {
+        if (path)
+            error.SetErrorString ("invalid path");
+        else
+            error.SetErrorString ("empty path");        
+    }
+    return 0;
+}
+
+uint32_t
+File::GetPermissions(Error &error) const
+{
+    int fd = GetDescriptor();
+    if (fd != kInvalidDescriptor)
+    {
+        struct stat file_stats;
+        if (::fstat (fd, &file_stats) == -1)
+            error.SetErrorToErrno();
+        else
+        {
+            error.Clear();
+            return file_stats.st_mode; // All bits from lldb_private::File::Permissions match those in POSIX mode bits
+        }
+    }
+    else
+    {
+        error.SetErrorString ("invalid file descriptor");
+    }
+    return 0;
+}
+
+
 Error
 File::Close ()
 {
@@ -334,58 +379,109 @@ File::GetFileSpec (FileSpec &file_spec)
     return error;
 }
 
-Error
-File::SeekFromStart (off_t& offset)
+off_t
+File::SeekFromStart (off_t offset, Error *error_ptr)
 {
-    Error error;
+    off_t result = 0;
     if (DescriptorIsValid())
     {
-        offset = ::lseek (m_descriptor, offset, SEEK_SET);
+        result = ::lseek (m_descriptor, offset, SEEK_SET);
 
-        if (offset == -1)
-            error.SetErrorToErrno();
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    else 
+    else if (StreamIsValid ())
     {
-        error.SetErrorString("invalid file handle");
+        result = ::fseek(m_stream, offset, SEEK_SET);
+        
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    return error;
+    else if (error_ptr)
+    {
+        error_ptr->SetErrorString("invalid file handle");
+    }
+    return result;
 }
 
-Error
-File::SeekFromCurrent (off_t& offset)
+off_t
+File::SeekFromCurrent (off_t offset,  Error *error_ptr)
 {
-    Error error;
+    off_t result = -1;
     if (DescriptorIsValid())
     {
-        offset = ::lseek (m_descriptor, offset, SEEK_CUR);
+        result = ::lseek (m_descriptor, offset, SEEK_CUR);
         
-        if (offset == -1)
-            error.SetErrorToErrno();
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    else 
+    else if (StreamIsValid ())
     {
-        error.SetErrorString("invalid file handle");
+        result = ::fseek(m_stream, offset, SEEK_CUR);
+        
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    return error;
+    else if (error_ptr)
+    {
+        error_ptr->SetErrorString("invalid file handle");
+    }
+    return result;
 }
 
-Error
-File::SeekFromEnd (off_t& offset)
+off_t
+File::SeekFromEnd (off_t offset, Error *error_ptr)
 {
-    Error error;
+    off_t result = -1;
     if (DescriptorIsValid())
     {
-        offset = ::lseek (m_descriptor, offset, SEEK_CUR);
+        result = ::lseek (m_descriptor, offset, SEEK_END);
         
-        if (offset == -1)
-            error.SetErrorToErrno();
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    else 
+    else if (StreamIsValid ())
     {
-        error.SetErrorString("invalid file handle");
+        result = ::fseek(m_stream, offset, SEEK_END);
+        
+        if (error_ptr)
+        {
+            if (result == -1)
+                error_ptr->SetErrorToErrno();
+            else
+                error_ptr->Clear();
+        }
     }
-    return error;
+    else if (error_ptr)
+    {
+        error_ptr->SetErrorString("invalid file handle");
+    }
+    return result;
 }
 
 Error
@@ -554,7 +650,7 @@ File::Read (void *buf, size_t &num_bytes
 }
 
 Error
-File::Read (size_t &num_bytes, off_t &offset, DataBufferSP &data_buffer_sp)
+File::Read (size_t &num_bytes, off_t &offset, bool null_terminate, DataBufferSP &data_buffer_sp)
 {
     Error error;
     
@@ -572,8 +668,8 @@ File::Read (size_t &num_bytes, off_t &of
                     if (num_bytes > bytes_left)
                         num_bytes = bytes_left;
                         
-                    std::auto_ptr<DataBufferHeap> data_heap_ap;
-                    data_heap_ap.reset(new DataBufferHeap(num_bytes, '\0'));
+                    std::unique_ptr<DataBufferHeap> data_heap_ap;
+                    data_heap_ap.reset(new DataBufferHeap(num_bytes + (null_terminate ? 1 : 0), '\0'));
                         
                     if (data_heap_ap.get())
                     {
@@ -641,12 +737,12 @@ File::Write (const void *buf, size_t &nu
 //------------------------------------------------------------------
 // Print some formatted output to the stream.
 //------------------------------------------------------------------
-int
+size_t
 File::Printf (const char *format, ...)
 {
     va_list args;
     va_start (args, format);
-    int result = PrintfVarArg (format, args);
+    size_t result = PrintfVarArg (format, args);
     va_end (args);
     return result;
 }
@@ -654,10 +750,10 @@ File::Printf (const char *format, ...)
 //------------------------------------------------------------------
 // Print some formatted output to the stream.
 //------------------------------------------------------------------
-int
+size_t
 File::PrintfVarArg (const char *format, va_list args)
 {
-    int result = 0;
+    size_t result = 0;
     if (DescriptorIsValid())
     {
         char *s = NULL;
@@ -679,3 +775,51 @@ File::PrintfVarArg (const char *format,
     }
     return result;
 }
+
+mode_t
+File::ConvertOpenOptionsForPOSIXOpen (uint32_t open_options)
+{
+    mode_t mode = 0;
+    if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite)
+        mode |= O_RDWR;
+    else if (open_options & eOpenOptionWrite)
+        mode |= O_WRONLY;
+    
+    if (open_options & eOpenOptionAppend)
+        mode |= O_APPEND;
+
+    if (open_options & eOpenOptionTruncate)
+        mode |= O_TRUNC;
+
+    if (open_options & eOpenOptionNonBlocking)
+        mode |= O_NONBLOCK;
+
+    if (open_options & eOpenOptionCanCreateNewOnly)
+        mode |= O_CREAT | O_EXCL;
+    else if (open_options & eOpenOptionCanCreate)
+        mode |= O_CREAT;
+
+    return mode;
+}
+
+#define	O_RDONLY	0x0000		/* open for reading only */
+#define	O_WRONLY	0x0001		/* open for writing only */
+#define	O_RDWR		0x0002		/* open for reading and writing */
+#define	O_ACCMODE	0x0003		/* mask for above modes */
+#define	O_NONBLOCK	0x0004		/* no delay */
+#define	O_APPEND	0x0008		/* set append mode */
+#define	O_SYNC		0x0080		/* synch I/O file integrity */
+#define	O_SHLOCK	0x0010		/* open with shared file lock */
+#define	O_EXLOCK	0x0020		/* open with exclusive file lock */
+#define	O_ASYNC		0x0040		/* signal pgrp when data ready */
+#define	O_FSYNC		O_SYNC		/* source compatibility: do not use */
+#define O_NOFOLLOW  0x0100      /* don't follow symlinks */
+#define	O_CREAT		0x0200		/* create if nonexistant */
+#define	O_TRUNC		0x0400		/* truncate to zero length */
+#define	O_EXCL		0x0800		/* error if already exists */
+#define	O_EVTONLY	0x8000		/* descriptor requested for event notifications only */
+#define	O_NOCTTY	0x20000		/* don't assign controlling terminal */
+#define O_DIRECTORY	0x100000
+#define O_SYMLINK	0x200000	/* allow open of a symlink */
+#define O_DSYNC 	0x400000	/* synch I/O data integrity */
+#define	O_CLOEXEC	0x1000000	/* implicitly set FD_CLOEXEC */

Modified: lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/FileSpec.cpp Thu Jun  6 19:06:43 2013
@@ -29,12 +29,13 @@
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataBufferMemoryMap.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Stream.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Utility/CleanUp.h"
 
 using namespace lldb;
 using namespace lldb_private;
-using namespace std;
 
 static bool
 GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr)
@@ -109,7 +110,7 @@ FileSpec::ResolveUsername (const char *s
     }
     else
     {
-        int user_name_len = first_slash - src_path - 1;
+        size_t user_name_len = first_slash - src_path - 1;
         ::memcpy (user_home, src_path + 1, user_name_len);
         user_home[user_name_len] = '\0';
         user_name = user_home;
@@ -419,7 +420,7 @@ FileSpec::operator== (const FileSpec& rh
                 // rhs's path wasn't resolved but now it is. Check if the resolved
                 // directory is the same as rhs's unresolved directory, and if so, 
                 // we can mark this object as resolved to avoid more future resolves
-                rhs.m_is_resolved = (m_directory == resolved_rhs.m_directory);
+                rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
             }
             else
                 return false;
@@ -523,16 +524,14 @@ FileSpec::Equal (const FileSpec& a, cons
 void
 FileSpec::Dump(Stream *s) const
 {
-    if (m_filename)
-        m_directory.Dump(s, "");    // Provide a default for m_directory when we dump it in case it is invalid
-
-    if (m_directory)
+    static ConstString g_slash_only ("/");
+    if (s)
     {
-        // If dirname was valid, then we need to print a slash between
-        // the directory and the filename
-        s->PutChar('/');
+        m_directory.Dump(s);
+        if (m_directory && m_directory != g_slash_only)
+            s->PutChar('/');
+        m_filename.Dump(s);
     }
-    m_filename.Dump(s);
 }
 
 //------------------------------------------------------------------
@@ -676,34 +675,6 @@ FileSpec::GetFilename() const
     return m_filename;
 }
 
-size_t
-FileSpec::GetPath (std::string& path) const
-{
-    const char *dirname = m_directory.GetCString();
-    const char *filename = m_filename.GetCString();
-    
-    uint32_t max_len = (dirname ? strlen(dirname) : 0) + (filename ? strlen(filename) : 0) + 2;
-    
-    path.resize(max_len);
-        
-    if (dirname)
-    {
-        if (filename)
-            return ::snprintf (&path[0], max_len, "%s/%s", dirname, filename);
-        else
-            return ::snprintf (&path[0], max_len, "%s", dirname);
-    }
-    else if (filename)
-    {
-        return ::snprintf (&path[0], max_len, "%s", filename);
-    }
-    else
-    {
-        path.clear();
-        return 0;
-    }
-}
-
 //------------------------------------------------------------------
 // Extract the directory and path into a fixed buffer. This is
 // needed as the directory and path are stored in separate string
@@ -733,18 +704,35 @@ FileSpec::GetPath(char *path, size_t pat
     return 0;
 }
 
+std::string
+FileSpec::GetPath (void) const
+{
+    static ConstString g_slash_only ("/");
+    std::string path;
+    const char *dirname = m_directory.GetCString();
+    const char *filename = m_filename.GetCString();
+    if (dirname)
+    {
+        path.append (dirname);
+        if (filename && m_directory != g_slash_only)
+            path.append ("/");
+    }
+    if (filename)
+        path.append (filename);
+    return path;
+}
+
 ConstString
 FileSpec::GetFileNameExtension () const
 {
-    const char *filename = m_filename.GetCString();
-    if (filename == NULL)
-        return ConstString();
-    
-    const char* dot_pos = strrchr(filename, '.');
-    if (dot_pos == NULL)
-        return ConstString();
-    
-    return ConstString(dot_pos+1);
+    if (m_filename)
+    {
+        const char *filename = m_filename.GetCString();
+        const char* dot_pos = strrchr(filename, '.');
+        if (dot_pos && dot_pos[1] != '\0')
+            return ConstString(dot_pos+1);
+    }
+    return ConstString();
 }
 
 ConstString
@@ -776,10 +764,11 @@ DataBufferSP
 FileSpec::MemoryMapFileContents(off_t file_offset, size_t file_size) const
 {
     DataBufferSP data_sp;
-    auto_ptr<DataBufferMemoryMap> mmap_data(new DataBufferMemoryMap());
+    std::unique_ptr<DataBufferMemoryMap> mmap_data(new DataBufferMemoryMap());
     if (mmap_data.get())
     {
-        if (mmap_data->MemoryMapFromFileSpec (this, file_offset, file_size) >= file_size)
+        const size_t mapped_length = mmap_data->MemoryMapFromFileSpec (this, file_offset, file_size);
+        if (((file_size == SIZE_MAX) && (mapped_length > 0)) || (mapped_length >= file_size))
             data_sp.reset(mmap_data.release());
     }
     return data_sp;
@@ -846,7 +835,37 @@ FileSpec::ReadFileContents (off_t file_o
         File file;
         error = file.Open(resolved_path, File::eOpenOptionRead);
         if (error.Success())
-            error = file.Read (file_size, file_offset, data_sp);
+        {
+            const bool null_terminate = false;
+            error = file.Read (file_size, file_offset, null_terminate, data_sp);
+        }
+    }
+    else
+    {
+        error.SetErrorString("invalid file specification");
+    }
+    if (error_ptr)
+        *error_ptr = error;
+    return data_sp;
+}
+
+DataBufferSP
+FileSpec::ReadFileContentsAsCString(Error *error_ptr)
+{
+    Error error;
+    DataBufferSP data_sp;
+    char resolved_path[PATH_MAX];
+    if (GetPath(resolved_path, sizeof(resolved_path)))
+    {
+        File file;
+        error = file.Open(resolved_path, File::eOpenOptionRead);
+        if (error.Success())
+        {
+            off_t offset = 0;
+            size_t length = SIZE_MAX;
+            const bool null_terminate = true;
+            error = file.Read (length, offset, null_terminate, data_sp);
+        }
     }
     else
     {
@@ -864,7 +883,7 @@ FileSpec::ReadFileLines (STLStringArray
     char path[PATH_MAX];
     if (GetPath(path, sizeof(path)))
     {
-        ifstream file_stream (path);
+        std::ifstream file_stream (path);
 
         if (file_stream)
         {
@@ -892,8 +911,15 @@ FileSpec::EnumerateDirectory
         lldb_utility::CleanUp <DIR *, int> dir_path_dir (opendir(dir_path), NULL, closedir);
         if (dir_path_dir.is_valid())
         {
-            struct dirent* dp;
-            while ((dp = readdir(dir_path_dir.get())) != NULL)
+            long path_max = fpathconf (dirfd (dir_path_dir.get()), _PC_NAME_MAX);
+#if defined (__APPLE_) && defined (__DARWIN_MAXPATHLEN)
+            if (path_max < __DARWIN_MAXPATHLEN)
+                path_max = __DARWIN_MAXPATHLEN;
+#endif
+            struct dirent *buf, *dp;
+            buf = (struct dirent *) malloc (offsetof (struct dirent, d_name) + path_max + 1);
+
+            while (buf && readdir_r(dir_path_dir.get(), buf, &dp) == 0 && dp)
             {
                 // Only search directories
                 if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
@@ -939,7 +965,6 @@ FileSpec::EnumerateDirectory
                         
                         switch (result)
                         {
-                        default:
                         case eEnumerateDirectoryResultNext:  
                             // Enumerate next entry in the current directory. We just
                             // exit this switch and will continue enumerating the
@@ -956,6 +981,8 @@ FileSpec::EnumerateDirectory
                             {
                                 // The subdirectory returned Quit, which means to 
                                 // stop all directory enumerations at all levels.
+                                if (buf)
+                                    free (buf);
                                 return eEnumerateDirectoryResultQuit;
                             }
                             break;
@@ -963,14 +990,22 @@ FileSpec::EnumerateDirectory
                         case eEnumerateDirectoryResultExit:  // Exit from the current directory at the current level.
                             // Exit from this directory level and tell parent to 
                             // keep enumerating.
+                            if (buf)
+                                free (buf);
                             return eEnumerateDirectoryResultNext;
 
                         case eEnumerateDirectoryResultQuit:  // Stop directory enumerations at any level
+                            if (buf)
+                                free (buf);
                             return eEnumerateDirectoryResultQuit;
                         }
                     }
                 }
             }
+            if (buf)
+            {
+                free (buf);
+            }
         }
     }
     // By default when exiting a directory, we tell the parent enumeration
@@ -1112,3 +1147,48 @@ FileSpec::RemoveLastPathComponent ()
     else
         SetFile(m_directory.GetCString(),resolve);
 }
+//------------------------------------------------------------------
+/// Returns true if the filespec represents an implementation source
+/// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
+/// extension).
+///
+/// @return
+///     \b true if the filespec represents an implementation source
+///     file, \b false otherwise.
+//------------------------------------------------------------------
+bool
+FileSpec::IsSourceImplementationFile () const
+{
+    ConstString extension (GetFileNameExtension());
+    if (extension)
+    {
+        static RegularExpression g_source_file_regex ("^(c|m|mm|cpp|c\\+\\+|cxx|cc|cp|s|asm|f|f77|f90|f95|f03|for|ftn|fpp|ada|adb|ads)$",
+                                                      REG_EXTENDED | REG_ICASE);
+        return g_source_file_regex.Execute (extension.GetCString());
+    }
+    return false;
+}
+
+bool
+FileSpec::IsRelativeToCurrentWorkingDirectory () const
+{
+    const char *directory = m_directory.GetCString();
+    if (directory && directory[0])
+    {
+        // If the path doesn't start with '/' or '~', return true
+        switch (directory[0])
+        {
+        case '/':
+        case '~':
+            return false;
+        default:
+            return true;
+        }
+    }
+    else if (m_filename)
+    {
+        // No directory, just a basename, return true
+        return true;
+    }
+    return false;
+}

Modified: lldb/branches/lldb-platform-work/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Host.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Host.cpp Thu Jun  6 19:06:43 2013
@@ -7,53 +7,61 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "lldb/Host/Host.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Core/ThreadSafeSTLMap.h"
-#include "lldb/Host/Config.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/TargetList.h"
-
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MachO.h"
+#include "lldb/lldb-python.h"
 
+// C includes
 #include <dlfcn.h>
 #include <errno.h>
 #include <grp.h>
 #include <limits.h>
 #include <netdb.h>
 #include <pwd.h>
+#include <sys/sysctl.h>
 #include <sys/types.h>
-
+#include <unistd.h>
 
 #if defined (__APPLE__)
 
 #include <dispatch/dispatch.h>
 #include <libproc.h>
 #include <mach-o/dyld.h>
-#include <sys/sysctl.h>
+#include <mach/mach_port.h>
 
-
-#elif defined (__linux__)
+#elif defined (__linux__) || defined(__FreeBSD_kernel__)
+/*  Linux or the FreeBSD kernel with glibc (Debian KFreeBSD for example) */
 
 #include <sys/wait.h>
 
 #elif defined (__FreeBSD__)
 
 #include <sys/wait.h>
-#include <sys/sysctl.h>
 #include <pthread_np.h>
 
 #endif
 
+#include "lldb/Host/Host.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ThreadSafeSTLMap.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/TargetList.h"
+
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/ADT/Twine.h"
+
+
+
+
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -88,7 +96,7 @@ Host::StartMonitoringChildProcess
     info_ptr->monitor_signals = monitor_signals;
     
     char thread_name[256];
-    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
+    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
     thread = ThreadCreate (thread_name,
                            MonitorChildProcessThreadFunction,
                            info_ptr,
@@ -128,7 +136,7 @@ private:
 static void *
 MonitorChildProcessThreadFunction (void *arg)
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
     const char *function = __FUNCTION__;
     if (log)
         log->Printf ("%s (arg = %p) thread starting...", function, arg);
@@ -143,16 +151,21 @@ MonitorChildProcessThreadFunction (void
     delete info;
 
     int status = -1;
-    const int options = 0;
+#if defined (__FreeBSD__)
+    #define __WALL 0
+#endif
+    const int options = __WALL;
+
     while (1)
     {
         log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
         if (log)
-            log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options);
+            log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
 
         // Wait for all child processes
         ::pthread_testcancel ();
-        const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
+        // Get signals from all children with same process group of pid
+        const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
         ::pthread_testcancel ();
 
         if (wait_pid == -1)
@@ -160,9 +173,13 @@ MonitorChildProcessThreadFunction (void
             if (errno == EINTR)
                 continue;
             else
+            {
+                if (log)
+                    log->Printf ("%s (arg = %p) thread exiting because waitpid failed (%s)...", __FUNCTION__, arg, strerror(errno));
                 break;
+            }
         }
-        else if (wait_pid == pid)
+        else if (wait_pid > 0)
         {
             bool exited = false;
             int signal = 0;
@@ -183,8 +200,10 @@ MonitorChildProcessThreadFunction (void
             {
                 signal = WTERMSIG(status);
                 status_cstr = "SIGNALED";
-                exited = true;
-                exit_status = -1;
+                if (wait_pid == pid) {
+                    exited = true;
+                    exit_status = -1;
+                }
             }
             else
             {
@@ -197,7 +216,7 @@ MonitorChildProcessThreadFunction (void
 
                 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
                 if (log)
-                    log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+                    log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
                                  function,
                                  wait_pid,
                                  options,
@@ -211,15 +230,23 @@ MonitorChildProcessThreadFunction (void
                 {
                     bool callback_return = false;
                     if (callback)
-                        callback_return = callback (callback_baton, pid, exited, signal, exit_status);
+                        callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
                     
                     // If our process exited, then this thread should exit
-                    if (exited)
+                    if (exited && wait_pid == pid)
+                    {
+                        if (log)
+                            log->Printf ("%s (arg = %p) thread exiting because pid received exit signal...", __FUNCTION__, arg);
                         break;
+                    }
                     // If the callback returns true, it means this process should
                     // exit
                     if (callback_return)
+                    {
+                        if (log)
+                            log->Printf ("%s (arg = %p) thread exiting because callback returned true...", __FUNCTION__, arg);
                         break;
+                    }
                 }
             }
         }
@@ -331,6 +358,11 @@ Host::GetArchitecture (SystemDefaultArch
         g_host_arch_32.Clear();
         g_host_arch_64.Clear();
 
+        // If the OS is Linux, "unknown" in the vendor slot isn't what we want
+        // for the default triple.  It's probably an artifact of config.guess.
+        if (triple.getOS() == llvm::Triple::Linux && triple.getVendor() == llvm::Triple::UnknownVendor)
+            triple.setVendorName("");
+
         switch (triple.getArch())
         {
         default:
@@ -339,9 +371,14 @@ Host::GetArchitecture (SystemDefaultArch
             break;
 
         case llvm::Triple::x86_64:
+            g_host_arch_64.SetTriple(triple);
+            g_supports_64 = true;
+            g_host_arch_32.SetTriple(triple.get32BitArchVariant());
+            g_supports_32 = true;
+            break;
+
         case llvm::Triple::sparcv9:
         case llvm::Triple::ppc64:
-        case llvm::Triple::cellspu:
             g_host_arch_64.SetTriple(triple);
             g_supports_64 = true;
             break;
@@ -370,15 +407,9 @@ Host::GetVendorString()
     static ConstString g_vendor;
     if (!g_vendor)
     {
-#if defined (__APPLE__)
         const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
         const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
         g_vendor.SetCStringWithLength(str_ref.data(), str_ref.size());
-#elif defined (__linux__)
-        g_vendor.SetCString("gnu");
-#elif defined (__FreeBSD__)
-        g_vendor.SetCString("freebsd");
-#endif
     }
     return g_vendor;
 }
@@ -389,15 +420,9 @@ Host::GetOSString()
     static ConstString g_os_string;
     if (!g_os_string)
     {
-#if defined (__APPLE__)
         const ArchSpec &host_arch = GetArchitecture (eSystemDefaultArchitecture);
         const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
         g_os_string.SetCStringWithLength(str_ref.data(), str_ref.size());
-#elif defined (__linux__)
-        g_os_string.SetCString("linux");
-#elif defined (__FreeBSD__)
-        g_os_string.SetCString("freebsd");
-#endif
     }
     return g_os_string;
 }
@@ -424,7 +449,12 @@ lldb::tid_t
 Host::GetCurrentThreadID()
 {
 #if defined (__APPLE__)
-    return ::mach_thread_self();
+    // Calling "mach_port_deallocate()" bumps the reference count on the thread
+    // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
+    // count.
+    thread_port_t thread_self = mach_thread_self();
+    mach_port_deallocate(mach_task_self(), thread_self);
+    return thread_self;
 #elif defined(__FreeBSD__)
     return lldb::tid_t(pthread_getthreadid_np());
 #else
@@ -494,7 +524,8 @@ Host::WillTerminate ()
 {
 }
 
-#if !defined (__APPLE__) && !defined (__FreeBSD__) // see macosx/Host.mm
+#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__) // see macosx/Host.mm
+
 void
 Host::ThreadCreated (const char *thread_name)
 {
@@ -513,7 +544,7 @@ Host::GetEnvironment (StringList &env)
     return 0;
 }
 
-#endif
+#endif // #if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined (__linux__)
 
 struct HostThreadCreateInfo
 {
@@ -537,7 +568,7 @@ ThreadCreateTrampoline (thread_arg_t arg
     thread_func_t thread_fptr = info->thread_fptr;
     thread_arg_t thread_arg = info->thread_arg;
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
     if (log)
         log->Printf("thread created");
     
@@ -600,92 +631,44 @@ Host::ThreadJoin (lldb::thread_t thread,
     return err == 0;
 }
 
-// rdar://problem/8153284
-// Fixed a crasher where during shutdown, loggings attempted to access the
-// thread name but the static map instance had already been destructed.
-// So we are using a ThreadSafeSTLMap POINTER, initializing it with a
-// pthread_once action.  That map will get leaked.
-//
-// Another approach is to introduce a static guard object which monitors its
-// own destruction and raises a flag, but this incurs more overhead.
-
-static pthread_once_t g_thread_map_once = PTHREAD_ONCE_INIT;
-static ThreadSafeSTLMap<uint64_t, std::string> *g_thread_names_map_ptr;
 
-static void
-InitThreadNamesMap()
-{
-    g_thread_names_map_ptr = new ThreadSafeSTLMap<uint64_t, std::string>();
-}
-
-//------------------------------------------------------------------
-// Control access to a static file thread name map using a single
-// static function to avoid a static constructor.
-//------------------------------------------------------------------
-static const char *
-ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
-{
-    int success = ::pthread_once (&g_thread_map_once, InitThreadNamesMap);
-    if (success != 0)
-        return NULL;
-    
-    uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
-
-    if (get)
-    {
-        // See if the thread name exists in our thread name pool
-        std::string value;
-        bool found_it = g_thread_names_map_ptr->GetValueForKey (pid_tid, value);
-        if (found_it)
-            return value.c_str();
-        else
-            return NULL;
-    }
-    else if (name)
-    {
-        // Set the thread name
-        g_thread_names_map_ptr->SetValueForKey (pid_tid, std::string(name));
-    }
-    return NULL;
-}
-
-const char *
+std::string
 Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
 {
-    const char *name = ThreadNameAccessor (true, pid, tid, NULL);
-    if (name == NULL)
-    {
+    std::string thread_name;
 #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
-        // We currently can only get the name of a thread in the current process.
-        if (pid == Host::GetCurrentProcessID())
+    // We currently can only get the name of a thread in the current process.
+    if (pid == Host::GetCurrentProcessID())
+    {
+        char pthread_name[1024];
+        if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
         {
-            char pthread_name[1024];
-            if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
+            if (pthread_name[0])
             {
-                if (pthread_name[0])
-                {
-                    // Set the thread in our string pool
-                    ThreadNameAccessor (false, pid, tid, pthread_name);
-                    // Get our copy of the thread name string
-                    name = ThreadNameAccessor (true, pid, tid, NULL);
-                }
+                thread_name = pthread_name;
             }
-            
-            if (name == NULL)
+        }
+        else
+        {
+            dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
+            if (current_queue != NULL)
             {
-                dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
-                if (current_queue != NULL)
-                    name = dispatch_queue_get_label (current_queue);
+                const char *queue_name = dispatch_queue_get_label (current_queue);
+                if (queue_name && queue_name[0])
+                {
+                    thread_name = queue_name;
+                }
             }
         }
-#endif
     }
-    return name;
+#endif
+    return thread_name;
 }
 
-void
+bool
 Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
 {
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
     lldb::pid_t curr_pid = Host::GetCurrentProcessID();
     lldb::tid_t curr_tid = Host::GetCurrentThreadID();
     if (pid == LLDB_INVALID_PROCESS_ID)
@@ -694,14 +677,39 @@ Host::SetThreadName (lldb::pid_t pid, ll
     if (tid == LLDB_INVALID_THREAD_ID)
         tid = curr_tid;
 
-#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
     // Set the pthread name if possible
     if (pid == curr_pid && tid == curr_tid)
     {
-        ::pthread_setname_np (name);
+        if (::pthread_setname_np (name) == 0)
+            return true;
+    }
+    return false;
+#elif defined (__linux__)
+    void *fn = dlsym (RTLD_DEFAULT, "pthread_setname_np");
+    if (fn)
+    {
+        int (*pthread_setname_np_func)(pthread_t thread, const char *name);
+        *reinterpret_cast<void **> (&pthread_setname_np_func) = fn;
+
+        lldb::pid_t curr_pid = Host::GetCurrentProcessID();
+        lldb::tid_t curr_tid = Host::GetCurrentThreadID();
+
+        if (pid == LLDB_INVALID_PROCESS_ID)
+            pid = curr_pid;
+
+        if (tid == LLDB_INVALID_THREAD_ID)
+            tid = curr_tid;
+
+        if (pid == curr_pid)
+        {
+            if (pthread_setname_np_func (tid, name) == 0)
+                return true;
+        }
     }
+    return false;
+#else
+    return false;
 #endif
-    ThreadNameAccessor (false, pid, tid, name);
 }
 
 FileSpec
@@ -991,13 +999,6 @@ Host::GetLLDBPath (PathType path_type, F
 
     case ePathTypePythonDir:                
         {
-            // TODO: Anyone know how we can determine this for linux? Other systems?
-            // For linux and FreeBSD we are currently assuming the
-            // location of the lldb binary that contains this function is
-            // the directory that will contain a python directory which
-            // has our lldb module. This is how files get placed when
-            // compiling with Makefiles.
-
             static ConstString g_lldb_python_dir;
             if (!g_lldb_python_dir)
             {
@@ -1016,9 +1017,19 @@ Host::GetLLDBPath (PathType path_type, F
                         ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
                     }
 #else
+                    llvm::Twine python_version_dir;
+                    python_version_dir = "/python"
+                                       + llvm::Twine(PY_MAJOR_VERSION)
+                                       + "."
+                                       + llvm::Twine(PY_MINOR_VERSION)
+                                       + "/site-packages";
+
                     // We may get our string truncated. Should we protect
                     // this with an assert?
-                    ::strncat(raw_path, "/python", sizeof(raw_path) - strlen(raw_path) - 1);
+
+                    ::strncat(raw_path, python_version_dir.str().c_str(),
+                              sizeof(raw_path) - strlen(raw_path) - 1);
+
 #endif
                     FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
                     g_lldb_python_dir.SetCString(resolved_path);
@@ -1087,9 +1098,6 @@ Host::GetLLDBPath (PathType path_type, F
             // TODO: where would user LLDB plug-ins be located on linux? Other systems?
             return false;
         }
-    default:
-        assert (!"Unhandled PathType");
-        break;
     }
 
     return false;
@@ -1212,16 +1220,16 @@ Host::GetEffectiveGroupID ()
     return getegid();
 }
 
-#if !defined (__APPLE__) && !defined (__FreeBSD__)
+#if !defined (__APPLE__) && !defined(__linux__)
 uint32_t
 Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
 {
     process_infos.Clear();
     return process_infos.GetSize();
 }
-#endif
+#endif // #if !defined (__APPLE__) && !defined(__linux__)
 
-#if !defined (__APPLE__) && !defined (__FreeBSD__)
+#if !defined (__APPLE__) && !defined (__FreeBSD__) && !defined(__linux__)
 bool
 Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
 {
@@ -1230,6 +1238,14 @@ Host::GetProcessInfo (lldb::pid_t pid, P
 }
 #endif
 
+#if !defined(__linux__)
+bool
+Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
+{
+    return false;
+}
+#endif
+
 lldb::TargetSP
 Host::GetDummyTarget (lldb_private::Debugger &debugger)
 {
@@ -1242,7 +1258,7 @@ Host::GetDummyTarget (lldb_private::Debu
         if (!arch.IsValid())
             arch = Host::GetArchitecture ();
         Error err = debugger.GetTargetList().CreateTarget(debugger, 
-                                                          FileSpec(), 
+                                                          NULL,
                                                           arch.GetTriple().getTriple().c_str(),
                                                           false, 
                                                           NULL, 
@@ -1300,30 +1316,31 @@ Host::RunShellCommand (const char *comma
                        int *status_ptr,
                        int *signo_ptr,
                        std::string *command_output_ptr,
-                       uint32_t timeout_sec)
+                       uint32_t timeout_sec,
+                       const char *shell)
 {
     Error error;
     ProcessLaunchInfo launch_info;
-
-    const bool localhost = true;
-    const bool will_debug = false;
-    const bool first_arg_is_full_shell_command = true;
-
-#ifndef LLDB_DEFAULT_SHELL_COMMAND
-#define LLDB_DEFAULT_SHELL_COMMAND   "/bin/bash"
-#endif
-    const char* shell_cmd = ::getenv("SHELL");
-    if (shell_cmd == NULL)
-        shell_cmd = LLDB_DEFAULT_SHELL_COMMAND;
-
-    launch_info.SetShell(shell_cmd);
-    launch_info.GetArguments().AppendArgument(command);
-
-    if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
-                                                     localhost,
-                                                     will_debug,
-                                                          first_arg_is_full_shell_command))
-        return error;
+    if (shell && shell[0])
+    {
+        // Run the command in a shell
+        launch_info.SetShell(shell);
+        launch_info.GetArguments().AppendArgument(command);
+        const bool localhost = true;
+        const bool will_debug = false;
+        const bool first_arg_is_full_shell_command = true;
+        launch_info.ConvertArgumentsForLaunchingInShell (error,
+                                                         localhost,
+                                                         will_debug,
+                                                         first_arg_is_full_shell_command);
+    }
+    else
+    {
+        // No shell, just run it
+        Args args (command);
+        const bool first_arg_is_executable = true;
+        launch_info.SetArguments(args, first_arg_is_executable);
+    }
     
     if (working_dir)
         launch_info.SetWorkingDirectory(working_dir);
@@ -1347,7 +1364,7 @@ Host::RunShellCommand (const char *comma
     }
     
     // The process monitor callback will delete the 'shell_info_ptr' below...
-    std::auto_ptr<ShellInfo> shell_info_ap (new ShellInfo());
+    std::unique_ptr<ShellInfo> shell_info_ap (new ShellInfo());
     
     const bool monitor_signals = false;
     launch_info.SetMonitorProcessCallback(MonitorShellCommand, shell_info_ap.get(), monitor_signals);
@@ -1362,7 +1379,7 @@ Host::RunShellCommand (const char *comma
     {
         // The process successfully launched, so we can defer ownership of
         // "shell_info" to the MonitorShellCommand callback function that will
-        // get called when the process dies. We release the std::auto_ptr as it
+        // get called when the process dies. We release the unique pointer as it
         // doesn't need to delete the ShellInfo anymore.
         ShellInfo *shell_info = shell_info_ap.release();
         TimeValue timeout_time(TimeValue::Now());
@@ -1420,6 +1437,52 @@ Host::RunShellCommand (const char *comma
 }
 
 
+uint32_t
+Host::GetNumberCPUS ()
+{
+    static uint32_t g_num_cores = UINT32_MAX;
+    if (g_num_cores == UINT32_MAX)
+    {
+#if defined(__APPLE__) or defined (__linux__) or defined (__FreeBSD__)
+
+        g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
+        
+#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+        
+        // Header file for this might need to be included at the top of this file
+        SYSTEM_INFO system_info;
+        ::GetSystemInfo (&system_info);
+        g_num_cores = system_info.dwNumberOfProcessors;
+        
+#else
+        
+        // Assume POSIX support if a host specific case has not been supplied above
+        g_num_cores = 0;
+        int num_cores = 0;
+        size_t num_cores_len = sizeof(num_cores);
+        int mib[] = { CTL_HW, HW_AVAILCPU };
+        
+        /* get the number of CPUs from the system */
+        if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+        {
+            g_num_cores = num_cores;
+        }
+        else
+        {
+            mib[1] = HW_NCPU;
+            num_cores_len = sizeof(num_cores);
+            if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+            {
+                if (num_cores > 0)
+                    g_num_cores = num_cores;
+            }
+        }
+#endif
+    }
+    return g_num_cores;
+}
+
+
 
 #if !defined (__APPLE__)
 bool
@@ -1461,80 +1524,108 @@ FDToFileMap& GetFDToFileMap()
 lldb::user_id_t
 Host::OpenFile (const FileSpec& file_spec,
                 uint32_t flags,
-                mode_t mode)
+                mode_t mode,
+                Error &error)
 {
-    std::string path;
-    if (file_spec.GetPath(path) == 0)
+    std::string path (file_spec.GetPath());
+    if (path.empty())
+    {
+        error.SetErrorString("empty path");
         return UINT64_MAX;
-    FileSP file_sp(new File(path.c_str(),flags,mode));
+    }
+    FileSP file_sp(new File());
+    error = file_sp->Open(path.c_str(),flags,mode);
     if (file_sp->IsValid() == false)
         return UINT64_MAX;
-    uint32_t fd = file_sp->GetDescriptor();
+    lldb::user_id_t fd = file_sp->GetDescriptor();
     GetFDToFileMap()[fd] = file_sp;
     return fd;
 }
 
 bool
-Host::CloseFile (lldb::user_id_t fd)
+Host::CloseFile (lldb::user_id_t fd, Error &error)
 {
     if (fd == UINT64_MAX)
+    {
+        error.SetErrorString ("invalid file descriptor");
+        return false;
+    }
+    FDToFileMap& file_map = GetFDToFileMap();
+    FDToFileMap::iterator pos = file_map.find(fd);
+    if (pos == file_map.end())
+    {
+        error.SetErrorStringWithFormat ("invalid host file descriptor %lli", fd);
         return false;
-    FDToFileMap::iterator i = GetFDToFileMap().find(fd),
-    end = GetFDToFileMap().end();
-    if (i == end)
+    }
+    FileSP file_sp = pos->second;
+    if (!file_sp)
+    {
+        error.SetErrorString ("invalid host backing file");
         return false;
-    FileSP file_sp = i->second;
-    Error err;
-    if (file_sp)
-        err = file_sp->Close();
-    GetFDToFileMap().erase(i);
-    return err.Success();
+    }
+    error = file_sp->Close();
+    file_map.erase(pos);
+    return error.Success();
 }
 
-uint32_t
-Host::WriteFile (lldb::user_id_t fd, uint64_t offset, void* data, size_t data_len)
+uint64_t
+Host::WriteFile (lldb::user_id_t fd, uint64_t offset, const void* src, uint64_t src_len, Error &error)
 {
     if (fd == UINT64_MAX)
-        return UINT32_MAX;
-    FDToFileMap::iterator i = GetFDToFileMap().find(fd),
-    end = GetFDToFileMap().end();
-    if (i == end)
-        return UINT32_MAX;
-    FileSP file_sp = i->second;
-    off_t offset_ = offset;
-    Error err = file_sp->SeekFromStart(offset_);
-    if (err.Fail())
-        return UINT32_MAX;
+    {
+        error.SetErrorString ("invalid file descriptor");
+        return UINT64_MAX;
+    }
+    FDToFileMap& file_map = GetFDToFileMap();
+    FDToFileMap::iterator pos = file_map.find(fd);
+    if (pos == file_map.end())
+    {
+        error.SetErrorStringWithFormat("invalid host file descriptor %lli", fd);
+        return false;
+    }
+    FileSP file_sp = pos->second;
     if (!file_sp)
-        return UINT32_MAX;
-    size_t data_len_ = data_len;
-    err = file_sp->Write(data,data_len_);
-    if (err.Fail())
-        return UINT32_MAX;
-    return data_len_;
+    {
+        error.SetErrorString ("invalid host backing file");
+        return UINT64_MAX;
+    }
+    if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail())
+        return UINT64_MAX;
+    size_t bytes_written = src_len;
+    error = file_sp->Write(src, bytes_written);
+    if (error.Fail())
+        return UINT64_MAX;
+    return bytes_written;
 }
 
-uint32_t
-Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* data_ptr, size_t len_wanted)
+uint64_t
+Host::ReadFile (lldb::user_id_t fd, uint64_t offset, void* dst, uint64_t dst_len, Error &error)
 {
     if (fd == UINT64_MAX)
-        return UINT32_MAX;
-    FDToFileMap::iterator i = GetFDToFileMap().find(fd),
-    end = GetFDToFileMap().end();
-    if (i == end)
-        return UINT32_MAX;
-    FileSP file_sp = i->second;
-    off_t offset_ = offset;
-    Error err = file_sp->SeekFromStart(offset_);
-    if (err.Fail())
-        return UINT32_MAX;
+    {
+        error.SetErrorString ("invalid file descriptor");
+        return UINT64_MAX;
+    }
+    FDToFileMap& file_map = GetFDToFileMap();
+    FDToFileMap::iterator pos = file_map.find(fd);
+    if (pos == file_map.end())
+    {
+        error.SetErrorStringWithFormat ("invalid host file descriptor %lli", fd);
+        return false;
+    }
+    FileSP file_sp = pos->second;
     if (!file_sp)
-        return UINT32_MAX;
-    size_t len_wanted_ = len_wanted;
-    err = file_sp->Read(data_ptr,len_wanted_);
-    if (err.Fail())
-        return UINT32_MAX;
-    return len_wanted_;
+    {
+        error.SetErrorString ("invalid host backing file");
+        return UINT64_MAX;
+    }
+    if (file_sp->SeekFromStart(offset, &error) != offset || error.Fail())
+        return UINT64_MAX;
+    size_t bytes_read = dst_len;
+    error = file_sp->Read(dst ,bytes_read);
+    if (error.Fail())
+        return UINT64_MAX;
+    return bytes_read;
 }
 
 lldb::user_id_t
@@ -1555,11 +1646,9 @@ Host::CalculateMD5 (const FileSpec& file
                     uint64_t &high)
 {
 #if defined (__APPLE__)
-    std::string hash_string;
-    file_spec.GetPath(hash_string);
     StreamString md5_cmd_line;
-    md5_cmd_line.Printf("md5 -q %s",hash_string.c_str());
-    hash_string.clear();
+    md5_cmd_line.Printf("md5 -q '%s'", file_spec.GetPath().c_str());
+    std::string hash_string;
     Error err = Host::RunShellCommand(md5_cmd_line.GetData(), NULL, NULL, NULL, &hash_string, 60);
     if (err.Fail())
         return false;

Modified: lldb/branches/lldb-platform-work/source/Host/common/Mutex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Mutex.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Mutex.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Mutex.cpp Thu Jun  6 19:06:43 2013
@@ -27,6 +27,7 @@
 // Enable extra mutex error checking
 #ifdef LLDB_CONFIGURATION_DEBUG
 #define ENABLE_MUTEX_ERROR_CHECKING 1
+#include <inttypes.h>
 #endif
 
 #if ENABLE_MUTEX_ERROR_CHECKING
@@ -218,10 +219,6 @@ Mutex::Mutex (Mutex::Type type) :
     case eMutexTypeRecursive:
         err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
         break;
-
-    default:
-        err = -1;
-        break;
     }
     assert(err == 0);
     err = ::pthread_mutex_init (&m_mutex, &attr);
@@ -241,8 +238,8 @@ Mutex::Mutex (Mutex::Type type) :
 //----------------------------------------------------------------------
 Mutex::~Mutex()
 {
-    int err;
-    err = ::pthread_mutex_destroy (&m_mutex);
+    int err = ::pthread_mutex_destroy (&m_mutex);
+    assert(err == 0);
 #if ENABLE_MUTEX_ERROR_CHECKING
     if (err == 0)
         error_check_mutex (&m_mutex, eMutexActionDestroyed);
@@ -275,7 +272,7 @@ Mutex::GetMutex()
 int
 Mutex::Lock()
 {
-    DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
+    DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
 
 #if ENABLE_MUTEX_ERROR_CHECKING
     error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
@@ -291,7 +288,7 @@ Mutex::Lock()
         assert(err == 0);
     }
 #endif
-    DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+    DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
     return err;
 }
 
@@ -311,7 +308,7 @@ Mutex::TryLock(const char *failure_messa
 #endif
 
     int err = ::pthread_mutex_trylock (&m_mutex);
-    DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+    DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
     return err;
 }
 
@@ -340,7 +337,7 @@ Mutex::Unlock()
         assert(err == 0);
     }
 #endif
-    DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+    DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
     return err;
 }
 
@@ -356,6 +353,38 @@ TrackingMutex::Unlock ()
     assert (m_failure_message.empty());
     return Mutex::Unlock();
 }
+
+int
+LoggingMutex::Lock ()
+{
+    printf("locking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::Lock();
+    m_locked = true;
+    printf("%d\n",x);
+    return x;
+}
+
+int
+LoggingMutex::Unlock ()
+{
+    printf("unlocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::Unlock();
+    m_locked = false;
+    printf("%d\n",x);
+    return x;
+}
+
+int
+LoggingMutex::TryLock (const char *failure_message)
+{
+    printf("trylocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+    int x = Mutex::TryLock(failure_message);
+    if (x == 0)
+        m_locked = true;
+    printf("%d\n",x);
+    return x;
+}
+
 #endif
-    
+
 

Modified: lldb/branches/lldb-platform-work/source/Host/common/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Symbols.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Symbols.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Symbols.cpp Thu Jun  6 19:06:43 2013
@@ -28,4 +28,21 @@ Symbols::LocateExecutableSymbolFile (con
     return FileSpec();
 }
 
+FileSpec
+Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
+                                 const lldb_private::UUID *uuid,
+                                 const ArchSpec *arch)
+{
+    return FileSpec();
+}
+
+bool
+Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup)
+{
+    // Fill in the module_spec.GetFileSpec() for the object file and/or the
+    // module_spec.GetSymbolFileSpec() for the debug symbols file.
+    return false;
+}
+
+
 #endif

Modified: lldb/branches/lldb-platform-work/source/Host/common/Terminal.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/common/Terminal.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/common/Terminal.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/common/Terminal.cpp Thu Jun  6 19:06:43 2013
@@ -120,6 +120,15 @@ TerminalState::~TerminalState()
 {
 }
 
+void
+TerminalState::Clear ()
+{
+    m_tty.Clear();
+    m_tflags = -1;
+    m_termios_ap.reset();
+    m_process_group = -1;
+}
+
 //----------------------------------------------------------------------
 // Save the current state of the TTY for the file descriptor "fd"
 // and if "save_process_group" is true, attempt to save the process

Modified: lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/freebsd/Host.cpp Thu Jun  6 19:06:43 2013
@@ -377,14 +377,14 @@ GetFreeBSDProcessArgs (const ProcessInst
 {
     if (process_info.ProcessIDIsValid())
     {
-        int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, process_info.GetProcessID() };
+        int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, (int)process_info.GetProcessID() };
 
         char arg_data[8192];
         size_t arg_data_size = sizeof(arg_data);
         if (::sysctl (mib, 4, arg_data, &arg_data_size , NULL, 0) == 0)
         {
             DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *));
-            uint32_t offset = 0;
+            lldb::offset_t offset = 0;
             const char *cstr;
 
             cstr = data.GetCStr (&offset);
@@ -443,7 +443,7 @@ GetFreeBSDProcessUserAndGroup(ProcessIns
     if (process_info.ProcessIDIsValid()) 
     {
         int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID,
-            process_info.GetProcessID() };
+            (int)process_info.GetProcessID() };
         proc_kinfo_size = sizeof(struct kinfo_proc);
 
         if (::sysctl (mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
@@ -573,14 +573,14 @@ Host::GetAuxvData(lldb_private::Process
    struct ps_strings ps_strings;
    struct ptrace_io_desc pid;
    DataBufferSP buf_sp;
-   std::auto_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+   std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
 
    if (::sysctl(mib, 2, &ps_strings_addr, &ps_strings_size, NULL, 0) == 0) {
            pid.piod_op = PIOD_READ_D;
            pid.piod_addr = &ps_strings;
            pid.piod_offs = ps_strings_addr;
            pid.piod_len = sizeof(ps_strings);
-           if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, NULL)) {
+           if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
                    perror("failed to fetch ps_strings");
                    buf_ap.release();
                    goto done;
@@ -591,7 +591,7 @@ Host::GetAuxvData(lldb_private::Process
            pid.piod_addr = aux_info;
            pid.piod_offs = auxv_addr;
            pid.piod_len = sizeof(aux_info);
-           if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, NULL)) {
+           if (::ptrace(PT_IO, process->GetID(), (caddr_t)&pid, 0)) {
                    perror("failed to fetch aux_info");
                    buf_ap.release();
                    goto done;

Modified: lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/linux/Host.cpp Thu Jun  6 19:06:43 2013
@@ -12,9 +12,9 @@
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <dirent.h>
 #include <fcntl.h>
 
-
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
@@ -25,12 +25,184 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
 
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Symbol/ObjectFile.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
+typedef enum ProcessStateFlags
+{
+    eProcessStateRunning           = (1u << 0), // Running
+    eProcessStateSleeping          = (1u << 1), // Sleeping in an interruptible wait
+    eProcessStateWaiting           = (1u << 2), // Waiting in an uninterruptible disk sleep
+    eProcessStateZombie            = (1u << 3), // Zombie
+    eProcessStateTracedOrStopped   = (1u << 4), // Traced or stopped (on a signal)
+    eProcessStatePaging            = (1u << 5)  // Paging
+} ProcessStateFlags;
+
+typedef struct ProcessStatInfo
+{
+    lldb::pid_t ppid;           // Parent Process ID
+    uint32_t fProcessState;     // ProcessStateFlags
+} ProcessStatInfo;
+
+// Get the process info with additional information from /proc/$PID/stat (like process state, and tracer pid).
+static bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid);
+
+
+namespace
+{
+
+lldb::DataBufferSP
+ReadProcPseudoFile (lldb::pid_t pid, const char *name)
+{
+    int fd;
+    char path[PATH_MAX];
+
+    // Make sure we've got a nil terminated buffer for all the folks calling
+    // GetBytes() directly off our returned DataBufferSP if we hit an error.
+    lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
+
+    // Ideally, we would simply create a FileSpec and call ReadFileContents.
+    // However, files in procfs have zero size (since they are, in general,
+    // dynamically generated by the kernel) which is incompatible with the
+    // current ReadFileContents implementation. Therefore we simply stream the
+    // data into a DataBuffer ourselves.
+    if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
+    {
+        if ((fd = open (path, O_RDONLY, 0)) >= 0)
+        {
+            size_t bytes_read = 0;
+            std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+            for (;;) 
+            {
+                size_t avail = buf_ap->GetByteSize() - bytes_read;
+                ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
+
+                if (status < 0) 
+                    break;
+
+                if (status == 0) 
+                {
+                    buf_ap->SetByteSize (bytes_read);
+                    buf_sp.reset (buf_ap.release());
+                    break;
+                }
+
+                bytes_read += status;
+
+                if (avail - status == 0)
+                    buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
+            }
+
+            close (fd);
+        }
+    }
+
+    return buf_sp;
+}
+
+} // anonymous namespace
+
+static bool
+ReadProcPseudoFileStat (lldb::pid_t pid, ProcessStatInfo& stat_info)
+{
+    // Read the /proc/$PID/stat file.
+    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "stat");
+
+    // The filename of the executable is stored in parenthesis right after the pid. We look for the closing
+    // parenthesis for the filename and work from there in case the name has something funky like ')' in it.
+    const char *filename_end = strrchr ((const char *)buf_sp->GetBytes(), ')');
+    if (filename_end)
+    {
+        char state = '\0';
+        int ppid = LLDB_INVALID_PROCESS_ID;
+
+        // Read state and ppid.
+        sscanf (filename_end + 1, " %c %d", &state, &ppid);
+
+        stat_info.ppid = ppid;
+
+        switch (state)
+        {
+            case 'R':
+                stat_info.fProcessState |= eProcessStateRunning;
+                break;
+            case 'S':
+                stat_info.fProcessState |= eProcessStateSleeping;
+                break;
+            case 'D':
+                stat_info.fProcessState |= eProcessStateWaiting;
+                break;
+            case 'Z':
+                stat_info.fProcessState |= eProcessStateZombie;
+                break;
+            case 'T':
+                stat_info.fProcessState |= eProcessStateTracedOrStopped;
+                break;
+            case 'W':
+                stat_info.fProcessState |= eProcessStatePaging;
+                break;
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+static void
+GetLinuxProcessUserAndGroup (lldb::pid_t pid, ProcessInstanceInfo &process_info, lldb::pid_t &tracerpid)
+{
+    tracerpid = 0;
+    uint32_t rUid = UINT32_MAX;     // Real User ID
+    uint32_t eUid = UINT32_MAX;     // Effective User ID
+    uint32_t rGid = UINT32_MAX;     // Real Group ID
+    uint32_t eGid = UINT32_MAX;     // Effective Group ID
+
+    // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields.
+    lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "status");
+
+    static const char uid_token[] = "Uid:";
+    char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token);
+    if (buf_uid)
+    {
+        // Real, effective, saved set, and file system UIDs. Read the first two.
+        buf_uid += sizeof(uid_token);
+        rUid = strtol (buf_uid, &buf_uid, 10);
+        eUid = strtol (buf_uid, &buf_uid, 10);
+    }
+
+    static const char gid_token[] = "Gid:";
+    char *buf_gid = strstr ((char *)buf_sp->GetBytes(), gid_token);
+    if (buf_gid)
+    {
+        // Real, effective, saved set, and file system GIDs. Read the first two.
+        buf_gid += sizeof(gid_token);
+        rGid = strtol (buf_gid, &buf_gid, 10);
+        eGid = strtol (buf_gid, &buf_gid, 10);
+    }
+
+    static const char tracerpid_token[] = "TracerPid:";
+    char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token);
+    if (buf_tracerpid)
+    {
+        // Tracer PID. 0 if we're not being debugged.
+        buf_tracerpid += sizeof(tracerpid_token);
+        tracerpid = strtol (buf_tracerpid, &buf_tracerpid, 10);
+    }
+
+    process_info.SetUserID (rUid);
+    process_info.SetEffectiveUserID (eUid);
+    process_info.SetGroupID (rGid);
+    process_info.SetEffectiveGroupID (eGid);
+}
+
 bool
-Host::GetOSVersion(uint32_t &major, 
-                   uint32_t &minor, 
+Host::GetOSVersion(uint32_t &major,
+                   uint32_t &minor,
                    uint32_t &update)
 {
     struct utsname un;
@@ -40,7 +212,7 @@ Host::GetOSVersion(uint32_t &major,
         return false;
 
     status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update);
-     return status == 3;
+    return status == 3;
 }
 
 Error
@@ -54,45 +226,261 @@ Host::LaunchProcess (ProcessLaunchInfo &
 lldb::DataBufferSP
 Host::GetAuxvData(lldb_private::Process *process)
 {
-    static const size_t path_size = 128;
-    static char path[path_size];
-    lldb::DataBufferSP buf_sp;
+    return ReadProcPseudoFile(process->GetID(), "auxv");
+}
 
-    int fd;
+static bool
+IsDirNumeric(const char *dname)
+{
+    for (; *dname; dname++)
+    {
+        if (!isdigit (*dname))
+            return false;
+    }
+    return true;
+}
 
-    // Ideally, we would simply create a FileSpec and call ReadFileContents.
-    // However, files in procfs have zero size (since they are, in general,
-    // dynamically generated by the kernel) which is incompatible with the
-    // current ReadFileContents implementation.  Therefore we simply stream the
-    // data into a DataBuffer ourselves.
-    if (snprintf(path, path_size, "/proc/%d/auxv", process->GetID()) < 0)
-        return buf_sp;
+uint32_t
+Host::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos)
+{
+    static const char procdir[] = "/proc/";
+
+    DIR *dirproc = opendir (procdir);
+    if (dirproc)
+    {
+        struct dirent *direntry = NULL;
+        const uid_t our_uid = getuid();
+        const lldb::pid_t our_pid = getpid();
+        bool all_users = match_info.GetMatchAllUsers();
+
+        while ((direntry = readdir (dirproc)) != NULL)
+        {
+            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
+                continue;
 
-    if ((fd = open(path, O_RDONLY, 0)) < 0)
-        return buf_sp;
+            lldb::pid_t pid = atoi (direntry->d_name);
+
+            // Skip this process.
+            if (pid == our_pid)
+                continue;
+
+            lldb::pid_t tracerpid;
+            ProcessStatInfo stat_info;
+            ProcessInstanceInfo process_info;
+
+            if (!GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid))
+                continue;
+
+            // Skip if process is being debugged.
+            if (tracerpid != 0)
+                continue;
+
+            // Skip zombies.
+            if (stat_info.fProcessState & eProcessStateZombie)
+                continue;
+
+            // Check for user match if we're not matching all users and not running as root.
+            if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
+                continue;
+
+            if (match_info.Matches (process_info))
+            {
+                process_infos.Append (process_info);
+            }
+        }
+
+        closedir (dirproc);
+    }
 
-    size_t bytes_read = 0;
-    std::auto_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
-    for (;;) 
+    return process_infos.GetSize();
+}
+
+bool
+Host::FindProcessThreads (const lldb::pid_t pid, TidMap &tids_to_attach)
+{
+    bool tids_changed = false;
+    static const char procdir[] = "/proc/";
+    static const char taskdir[] = "/task/";
+    std::string process_task_dir = procdir + std::to_string(pid) + taskdir;
+    DIR *dirproc = opendir (process_task_dir.c_str());
+
+    if (dirproc)
     {
-        size_t avail = buf_ap->GetByteSize() - bytes_read;
-        ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
+        struct dirent *direntry = NULL;
+        while ((direntry = readdir (dirproc)) != NULL)
+        {
+            if (direntry->d_type != DT_DIR || !IsDirNumeric (direntry->d_name))
+                continue;
 
-        if (status < 0) 
-            break;
+            lldb::tid_t tid = atoi(direntry->d_name);
+            TidMap::iterator it = tids_to_attach.find(tid);
+            if (it == tids_to_attach.end())
+            {
+                tids_to_attach.insert(TidPair(tid, false));
+                tids_changed = true;
+            }
+        }
+        closedir (dirproc);
+    }
 
-        bytes_read += status;
+    return tids_changed;
+}
+
+static bool
+GetELFProcessCPUType (const char *exe_path, ProcessInstanceInfo &process_info)
+{
+    // Clear the architecture.
+    process_info.GetArchitecture().Clear();
 
-        if (status == 0) 
+    ModuleSpecList specs;
+    FileSpec filespec (exe_path, false);
+    const size_t num_specs = ObjectFile::GetModuleSpecifications (filespec, 0, specs);
+    // GetModuleSpecifications() could fail if the executable has been deleted or is locked.
+    // But it shouldn't return more than 1 architecture.
+    assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
+    if (num_specs == 1)
+    {
+        ModuleSpec module_spec;
+        if (specs.GetModuleSpecAtIndex (0, module_spec) && module_spec.GetArchitecture().IsValid())
         {
-            buf_ap->SetByteSize(bytes_read);
-            buf_sp.reset(buf_ap.release());
-            break;
+            process_info.GetArchitecture () = module_spec.GetArchitecture();
+            return true;
         }
+    }
+    return false;
+}
+
+static bool
+GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid)
+{
+    tracerpid = 0;
+    process_info.Clear();
+    ::memset (&stat_info, 0, sizeof(stat_info));
+    stat_info.ppid = LLDB_INVALID_PROCESS_ID;
+
+    // Use special code here because proc/[pid]/exe is a symbolic link.
+    char link_path[PATH_MAX];
+    char exe_path[PATH_MAX] = "";
+    if (snprintf (link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0)
+        return false;
+
+    ssize_t len = readlink (link_path, exe_path, sizeof(exe_path) - 1);
+    if (len <= 0)
+        return false;
+
+    // readlink does not append a null byte.
+    exe_path[len] = 0;
 
-        if (avail - status == 0)
-            buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
+    // If the binary has been deleted, the link name has " (deleted)" appended.
+    //  Remove if there.
+    static const ssize_t deleted_len = strlen(" (deleted)");
+    if (len > deleted_len &&
+        !strcmp(exe_path + len - deleted_len, " (deleted)"))
+    {
+        exe_path[len - deleted_len] = 0;
+    }
+    else
+    {
+        GetELFProcessCPUType (exe_path, process_info);
     }
 
-    return buf_sp;
+    process_info.SetProcessID(pid);
+    process_info.GetExecutableFile().SetFile(exe_path, false);
+
+    lldb::DataBufferSP buf_sp;
+
+    // Get the process environment.
+    buf_sp = ReadProcPseudoFile(pid, "environ");
+    Args &info_env = process_info.GetEnvironmentEntries();
+    char *next_var = (char *)buf_sp->GetBytes();
+    char *end_buf = next_var + buf_sp->GetByteSize();
+    while (next_var < end_buf && 0 != *next_var)
+    {
+        info_env.AppendArgument(next_var);
+        next_var += strlen(next_var) + 1;
+    }
+
+    // Get the commond line used to start the process.
+    buf_sp = ReadProcPseudoFile(pid, "cmdline");
+
+    // Grab Arg0 first.
+    char *cmd = (char *)buf_sp->GetBytes();
+    process_info.SetArg0(cmd);
+
+    // Now process any remaining arguments.
+    Args &info_args = process_info.GetArguments();
+    char *next_arg = cmd + strlen(cmd) + 1;
+    end_buf = cmd + buf_sp->GetByteSize();
+    while (next_arg < end_buf && 0 != *next_arg)
+    {
+        info_args.AppendArgument(next_arg);
+        next_arg += strlen(next_arg) + 1;
+    }
+
+    // Read /proc/$PID/stat to get our parent pid.
+    if (ReadProcPseudoFileStat (pid, stat_info))
+    {
+        process_info.SetParentProcessID (stat_info.ppid);
+    }
+
+    // Get User and Group IDs and get tracer pid.
+    GetLinuxProcessUserAndGroup (pid, process_info, tracerpid);
+
+    return true;
+}
+
+bool
+Host::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
+{
+    lldb::pid_t tracerpid;
+    ProcessStatInfo stat_info;
+
+    return GetProcessAndStatInfo (pid, process_info, stat_info, tracerpid);
+}
+
+void
+Host::ThreadCreated (const char *thread_name)
+{
+    if (!Host::SetThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, thread_name))
+    {
+        // pthread_setname_np_func can fail if the thread name is longer than
+        //  the supported limit on Linux. When this occurs, the error ERANGE is returned
+        // and SetThreadName will fail. Let's drop it down to 16 characters and try again.
+        char namebuf[16];
+
+        // Thread names are coming in like '<lldb.comm.debugger.edit>' and '<lldb.comm.debugger.editline>'
+        // So just chopping the end of the string off leads to a lot of similar named threads.
+        // Go through the thread name and search for the last dot and use that.
+        const char *lastdot = ::strrchr( thread_name, '.' );
+
+        if (lastdot && lastdot != thread_name)
+            thread_name = lastdot + 1;
+        ::strncpy (namebuf, thread_name, sizeof(namebuf));
+        namebuf[ sizeof(namebuf) - 1 ] = 0;
+
+        int namebuflen = strlen(namebuf);
+        if (namebuflen > 0)
+        {
+            if (namebuf[namebuflen - 1] == '(' || namebuf[namebuflen - 1] == '>')
+            {
+                // Trim off trailing '(' and '>' characters for a bit more cleanup.
+                namebuflen--;
+                namebuf[namebuflen] = 0;
+            }
+            Host::SetThreadName (LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID, namebuf);
+        }
+    }
+}
+
+void
+Host::Backtrace (Stream &strm, uint32_t max_frames)
+{
+    // TODO: Is there a way to backtrace the current process on linux?
+}
+
+size_t
+Host::GetEnvironment (StringList &env)
+{
+    // TODO: Is there a way to the host environment for this process on linux?
+    return 0;
 }

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Host.mm Thu Jun  6 19:06:43 2013
@@ -502,9 +502,8 @@ LaunchInNewTerminalWithAppleScript (cons
         
     if (!darwin_debug_file_spec.Exists())
     {
-        error.SetErrorStringWithFormat ("the 'darwin-debug' executable doesn't exists at %s/%s", 
-                                        darwin_debug_file_spec.GetDirectory().GetCString(),
-                                        darwin_debug_file_spec.GetFilename().GetCString());
+        error.SetErrorStringWithFormat ("the 'darwin-debug' executable doesn't exists at '%s'", 
+                                        darwin_debug_file_spec.GetPath().c_str());
         return error;
     }
     
@@ -523,10 +522,42 @@ LaunchInNewTerminalWithAppleScript (cons
     const char *working_dir = launch_info.GetWorkingDirectory();
     if (working_dir)
         command.Printf(" --working-dir '%s'", working_dir);
+    else
+    {
+        char cwd[PATH_MAX];
+        if (getcwd(cwd, PATH_MAX))
+            command.Printf(" --working-dir '%s'", cwd);
+    }
     
     if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR))
         command.PutCString(" --disable-aslr");
     
+    // We are launching on this host in a terminal. So compare the environemnt on the host
+    // to what is supplied in the launch_info. Any items that aren't in the host environemnt
+    // need to be sent to darwin-debug. If we send all environment entries, we might blow the
+    // max command line length, so we only send user modified entries.
+    const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector ();
+    StringList host_env;
+    const size_t host_env_count = Host::GetEnvironment (host_env);
+    const char *env_entry;
+    for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx)
+    {
+        bool add_entry = true;
+        for (size_t i=0; i<host_env_count; ++i)
+        {
+            const char *host_env_entry = host_env.GetStringAtIndex(i);
+            if (strcmp(env_entry, host_env_entry) == 0)
+            {
+                add_entry = false;
+                break;
+            }
+        }
+        if (add_entry)
+        {
+            command.Printf(" --env='%s'", env_entry);
+        }
+    }
+
     command.PutCString(" -- ");
 
     const char **argv = launch_info.GetArguments().GetConstArgumentVector ();
@@ -681,7 +712,7 @@ Host::OpenFileInExternalEditor (const Fi
         uint32_t  reserved2;  // must be zero
     } BabelAESelInfo;
     
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
     char file_path[PATH_MAX];
     file_spec.GetPath(file_path, PATH_MAX);
     CFCString file_cfstr (file_path, kCFStringEncodingUTF8);
@@ -1039,14 +1070,24 @@ GetMacOSXProcessCPUType (ProcessInstance
         mib_len++;
     
         cpu_type_t cpu, sub = 0;
-        size_t cpu_len = sizeof(cpu);
-        if (::sysctl (mib, mib_len, &cpu, &cpu_len, 0, 0) == 0)
+        size_t len = sizeof(cpu);
+        if (::sysctl (mib, mib_len, &cpu, &len, 0, 0) == 0)
         {
             switch (cpu)
             {
                 case llvm::MachO::CPUTypeI386:      sub = llvm::MachO::CPUSubType_I386_ALL;     break;
                 case llvm::MachO::CPUTypeX86_64:    sub = llvm::MachO::CPUSubType_X86_64_ALL;   break;
-                default: break;
+                case llvm::MachO::CPUTypeARM:
+                    {
+                        uint32_t cpusubtype = 0;
+                        len = sizeof(cpusubtype);
+                        if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
+                            sub = cpusubtype;
+                    }
+                    break;
+
+                default:
+                    break;
             }
             process_info.GetArchitecture ().SetArchitecture (eArchTypeMachO, cpu, sub);
             return true;
@@ -1069,7 +1110,7 @@ GetMacOSXProcessArgs (const ProcessInsta
         if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
         {
             DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *));
-            uint32_t offset = 0;
+            lldb::offset_t offset = 0;
             uint32_t argc = data.GetU32 (&offset);
             const char *cstr;
             
@@ -1291,7 +1332,7 @@ static Error
 getXPCAuthorization (ProcessLaunchInfo &launch_info)
 {
     Error error;
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
     
     if ((launch_info.GetUserID() == 0) && !authorizationRef)
     {
@@ -1302,7 +1343,7 @@ getXPCAuthorization (ProcessLaunchInfo &
             error.SetErrorString("Can't create authorizationRef.");
             if (log)
             {
-                error.PutToLog(log.get(), "%s", error.AsCString());
+                error.PutToLog(log, "%s", error.AsCString());
             }
             return error;
         }
@@ -1343,7 +1384,7 @@ getXPCAuthorization (ProcessLaunchInfo &
             error.SetErrorStringWithFormat("Launching as root needs root authorization.");
             if (log)
             {
-                error.PutToLog(log.get(), "%s", error.AsCString());
+                error.PutToLog(log, "%s", error.AsCString());
             }
             
             if (authorizationRef)
@@ -1366,8 +1407,8 @@ LaunchProcessXPC (const char *exe_path,
     if (error.Fail())
         return error;
     
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
-        
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+    
     uid_t requested_uid = launch_info.GetUserID();
     const char *xpc_service  = nil;
     bool send_auth = false;
@@ -1384,11 +1425,11 @@ LaunchProcessXPC (const char *exe_path,
         }
         else
         {
-            error.SetError(4, eErrorTypeGeneric);
+            error.SetError(3, eErrorTypeGeneric);
             error.SetErrorStringWithFormat("Launching root via XPC needs to externalize authorization reference.");
             if (log)
             {
-                error.PutToLog(log.get(), "%s", error.AsCString());
+                error.PutToLog(log, "%s", error.AsCString());
             }
             return error;
         }
@@ -1396,11 +1437,11 @@ LaunchProcessXPC (const char *exe_path,
     }
     else
     {
-        error.SetError(3, eErrorTypeGeneric);
+        error.SetError(4, eErrorTypeGeneric);
         error.SetErrorStringWithFormat("Launching via XPC is only currently available for either the login user or root.");
         if (log)
         {
-            error.PutToLog(log.get(), "%s", error.AsCString());
+            error.PutToLog(log, "%s", error.AsCString());
         }
         return error;
     }
@@ -1412,7 +1453,7 @@ LaunchProcessXPC (const char *exe_path,
         
         if (type == XPC_TYPE_ERROR) {
             if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
-                // The service has either canceled itself, crashed, or been terminated. 
+                // The service has either canceled itself, crashed, or been terminated.
                 // The XPC connection is still valid and sending a message to it will re-launch the service.
                 // If the service is state-full, this is the time to initialize the new service.
                 return;
@@ -1425,12 +1466,12 @@ LaunchProcessXPC (const char *exe_path,
                 // printf("Unexpected error from service: %s", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
             }
             
-        } else {			
+        } else {
             // printf("Received unexpected event in handler");
         }
     });
     
-        xpc_connection_set_finalizer_f (conn, xpc_finalizer_t(xpc_release));
+    xpc_connection_set_finalizer_f (conn, xpc_finalizer_t(xpc_release));
 	xpc_connection_resume (conn);
     xpc_object_t message = xpc_dictionary_create (nil, nil, 0);
     
@@ -1447,24 +1488,36 @@ LaunchProcessXPC (const char *exe_path,
     xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, GetPosixspawnFlags(launch_info));
     
     xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, message);
-    
-    pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey);
-    if (pid == 0)
+    xpc_type_t returnType = xpc_get_type(reply);
+    if (returnType == XPC_TYPE_DICTIONARY)
     {
-        int errorType = xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey);
-        int errorCode = xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey);
-        
-        error.SetError(errorCode, eErrorTypeGeneric);
-        error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode);
-        if (log)
+        pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey);
+        if (pid == 0)
         {
-            error.PutToLog(log.get(), "%s", error.AsCString());
+            int errorType = xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey);
+            int errorCode = xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey);
+            
+            error.SetError(errorCode, eErrorTypeGeneric);
+            error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode);
+            if (log)
+            {
+                error.PutToLog(log, "%s", error.AsCString());
+            }
+            
+            if (authorizationRef)
+            {
+                AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
+                authorizationRef = NULL;
+            }
         }
-        
-        if (authorizationRef)
+    }
+    else if (returnType == XPC_TYPE_ERROR)
+    {
+        error.SetError(5, eErrorTypeGeneric);
+        error.SetErrorStringWithFormat("Problems with launching via XPC. XPC error : %s", xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION));
+        if (log)
         {
-            AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
-            authorizationRef = NULL;
+            error.PutToLog(log, "%s", error.AsCString());
         }
     }
     
@@ -1479,13 +1532,13 @@ static Error
 LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
 {
     Error error;
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
     
     posix_spawnattr_t attr;
     error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
     
     if (error.Fail() || log)
-        error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
+        error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
     if (error.Fail())
         return error;
 
@@ -1503,7 +1556,7 @@ LaunchProcessPosixSpawn (const char *exe
     short flags = GetPosixspawnFlags(launch_info);
     error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
     if (error.Fail() || log)
-        error.PutToLog(log.get(), "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
+        error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
     if (error.Fail())
         return error;
     
@@ -1521,7 +1574,7 @@ LaunchProcessPosixSpawn (const char *exe
         size_t ocount = 0;
         error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
         if (error.Fail() || log)
-            error.PutToLog(log.get(), "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %zu )", cpu, ocount);
+            error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
         
         if (error.Fail() || ocount != 1)
             return error;
@@ -1542,7 +1595,6 @@ LaunchProcessPosixSpawn (const char *exe
         argv = (char * const*)tmp_argv;
     }
 
-
     const char *working_dir = launch_info.GetWorkingDirectory();
     if (working_dir)
     {
@@ -1565,7 +1617,7 @@ LaunchProcessPosixSpawn (const char *exe
         posix_spawn_file_actions_t file_actions;
         error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
         if (error.Fail() || log)
-            error.PutToLog(log.get(), "::posix_spawn_file_actions_init ( &file_actions )");
+            error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
         if (error.Fail())
             return error;
 
@@ -1580,7 +1632,7 @@ LaunchProcessPosixSpawn (const char *exe
             {
                 if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
                                                                              launch_file_action,
-                                                                             log.get(),
+                                                                             log,
                                                                              error))
                     return error;
             }
@@ -1595,13 +1647,21 @@ LaunchProcessPosixSpawn (const char *exe
                         eErrorTypePOSIX);
 
         if (error.Fail() || log)
-            error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", 
+        {
+            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
                            pid, 
                            exe_path, 
                            &file_actions, 
                            &attr, 
                            argv, 
                            envp);
+            if (log)
+            {
+                for (int ii=0; argv[ii]; ++ii)
+                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+            }
+        }
+
     }
     else
     {
@@ -1614,12 +1674,19 @@ LaunchProcessPosixSpawn (const char *exe
                         eErrorTypePOSIX);
 
         if (error.Fail() || log)
-            error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )", 
+        {
+            error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
                            pid, 
                            exe_path, 
                            &attr, 
                            argv, 
                            envp);
+            if (log)
+            {
+                for (int ii=0; argv[ii]; ++ii)
+                    log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+            }
+        }
     }
     
     if (working_dir)
@@ -1754,7 +1821,7 @@ Host::StartMonitoringChildProcess (Host:
     if (monitor_signals)
         mask |= DISPATCH_PROC_SIGNAL;
 
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
 
 
     dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC, 

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/Symbols.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/Symbols.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/Symbols.cpp Thu Jun  6 19:06:43 2013
@@ -11,6 +11,7 @@
 
 // C Includes
 #include <dirent.h>
+#include <pwd.h>
 #include "llvm/Support/MachO.h"
 
 // C++ Includes
@@ -22,12 +23,15 @@
 #include "lldb/Core/DataBuffer.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/UUID.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Utility/CleanUp.h"
 #include "Host/macosx/cfcpp/CFCBundle.h"
+#include "Host/macosx/cfcpp/CFCData.h"
 #include "Host/macosx/cfcpp/CFCReleaser.h"
 #include "Host/macosx/cfcpp/CFCString.h"
 #include "mach/machine.h"
@@ -54,7 +58,7 @@ SkinnyMachOFileContainsArchAndUUID
     const lldb_private::UUID *uuid,   // the UUID we are looking for
     off_t file_offset,
     DataExtractor& data,
-    uint32_t data_offset,
+    lldb::offset_t data_offset,
     const uint32_t magic
 )
 {
@@ -79,7 +83,7 @@ SkinnyMachOFileContainsArchAndUUID
     {
         ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
 
-        if (file_arch != *arch)
+        if (!file_arch.IsCompatibleMatch(*arch))
             return false;
     }
 
@@ -112,7 +116,7 @@ SkinnyMachOFileContainsArchAndUUID
 
     for (i=0; i<ncmds; i++)
     {
-        const uint32_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
+        const lldb::offset_t cmd_offset = data_offset;    // Save this data_offset in case parsing of the segment goes awry!
         uint32_t cmd        = data.GetU32(&data_offset);
         uint32_t cmd_size   = data.GetU32(&data_offset);
         if (cmd == LoadCommandUUID)
@@ -120,15 +124,6 @@ SkinnyMachOFileContainsArchAndUUID
             lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
             if (file_uuid == *uuid)
                 return true;
-
-            // Emit some warning messages since the UUIDs do not match!
-            char path_buf[PATH_MAX];
-            path_buf[0] = '\0';
-            const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
-                                                                     : file_spec.GetFilename().AsCString();
-            Host::SystemLog (Host::eSystemLogWarning, 
-                             "warning: UUID mismatch detected between binary and:\n\t'%s'\n", 
-                             path);
             return false;
         }
         data_offset = cmd_offset + cmd_size;
@@ -144,7 +139,7 @@ UniversalMachOFileContainsArchAndUUID
     const lldb_private::UUID *uuid,
     off_t file_offset,
     DataExtractor& data,
-    uint32_t data_offset,
+    lldb::offset_t data_offset,
     const uint32_t magic
 )
 {
@@ -174,7 +169,7 @@ UniversalMachOFileContainsArchAndUUID
         if (arch)
         {
             ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
-            if (fat_arch != *arch)
+            if (!fat_arch.IsExactMatch(*arch))
                 continue;
         }
 
@@ -182,7 +177,7 @@ UniversalMachOFileContainsArchAndUUID
         DataExtractor arch_data;
         DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
         arch_data.SetData(data_buffer_sp);
-        uint32_t arch_data_offset = 0;
+        lldb::offset_t arch_data_offset = 0;
         uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
 
         switch (arch_magic)
@@ -215,7 +210,7 @@ FileAtPathContainsArchAndUUID
     {
         data.SetData(data_buffer_sp);
 
-        uint32_t data_offset = 0;
+        lldb::offset_t data_offset = 0;
         uint32_t magic = data.GetU32(&data_offset);
 
         switch (magic)
@@ -239,12 +234,10 @@ FileAtPathContainsArchAndUUID
     return false;
 }
 
-static FileSpec
-LocateDSYMMachFileInDSYMBundle
-(
-    const FileSpec& dsym_bundle_fspec,
-    const lldb_private::UUID *uuid,
-    const ArchSpec *arch)
+FileSpec
+Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
+                                 const lldb_private::UUID *uuid,
+                                 const ArchSpec *arch)
 {
     char path[PATH_MAX];
 
@@ -352,11 +345,11 @@ LocateMacOSXFilesUsingDebugSymbols
                     {
                         if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
                         {
-                            out_dsym_fspec->SetFile(path, false);
+                            out_dsym_fspec->SetFile(path, path[0] == '~');
 
                             if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory)
                             {
-                                *out_dsym_fspec = LocateDSYMMachFileInDSYMBundle (*out_dsym_fspec, uuid, arch);
+                                *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch);
                                 if (*out_dsym_fspec)
                                     ++items_found;
                             }
@@ -371,10 +364,8 @@ LocateMacOSXFilesUsingDebugSymbols
                     CFDictionaryRef uuid_dict = NULL;
                     if (dict.get())
                     {
-                        char uuid_cstr_buf[64];
-                        const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf));
-                        CFCString uuid_cfstr (uuid_cstr);
-                        CFDictionaryRef uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
+                        CFCString uuid_cfstr (uuid->GetAsString().c_str());
+                        uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get()));
                         if (uuid_dict)
                         {
 
@@ -579,3 +570,232 @@ Symbols::LocateExecutableSymbolFile (con
     }
     return symbol_fspec;
 }
+
+
+static bool
+GetModuleSpecInfoFromUUIDDictionary (CFDictionaryRef uuid_dict, ModuleSpec &module_spec)
+{
+    bool success = false;
+    if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ())
+    {
+        std::string str;
+        CFStringRef cf_str;
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+                module_spec.GetFileSpec().SetFile (str.c_str(), true);
+        }
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+            {
+                module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true);
+                success = true;
+            }
+        }
+        
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGArchitecture"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            if (CFCString::FileSystemRepresentation(cf_str, str))
+                module_spec.GetArchitecture().SetTriple(str.c_str());
+        }
+
+        std::string DBGBuildSourcePath;
+        std::string DBGSourcePath;
+
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+        }
+
+        cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSourcePath"));
+        if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
+        {
+            CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+        }
+        
+        if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty())
+        {
+            module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true);
+        }
+    }
+    return success;
+}
+
+
+bool
+Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec, bool force_lookup)
+{
+    bool success = false;
+    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
+    const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+
+    // It's expensive to check for the DBGShellCommands defaults setting, only do it once per
+    // lldb run and cache the result.  
+    static bool g_have_checked_for_dbgshell_command = false;
+    static const char *g_dbgshell_command = NULL;
+    if (g_have_checked_for_dbgshell_command == false)
+    {
+        g_have_checked_for_dbgshell_command = true;
+        CFTypeRef defaults_setting = CFPreferencesCopyAppValue (CFSTR ("DBGShellCommands"), CFSTR ("com.apple.DebugSymbols"));
+        if (defaults_setting && CFGetTypeID (defaults_setting) == CFStringGetTypeID())
+        { 
+            char cstr_buf[PATH_MAX];
+            if (CFStringGetCString ((CFStringRef) defaults_setting, cstr_buf, sizeof (cstr_buf), kCFStringEncodingUTF8))
+            {
+                g_dbgshell_command = strdup (cstr_buf);  // this malloc'ed memory will never be freed
+            }
+        }
+        if (defaults_setting)
+        {
+            CFRelease (defaults_setting);
+        }
+    }
+
+    // When g_dbgshell_command is NULL, the user has not enabled the use of an external program
+    // to find the symbols, don't run it for them.
+    if (force_lookup == false && g_dbgshell_command == NULL)
+    {
+        return false;
+    }
+
+    if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists()))
+    {
+        static bool g_located_dsym_for_uuid_exe = false;
+        static bool g_dsym_for_uuid_exe_exists = false;
+        static char g_dsym_for_uuid_exe_path[PATH_MAX];
+        if (!g_located_dsym_for_uuid_exe)
+        {
+            g_located_dsym_for_uuid_exe = true;
+            const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
+            FileSpec dsym_for_uuid_exe_spec;
+            if (dsym_for_uuid_exe_path_cstr)
+            {
+                dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
+                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+            }
+            
+            if (!g_dsym_for_uuid_exe_exists)
+            {
+                dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
+                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+                if (!g_dsym_for_uuid_exe_exists)
+                {
+                    long bufsize;
+                    if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1)
+                    {
+                        char buffer[bufsize];
+                        struct passwd pwd;
+                        struct passwd *tilde_rc = NULL;
+                        // we are a library so we need to use the reentrant version of getpwnam()
+                        if (getpwnam_r ("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 
+                            && tilde_rc 
+                            && tilde_rc->pw_dir)
+                        {
+                            std::string dsymforuuid_path(tilde_rc->pw_dir);
+                            dsymforuuid_path += "/bin/dsymForUUID";
+                            dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false);
+                            g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+                        }
+                    }
+                }
+            }
+            if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL)
+            {
+                dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
+                g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+            }
+
+            if (g_dsym_for_uuid_exe_exists)
+                dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path));
+        }
+        if (g_dsym_for_uuid_exe_exists)
+        {
+            std::string uuid_str;
+            char file_path[PATH_MAX];
+            file_path[0] = '\0';
+
+            if (uuid_ptr)
+                uuid_str = uuid_ptr->GetAsString();
+
+            if (file_spec_ptr)
+                file_spec_ptr->GetPath(file_path, sizeof(file_path));
+            
+            StreamString command;
+            if (!uuid_str.empty())
+                command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_str.c_str());
+            else if (file_path && file_path[0])
+                command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, file_path);
+            
+            if (!command.GetString().empty())
+            {
+                int exit_status = -1;
+                int signo = -1;
+                std::string command_output;
+                Error error = Host::RunShellCommand (command.GetData(),
+                                                     NULL,              // current working directory
+                                                     &exit_status,      // Exit status
+                                                     &signo,            // Signal int *
+                                                     &command_output,   // Command output
+                                                     30,                // Large timeout to allow for long dsym download times
+                                                     NULL);             // Don't run in a shell (we don't need shell expansion)
+                if (error.Success() && exit_status == 0 && !command_output.empty())
+                {
+                    CFCData data (CFDataCreateWithBytesNoCopy (NULL,
+                                                               (const UInt8 *)command_output.data(),
+                                                               command_output.size(),
+                                                               kCFAllocatorNull));
+                    
+                    CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
+                    
+                    if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
+                    {
+                        if (!uuid_str.empty())
+                        {
+                            CFCString uuid_cfstr(uuid_str.c_str());
+                            CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue (plist.get(), uuid_cfstr.get());
+                            success = GetModuleSpecInfoFromUUIDDictionary (uuid_dict, module_spec);
+                        }
+                        else
+                        {
+                            const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
+                            if (num_values > 0)
+                            {
+                                std::vector<CFStringRef> keys (num_values, NULL);
+                                std::vector<CFDictionaryRef> values (num_values, NULL);
+                                ::CFDictionaryGetKeysAndValues(plist.get(), NULL, (const void **)&values[0]);
+                                if (num_values == 1)
+                                {
+                                    return GetModuleSpecInfoFromUUIDDictionary (values[0], module_spec);
+                                }
+                                else
+                                {
+                                    for (CFIndex i=0; i<num_values; ++i)
+                                    {
+                                        ModuleSpec curr_module_spec;
+                                        if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec))
+                                        {
+                                            if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture()))
+                                            {
+                                                module_spec = curr_module_spec;
+                                                return true;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return success;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp Thu Jun  6 19:06:43 2013
@@ -432,6 +432,44 @@ CFCMutableDictionary::SetValueUInt64(CFS
 }
 
 bool
+CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, bool can_create)
+{
+    CFMutableDictionaryRef dict = Dictionary(can_create);
+    if (dict != NULL)
+    {
+        // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+        // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+        CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+        if (cf_number.get())
+        {
+            // Let the dictionary own the CFNumber
+            ::CFDictionaryAddValue (dict, key, cf_number.get());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, bool can_create)
+{
+    CFMutableDictionaryRef dict = Dictionary(can_create);
+    if (dict != NULL)
+    {
+        // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+        // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+        CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+        if (cf_number.get())
+        {
+            // Let the dictionary own the CFNumber
+            ::CFDictionarySetValue (dict, key, cf_number.get());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
 CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, bool can_create)
 {
     CFMutableDictionaryRef dict = Dictionary(can_create);

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.h (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/cfcpp/CFCMutableDictionary.h Thu Jun  6 19:06:43 2013
@@ -53,6 +53,8 @@ public:
     bool    SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false);
     bool    AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
     bool    SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
+    bool    AddValueDouble(CFStringRef key, double value, bool can_create = false);
+    bool    SetValueDouble(CFStringRef key, double value, bool can_create = false);
     bool    AddValueCString(CFStringRef key, const char *cstr, bool can_create = false);
     bool    SetValueCString(CFStringRef key, const char *cstr, bool can_create = false);
     void    RemoveValue(const void *value);

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist Thu Jun  6 19:06:43 2013
@@ -25,7 +25,7 @@
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>165</string>
+	<string>300.99.0</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
 	<key>XPCService</key>
@@ -39,6 +39,8 @@
 		<string>root</string>
 		<key>ServiceType</key>
 		<string>Application</string>
+        <key>JoinExistingSession</key>
+        <true/>
 	</dict>
 </dict>
 </plist>

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist Thu Jun  6 19:06:43 2013
@@ -25,7 +25,7 @@
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>
-	<string>165</string>
+	<string>300.99.0</string>
 	<key>NSHumanReadableCopyright</key>
 	<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
 	<key>XPCService</key>

Modified: lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/main.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/main.mm?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/main.mm (original)
+++ lldb/branches/lldb-platform-work/source/Host/macosx/launcherXPCService/main.mm Thu Jun  6 19:06:43 2013
@@ -16,6 +16,7 @@
 #include <spawn.h>
 #include <signal.h>
 #include <assert.h>
+#include <sys/errno.h>
 #include "LauncherXPCService.h"
 
 // Declaration. Returns 0 if successful.
@@ -109,6 +110,31 @@ int get_args(xpc_object_t message, const
     return 0;
 }
 
+void _wait_for_child_exit(pid_t childPID)
+{
+    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, childPID, DISPATCH_PROC_EXIT, queue);
+    
+    if (source) {
+        dispatch_source_set_cancel_handler(source, ^{
+            dispatch_release(source);
+        });
+        
+        dispatch_source_set_event_handler(source, ^{
+            
+            // Either finding the process was successful, or the process disappeared before libdispatch got around to hooking up the source.
+            dispatch_source_cancel(source);
+            
+            int status, ret;
+            do {
+                ret = waitpid(childPID, &status, 0);
+            } while (ret < 0 && errno == EINTR);
+            
+        });
+        dispatch_resume(source);
+    }
+}
+
 static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event) 
 {
 	xpc_type_t type = xpc_get_type(event);
@@ -154,6 +180,10 @@ static void launcherXPC_peer_event_handl
                     
                     if (argvp) free(argvp);
                     if (envp) free(envp);
+                    
+                    if (errorCode == 0) {
+                        _wait_for_child_exit(childPID);
+                    }
                 }
             }
         }

Modified: lldb/branches/lldb-platform-work/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/Args.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/Args.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/Args.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 // C Includes
 #include <getopt.h>
 #include <cstdlib>
@@ -14,12 +16,17 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Interpreter/Args.h"
-#include "lldb/Core/FormatManager.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+//#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+//#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -91,24 +98,15 @@ Args::~Args ()
 void
 Args::Dump (Stream *s)
 {
-//    int argc = GetArgumentCount();
-//
-//    arg_sstr_collection::const_iterator pos, begin = m_args.begin(), end = m_args.end();
-//    for (pos = m_args.begin(); pos != end; ++pos)
-//    {
-//        s->Indent();
-//        s->Printf("args[%zu]=%s\n", std::distance(begin, pos), pos->c_str());
-//    }
-//    s->EOL();
-    const int argc = m_argv.size();
-    for (int i=0; i<argc; ++i)
+    const size_t argc = m_argv.size();
+    for (size_t i=0; i<argc; ++i)
     {
         s->Indent();
         const char *arg_cstr = m_argv[i];
         if (arg_cstr)
-            s->Printf("argv[%i]=\"%s\"\n", i, arg_cstr);
+            s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
         else
-            s->Printf("argv[%i]=NULL\n", i);
+            s->Printf("argv[%zi]=NULL\n", i);
     }
     s->EOL();
 }
@@ -117,8 +115,8 @@ bool
 Args::GetCommandString (std::string &command) const
 {
     command.clear();
-    int argc = GetArgumentCount();
-    for (int i=0; i<argc; ++i)
+    const size_t argc = GetArgumentCount();
+    for (size_t i=0; i<argc; ++i)
     {
         if (i > 0)
             command += ' ';
@@ -131,7 +129,7 @@ bool
 Args::GetQuotedCommandString (std::string &command) const
 {
     command.clear ();
-    size_t argc = GetArgumentCount ();
+    const size_t argc = GetArgumentCount();
     for (size_t i = 0; i < argc; ++i)
     {
         if (i > 0)
@@ -573,7 +571,7 @@ Args::DeleteArgumentAtIndex (size_t idx)
 }
 
 void
-Args::SetArguments (int argc, const char **argv)
+Args::SetArguments (size_t argc, const char **argv)
 {
     // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
     // no need to clear it here.
@@ -634,13 +632,16 @@ Args::ParseOptions (Options &options)
     {
         if (long_options[i].flag == NULL)
         {
-            sstr << (char)long_options[i].val;
-            switch (long_options[i].has_arg)
+            if (isprint8(long_options[i].val))
             {
-            default:
-            case no_argument:                       break;
-            case required_argument: sstr << ':';    break;
-            case optional_argument: sstr << "::";   break;
+                sstr << (char)long_options[i].val;
+                switch (long_options[i].has_arg)
+                {
+                default:
+                case no_argument:                       break;
+                case required_argument: sstr << ':';    break;
+                case optional_argument: sstr << "::";   break;
+                }
             }
         }
     }
@@ -654,8 +655,11 @@ Args::ParseOptions (Options &options)
     while (1)
     {
         int long_options_index = -1;
-        val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
-                            &long_options_index);
+        val = ::getopt_long_only(GetArgumentCount(),
+                                 GetArgumentVector(),
+                                 sstr.GetData(),
+                                 long_options,
+                                 &long_options_index);
         if (val == -1)
             break;
 
@@ -719,11 +723,12 @@ Args::StringToSInt32 (const char *s, int
     if (s && s[0])
     {
         char *end = NULL;
-        int32_t uval = ::strtol (s, &end, base);
+        const long sval = ::strtol (s, &end, base);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
-            return uval; // All characters were used, return the result
+            if (success_ptr)
+                *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN));
+            return (int32_t)sval; // All characters were used, return the result
         }
     }
     if (success_ptr) *success_ptr = false;
@@ -736,11 +741,12 @@ Args::StringToUInt32 (const char *s, uin
     if (s && s[0])
     {
         char *end = NULL;
-        uint32_t uval = ::strtoul (s, &end, base);
+        const unsigned long uval = ::strtoul (s, &end, base);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
-            return uval; // All characters were used, return the result
+            if (success_ptr)
+                *success_ptr = (uval <= UINT32_MAX);
+            return (uint32_t)uval; // All characters were used, return the result
         }
     }
     if (success_ptr) *success_ptr = false;
@@ -783,29 +789,150 @@ Args::StringToUInt64 (const char *s, uin
 }
 
 lldb::addr_t
-Args::StringToAddress (const char *s, lldb::addr_t fail_value, bool *success_ptr)
+Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr)
 {
+    bool error_set = false;
     if (s && s[0])
     {
         char *end = NULL;
         lldb::addr_t addr = ::strtoull (s, &end, 0);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
+            if (error_ptr)
+                error_ptr->Clear();
             return addr; // All characters were used, return the result
         }
         // Try base 16 with no prefix...
         addr = ::strtoull (s, &end, 16);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
+            if (error_ptr)
+                error_ptr->Clear();
             return addr; // All characters were used, return the result
         }
+        
+        if (exe_ctx)
+        {
+            Target *target = exe_ctx->GetTargetPtr();
+            if (target)
+            {
+                lldb::ValueObjectSP valobj_sp;
+                EvaluateExpressionOptions options;
+                options.SetCoerceToId(false);
+                options.SetUnwindOnError(true);
+                options.SetKeepInMemory(false);
+                options.SetRunOthers(true);
+                
+                ExecutionResults expr_result = target->EvaluateExpression(s,
+                                                                          exe_ctx->GetFramePtr(),
+                                                                          valobj_sp,
+                                                                          options);
+
+                bool success = false;
+                if (expr_result == eExecutionCompleted)
+                {
+                    // Get the address to watch.
+                    addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
+                    if (success)
+                    {
+                        if (error_ptr)
+                            error_ptr->Clear();
+                        return addr;
+                    }
+                    else
+                    {
+                        if (error_ptr)
+                        {
+                            error_set = true;
+                            error_ptr->SetErrorStringWithFormat("address expression \"%s\" resulted in a value whose type can't be converted to an address: %s", s, valobj_sp->GetTypeName().GetCString());
+                        }
+                    }
+                    
+                }
+                else
+                {
+                    // Since the compiler can't handle things like "main + 12" we should
+                    // try to do this for now. The compliler doesn't like adding offsets
+                    // to function pointer types.
+                    static RegularExpression g_symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+                    RegularExpression::Match regex_match(3);
+                    if (g_symbol_plus_offset_regex.Execute(s, &regex_match))
+                    {
+                        uint64_t offset = 0;
+                        bool add = true;
+                        std::string name;
+                        std::string str;
+                        if (regex_match.GetMatchAtIndex(s, 1, name))
+                        {
+                            if (regex_match.GetMatchAtIndex(s, 2, str))
+                            {
+                                add = str[0] == '+';
+                                
+                                if (regex_match.GetMatchAtIndex(s, 3, str))
+                                {
+                                    offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
+                                    
+                                    if (success)
+                                    {
+                                        Error error;
+                                        addr = StringToAddress (exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
+                                        if (addr != LLDB_INVALID_ADDRESS)
+                                        {
+                                            if (add)
+                                                return addr + offset;
+                                            else
+                                                return addr - offset;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    
+                    if (error_ptr)
+                    {
+                        error_set = true;
+                        error_ptr->SetErrorStringWithFormat("address expression \"%s\" evaluation failed", s);
+                    }
+                }
+            }
+        }
+    }
+    if (error_ptr)
+    {
+        if (!error_set)
+            error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s);
     }
-    if (success_ptr) *success_ptr = false;
     return fail_value;
 }
 
+const char *
+Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null_if_empty)
+{
+    static const char *k_white_space = " \t\v";
+    if (!s.empty())
+    {
+        if (leading)
+        {
+            size_t pos = s.find_first_not_of (k_white_space);
+            if (pos == std::string::npos)
+                s.clear();
+            else if (pos > 0)
+                s.erase(0, pos);
+        }
+        
+        if (trailing)
+        {
+            size_t rpos = s.find_last_not_of(k_white_space);
+            if (rpos != std::string::npos && rpos + 1 < s.size())
+                s.erase(rpos + 1);
+        }
+    }
+    if (return_null_if_empty && s.empty())
+        return NULL;
+    return s.c_str();
+}
+
 bool
 Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
 {
@@ -844,8 +971,7 @@ Args::StringToVersion (const char *s, ui
     if (s && s[0])
     {
         char *pos = NULL;
-        uint32_t uval32;
-        uval32 = ::strtoul (s, &pos, 0);
+        unsigned long uval32 = ::strtoul (s, &pos, 0);
         if (pos == s)
             return s;
         major = uval32;
@@ -895,7 +1021,7 @@ Args::GetShellSafeArgument (const char *
 }
 
 
-int32_t
+int64_t
 Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
 {    
     if (enum_values)
@@ -955,7 +1081,7 @@ Args::StringToFormat
 (
     const char *s,
     lldb::Format &format,
-    uint32_t *byte_size_ptr
+    size_t *byte_size_ptr
 )
 {
     format = eFormatInvalid;
@@ -1007,6 +1133,60 @@ Args::StringToFormat
     return error;
 }
 
+lldb::Encoding
+Args::StringToEncoding (const char *s, lldb::Encoding fail_value)
+{
+    if (s && s[0])
+    {
+        if (strcmp(s, "uint") == 0)
+            return eEncodingUint;
+        else if (strcmp(s, "sint") == 0)
+            return eEncodingSint;
+        else if (strcmp(s, "ieee754") == 0)
+            return eEncodingIEEE754;
+        else if (strcmp(s, "vector") == 0)
+            return eEncodingVector;
+    }
+    return fail_value;
+}
+
+uint32_t
+Args::StringToGenericRegister (const char *s)
+{
+    if (s && s[0])
+    {
+        if (strcmp(s, "pc") == 0)
+            return LLDB_REGNUM_GENERIC_PC;
+        else if (strcmp(s, "sp") == 0)
+            return LLDB_REGNUM_GENERIC_SP;
+        else if (strcmp(s, "fp") == 0)
+            return LLDB_REGNUM_GENERIC_FP;
+        else if (strcmp(s, "ra") == 0)
+            return LLDB_REGNUM_GENERIC_RA;
+        else if (strcmp(s, "flags") == 0)
+            return LLDB_REGNUM_GENERIC_FLAGS;
+        else if (strncmp(s, "arg", 3) == 0)
+        {
+            if (s[3] && s[4] == '\0')
+            {
+                switch (s[3])
+                {
+                    case '1': return LLDB_REGNUM_GENERIC_ARG1;
+                    case '2': return LLDB_REGNUM_GENERIC_ARG2;
+                    case '3': return LLDB_REGNUM_GENERIC_ARG3;
+                    case '4': return LLDB_REGNUM_GENERIC_ARG4;
+                    case '5': return LLDB_REGNUM_GENERIC_ARG5;
+                    case '6': return LLDB_REGNUM_GENERIC_ARG6;
+                    case '7': return LLDB_REGNUM_GENERIC_ARG7;
+                    case '8': return LLDB_REGNUM_GENERIC_ARG8;
+                }
+            }
+        }
+    }
+    return LLDB_INVALID_REGNUM;
+}
+
+
 void
 Args::LongestCommonPrefix (std::string &common_prefix)
 {
@@ -1047,7 +1227,7 @@ Args::FindArgumentIndexForOption (struct
 {
     char short_buffer[3];
     char long_buffer[255];
-    ::snprintf (short_buffer, sizeof (short_buffer), "-%c", (char) long_options[long_options_index].val);
+    ::snprintf (short_buffer, sizeof (short_buffer), "-%c", long_options[long_options_index].val);
     ::snprintf (long_buffer, sizeof (long_buffer),  "--%s", long_options[long_options_index].name);
     size_t end = GetArgumentCount ();
     size_t idx = 0;
@@ -1134,8 +1314,11 @@ Args::ParseAliasOptions (Options &option
     while (1)
     {
         int long_options_index = -1;
-        val = ::getopt_long (GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
-                             &long_options_index);
+        val = ::getopt_long_only (GetArgumentCount(),
+                                  GetArgumentVector(),
+                                  sstr.GetData(),
+                                  long_options,
+                                  &long_options_index);
 
         if (val == -1)
             break;
@@ -1171,7 +1354,7 @@ Args::ParseAliasOptions (Options &option
         if (long_options_index >= 0)
         {
             StreamString option_str;
-            option_str.Printf ("-%c", (char) val);
+            option_str.Printf ("-%c", val);
 
             switch (long_options[long_options_index].has_arg)
             {
@@ -1211,16 +1394,14 @@ Args::ParseAliasOptions (Options &option
                 }
                 break;
             default:
-                result.AppendErrorWithFormat
-                ("error with options table; invalid value in has_arg field for option '%c'.\n",
-                 (char) val);
+                result.AppendErrorWithFormat ("error with options table; invalid value in has_arg field for option '%c'.\n", val);
                 result.SetStatus (eReturnStatusFailed);
                 break;
             }
         }
         else
         {
-            result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", (char) val);
+            result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", val);
             result.SetStatus (eReturnStatusFailed);
         }
 
@@ -1314,8 +1495,8 @@ Args::ParseArgsForCompletion
     int val;
     const OptionDefinition *opt_defs = options.GetDefinitions();
 
-    // Fooey... getopt_long permutes the GetArgumentVector to move the options to the front.
-    // So we have to build another Arg and pass that to getopt_long so it doesn't
+    // Fooey... getopt_long_only permutes the GetArgumentVector to move the options to the front.
+    // So we have to build another Arg and pass that to getopt_long_only so it doesn't
     // change the one we have.
 
     std::vector<const char *> dummy_vec (GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1);
@@ -1326,14 +1507,13 @@ Args::ParseArgsForCompletion
     while (1)
     {
         bool missing_argument = false;
-        int parse_start = optind;
         int long_options_index = -1;
         
-        val = ::getopt_long (dummy_vec.size() - 1,
-                             (char *const *) &dummy_vec.front(), 
-                             sstr.GetData(), 
-                             long_options,
-                             &long_options_index);
+        val = ::getopt_long_only (dummy_vec.size() - 1,
+                                  (char *const *) &dummy_vec.front(),
+                                  sstr.GetData(),
+                                  long_options,
+                                  &long_options_index);
 
         if (val == -1)
         {
@@ -1347,7 +1527,7 @@ Args::ParseArgsForCompletion
             // Handling the "--" is a little tricky, since that may mean end of options or arguments, or the
             // user might want to complete options by long name.  I make this work by checking whether the
             // cursor is in the "--" argument, and if so I assume we're completing the long option, otherwise
-            // I let it pass to getopt_long which will terminate the option parsing.
+            // I let it pass to getopt_long_only which will terminate the option parsing.
             // Note, in either case we continue parsing the line so we can figure out what other options
             // were passed.  This will be useful when we come to restricting completions based on what other
             // options we've seen on the line.
@@ -1420,7 +1600,7 @@ Args::ParseArgsForCompletion
             switch (long_options[long_options_index].has_arg)
             {
             case no_argument:
-                option_element_vector.push_back (OptionArgElement (opt_defs_index, parse_start, 0));
+                option_element_vector.push_back (OptionArgElement (opt_defs_index, optind - 1, 0));
                 break;
             case required_argument:
                 if (optarg != NULL)
@@ -1463,7 +1643,7 @@ Args::ParseArgsForCompletion
     }
     
     // Finally we have to handle the case where the cursor index points at a single "-".  We want to mark that in
-    // the option_element_vector, but only if it is not after the "--".  But it turns out that getopt_long just ignores
+    // the option_element_vector, but only if it is not after the "--".  But it turns out that getopt_long_only just ignores
     // an isolated "-".  So we have to look it up by hand here.  We only care if it is AT the cursor position.
     
     if ((dash_dash_pos == -1 || cursor_index < dash_dash_pos)
@@ -1474,3 +1654,136 @@ Args::ParseArgsForCompletion
         
     }
 }
+
+void
+Args::EncodeEscapeSequences (const char *src, std::string &dst)
+{
+    dst.clear();
+    if (src)
+    {
+        for (const char *p = src; *p != '\0'; ++p)
+        {
+            size_t non_special_chars = ::strcspn (p, "\\");
+            if (non_special_chars > 0)
+            {
+                dst.append(p, non_special_chars);
+                p += non_special_chars;
+                if (*p == '\0')
+                    break;
+            }
+            
+            if (*p == '\\')
+            {
+                ++p; // skip the slash
+                switch (*p)
+                {
+                    case 'a' : dst.append(1, '\a'); break;
+                    case 'b' : dst.append(1, '\b'); break;
+                    case 'f' : dst.append(1, '\f'); break;
+                    case 'n' : dst.append(1, '\n'); break;
+                    case 'r' : dst.append(1, '\r'); break;
+                    case 't' : dst.append(1, '\t'); break;
+                    case 'v' : dst.append(1, '\v'); break;
+                    case '\\': dst.append(1, '\\'); break;
+                    case '\'': dst.append(1, '\''); break;
+                    case '"' : dst.append(1, '"'); break;
+                    case '0' :
+                        // 1 to 3 octal chars
+                    {
+                        // Make a string that can hold onto the initial zero char,
+                        // up to 3 octal digits, and a terminating NULL.
+                        char oct_str[5] = { '\0', '\0', '\0', '\0', '\0' };
+                        
+                        int i;
+                        for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
+                            oct_str[i] = p[i];
+                        
+                        // We don't want to consume the last octal character since
+                        // the main for loop will do this for us, so we advance p by
+                        // one less than i (even if i is zero)
+                        p += i - 1;
+                        unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
+                        if (octal_value <= UINT8_MAX)
+                        {
+                            dst.append(1, (char)octal_value);
+                        }
+                    }
+                        break;
+                        
+                    case 'x':
+                        // hex number in the format
+                        if (isxdigit(p[1]))
+                        {
+                            ++p;    // Skip the 'x'
+                            
+                            // Make a string that can hold onto two hex chars plus a
+                            // NULL terminator
+                            char hex_str[3] = { *p, '\0', '\0' };
+                            if (isxdigit(p[1]))
+                            {
+                                ++p; // Skip the first of the two hex chars
+                                hex_str[1] = *p;
+                            }
+                            
+                            unsigned long hex_value = strtoul (hex_str, NULL, 16);
+                            if (hex_value <= UINT8_MAX)
+                                dst.append (1, (char)hex_value);
+                        }
+                        else
+                        {
+                            dst.append(1, 'x');
+                        }
+                        break;
+                        
+                    default:
+                        // Just desensitize any other character by just printing what
+                        // came after the '\'
+                        dst.append(1, *p);
+                        break;
+                        
+                }
+            }
+        }
+    }
+}
+
+
+void
+Args::ExpandEscapedCharacters (const char *src, std::string &dst)
+{
+    dst.clear();
+    if (src)
+    {
+        for (const char *p = src; *p != '\0'; ++p)
+        {
+            if (isprint8(*p))
+                dst.append(1, *p);
+            else
+            {
+                switch (*p)
+                {
+                    case '\a': dst.append("\\a"); break;
+                    case '\b': dst.append("\\b"); break;
+                    case '\f': dst.append("\\f"); break;
+                    case '\n': dst.append("\\n"); break;
+                    case '\r': dst.append("\\r"); break;
+                    case '\t': dst.append("\\t"); break;
+                    case '\v': dst.append("\\v"); break;
+                    case '\'': dst.append("\\'"); break;
+                    case '"': dst.append("\\\""); break;
+                    case '\\': dst.append("\\\\"); break;
+                    default:
+                        {
+                            // Just encode as octal
+                            dst.append("\\0");
+                            char octal_str[32];
+                            snprintf(octal_str, sizeof(octal_str), "%o", *p);
+                            dst.append(octal_str);
+                        }
+                        break;
+                }
+            }
+        }
+    }
+}
+

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandInterpreter.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include <string>
 #include <vector>
 
@@ -26,6 +28,7 @@
 #include "../Commands/CommandObjectLog.h"
 #include "../Commands/CommandObjectMemory.h"
 #include "../Commands/CommandObjectPlatform.h"
+#include "../Commands/CommandObjectPlugin.h"
 #include "../Commands/CommandObjectProcess.h"
 #include "../Commands/CommandObjectQuit.h"
 #include "../Commands/CommandObjectRegister.h"
@@ -39,26 +42,48 @@
 #include "../Commands/CommandObjectVersion.h"
 #include "../Commands/CommandObjectWatchpoint.h"
 
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
+
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/InputReader.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/Timer.h"
+
 #include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/TargetList.h"
-#include "lldb/Utility/CleanUp.h"
 
-#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandCompletions.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/ScriptInterpreterNone.h"
 #include "lldb/Interpreter/ScriptInterpreterPython.h"
 
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/TargetList.h"
+
+#include "lldb/Utility/CleanUp.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
+
+static PropertyDefinition
+g_properties[] =
+{
+    { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." },
+    { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." },
+    { NULL                  , OptionValue::eTypeInvalid, true, 0    , NULL, NULL, NULL }
+};
+
+enum
+{
+    ePropertyExpandRegexAliases = 0,
+    ePropertyPromptOnQuit = 1
+};
+
 ConstString &
 CommandInterpreter::GetStaticBroadcasterClass ()
 {
@@ -73,6 +98,7 @@ CommandInterpreter::CommandInterpreter
     bool synchronous_execution
 ) :
     Broadcaster (&debugger, "lldb.command-interpreter"),
+    Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
     m_debugger (debugger),
     m_synchronous_execution (synchronous_execution),
     m_skip_lldbinit_files (false),
@@ -84,18 +110,26 @@ CommandInterpreter::CommandInterpreter
     m_truncation_warning(eNoTruncation),
     m_command_source_depth (0)
 {
-    const char *dbg_name = debugger.GetInstanceName().AsCString();
-    std::string lang_name = ScriptInterpreter::LanguageToString (script_language);
-    StreamString var_name;
-    var_name.Printf ("[%s].script-lang", dbg_name);
-    debugger.GetSettingsController()->SetVariable (var_name.GetData(), lang_name.c_str(), 
-                                                   eVarSetOperationAssign, false, 
-                                                   m_debugger.GetInstanceName().AsCString());                                                   
+    debugger.SetScriptLanguage (script_language);
     SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
     SetEventName (eBroadcastBitResetPrompt, "reset-prompt");
-    SetEventName (eBroadcastBitQuitCommandReceived, "quit");
-    
+    SetEventName (eBroadcastBitQuitCommandReceived, "quit");    
     CheckInWithManager ();
+    m_collection_sp->Initialize (g_properties);
+}
+
+bool
+CommandInterpreter::GetExpandRegexAliases () const
+{
+    const uint32_t idx = ePropertyExpandRegexAliases;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
+CommandInterpreter::GetPromptOnQuit () const
+{
+    const uint32_t idx = ePropertyPromptOnQuit;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
 }
 
 void
@@ -115,12 +149,18 @@ CommandInterpreter::Initialize ()
         AddAlias ("exit", cmd_obj_sp);
     }
     
-    cmd_obj_sp = GetCommandSPExact ("process attach", false);
+    cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false);
     if (cmd_obj_sp)
     {
         AddAlias ("attach", cmd_obj_sp);
     }
 
+    cmd_obj_sp = GetCommandSPExact ("process detach",false);
+    if (cmd_obj_sp)
+    {
+        AddAlias ("detach", cmd_obj_sp);
+    }
+
     cmd_obj_sp = GetCommandSPExact ("process continue", false);
     if (cmd_obj_sp)
     {
@@ -132,9 +172,9 @@ CommandInterpreter::Initialize ()
     if (cmd_obj_sp)
         AddAlias ("b", cmd_obj_sp);
 
-    cmd_obj_sp = GetCommandSPExact ("thread backtrace", false);
+    cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
     if (cmd_obj_sp)
-        AddAlias ("bt", cmd_obj_sp);
+        AddAlias ("tbreak", cmd_obj_sp);
 
     cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
     if (cmd_obj_sp)
@@ -176,13 +216,25 @@ CommandInterpreter::Initialize ()
         AddAlias ("f", cmd_obj_sp);
     }
 
-    cmd_obj_sp = GetCommandSPExact ("source list", false);
+    cmd_obj_sp = GetCommandSPExact ("thread select", false);
+    if (cmd_obj_sp)
+    {
+        AddAlias ("t", cmd_obj_sp);
+    }
+
+    cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
     if (cmd_obj_sp)
     {
         AddAlias ("l", cmd_obj_sp);
         AddAlias ("list", cmd_obj_sp);
     }
 
+    cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
+    if (cmd_obj_sp)
+    {
+        AddAlias ("env", cmd_obj_sp);
+    }
+
     cmd_obj_sp = GetCommandSPExact ("memory read", false);
     if (cmd_obj_sp)
         AddAlias ("x", cmd_obj_sp);
@@ -213,6 +265,10 @@ CommandInterpreter::Initialize ()
     if (cmd_obj_sp)
         AddAlias ("undisplay", cmd_obj_sp);
 
+    cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false);
+    if (cmd_obj_sp)
+        AddAlias ("bt", cmd_obj_sp);
+
     cmd_obj_sp = GetCommandSPExact ("target create", false);
     if (cmd_obj_sp)
         AddAlias ("file", cmd_obj_sp);
@@ -226,9 +282,7 @@ CommandInterpreter::Initialize ()
     
     cmd_obj_sp = GetCommandSPExact ("expression", false);
     if (cmd_obj_sp)
-    {
-        AddAlias ("expr", cmd_obj_sp);
-        
+    {        
         ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
         AddAlias ("p", cmd_obj_sp);
         AddAlias ("print", cmd_obj_sp);
@@ -238,14 +292,16 @@ CommandInterpreter::Initialize ()
         AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);
 
         alias_arguments_vector_sp.reset (new OptionArgVector);
-        ProcessAliasOptionsArgs (cmd_obj_sp, "-o --", alias_arguments_vector_sp);
+        ProcessAliasOptionsArgs (cmd_obj_sp, "-O -- ", alias_arguments_vector_sp);
         AddAlias ("po", cmd_obj_sp);
         AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
     }
     
     cmd_obj_sp = GetCommandSPExact ("process kill", false);
     if (cmd_obj_sp)
+    {
         AddAlias ("kill", cmd_obj_sp);
+    }
     
     cmd_obj_sp = GetCommandSPExact ("process launch", false);
     if (cmd_obj_sp)
@@ -273,8 +329,8 @@ CommandInterpreter::Initialize ()
     {
         alias_arguments_vector_sp.reset (new OptionArgVector);
         ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp);
-        AddAlias ("rb", cmd_obj_sp);
-        AddOrReplaceAliasOptions("rb", alias_arguments_vector_sp);
+        AddAlias ("rbreak", cmd_obj_sp);
+        AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp);
     }
 }
 
@@ -299,37 +355,19 @@ CommandInterpreter::LoadCommandDictionar
 {
     Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
 
-    // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
-    //
-    // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
-    // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
-    // the cross-referencing stuff) are created!!!
-    //
-    // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
-
-
-    // Command objects that inherit from CommandObjectCrossref must be created before other command objects
-    // are created.  This is so that when another command is created that needs to go into a crossref object,
-    // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
-    // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
-
-    // Non-CommandObjectCrossref commands can now be created.
-
     lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
     
     m_command_dict["apropos"]   = CommandObjectSP (new CommandObjectApropos (*this));
     m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
-    //m_command_dict["call"]      = CommandObjectSP (new CommandObjectCall (*this));
     m_command_dict["command"]   = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
     m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
     m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
-//    m_command_dict["file"]      = CommandObjectSP (new CommandObjectFile (*this));
     m_command_dict["frame"]     = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
     m_command_dict["help"]      = CommandObjectSP (new CommandObjectHelp (*this));
-    ///    m_command_dict["image"]     = CommandObjectSP (new CommandObjectImage (*this));
     m_command_dict["log"]       = CommandObjectSP (new CommandObjectLog (*this));
     m_command_dict["memory"]    = CommandObjectSP (new CommandObjectMemory (*this));
     m_command_dict["platform"]  = CommandObjectSP (new CommandObjectPlatform (*this));
+    m_command_dict["plugin"]    = CommandObjectSP (new CommandObjectPlugin (*this));
     m_command_dict["process"]   = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
     m_command_dict["quit"]      = CommandObjectSP (new CommandObjectQuit (*this));
     m_command_dict["register"]  = CommandObjectSP (new CommandObjectRegister (*this));
@@ -342,27 +380,94 @@ CommandInterpreter::LoadCommandDictionar
     m_command_dict["version"]   = CommandObjectSP (new CommandObjectVersion (*this));
     m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));
 
-    std::auto_ptr<CommandObjectRegexCommand>
+    const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
+                                      {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
+                                      {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
+                                      {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
+                                      {"^(-.*)$", "breakpoint set %1"},
+                                      {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
+                                      {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"},
+                                      {"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}};
+    
+    size_t num_regexes = sizeof break_regexes/sizeof(char *[2]);
+        
+    std::unique_ptr<CommandObjectRegexCommand>
     break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                       "_regexp-break",
-                                                      "Set a breakpoint using a regular expression to specify the location.",
-                                                      "_regexp-break [<filename>:<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
+                                                      "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
+                                                      "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
+                                                      2,
+                                                      CommandCompletions::eSymbolCompletion |
+                                                      CommandCompletions::eSourceFileCompletion));
+
     if (break_regex_cmd_ap.get())
     {
-        if (break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2") &&
-            break_regex_cmd_ap->AddRegexCommand("^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1") &&
-            break_regex_cmd_ap->AddRegexCommand("^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'") &&
-            break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full") &&
-            break_regex_cmd_ap->AddRegexCommand("^(-.*)$", "breakpoint set %1") &&
-            break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'") &&
-            break_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"))
+        bool success = true;
+        for (size_t i = 0; i < num_regexes; i++)
+        {
+            success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]);
+            if (!success)
+                break;
+        }
+        success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
+
+        if (success)
         {
             CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
             m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
         }
     }
 
-    std::auto_ptr<CommandObjectRegexCommand>
+    std::unique_ptr<CommandObjectRegexCommand>
+    tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                      "_regexp-tbreak",
+                                                      "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
+                                                      "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
+                                                       2,
+                                                       CommandCompletions::eSymbolCompletion |
+                                                       CommandCompletions::eSourceFileCompletion));
+
+    if (tbreak_regex_cmd_ap.get())
+    {
+        bool success = true;
+        for (size_t i = 0; i < num_regexes; i++)
+        {
+            // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer.
+            char buffer[1024];
+            int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
+            assert (num_printed < 1024);
+            success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer);
+            if (!success)
+                break;
+        }
+        success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");
+
+        if (success)
+        {
+            CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release());
+            m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp;
+        }
+    }
+
+    std::unique_ptr<CommandObjectRegexCommand>
+    attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                       "_regexp-attach",
+                                                       "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
+                                                       "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]",
+                                                       2));
+    if (attach_regex_cmd_ap.get())
+    {
+        if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
+            attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach'
+            attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") &&
+            attach_regex_cmd_ap->AddRegexCommand("^$", "process attach"))
+        {
+            CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release());
+            m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp;
+        }
+    }
+    
+    std::unique_ptr<CommandObjectRegexCommand>
     down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                      "_regexp-down",
                                                      "Go down \"n\" frames in the stack (1 frame by default).",
@@ -377,7 +482,7 @@ CommandInterpreter::LoadCommandDictionar
         }
     }
     
-    std::auto_ptr<CommandObjectRegexCommand>
+    std::unique_ptr<CommandObjectRegexCommand>
     up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                    "_regexp-up",
                                                    "Go up \"n\" frames in the stack (1 frame by default).",
@@ -392,11 +497,11 @@ CommandInterpreter::LoadCommandDictionar
         }
     }
 
-    std::auto_ptr<CommandObjectRegexCommand>
+    std::unique_ptr<CommandObjectRegexCommand>
     display_regex_cmd_ap(new CommandObjectRegexCommand (*this,
-                                                   "_regexp-display",
-                                                   "Add an expression evaluation stop-hook.",
-                                                   "_regexp-display expression", 2));
+                                                        "_regexp-display",
+                                                        "Add an expression evaluation stop-hook.",
+                                                        "_regexp-display expression", 2));
     if (display_regex_cmd_ap.get())
     {
         if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\""))
@@ -406,11 +511,11 @@ CommandInterpreter::LoadCommandDictionar
         }
     }
 
-    std::auto_ptr<CommandObjectRegexCommand>
+    std::unique_ptr<CommandObjectRegexCommand>
     undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this,
-                                                   "_regexp-undisplay",
-                                                   "Remove an expression evaluation stop-hook.",
-                                                   "_regexp-undisplay stop-hook-number", 2));
+                                                          "_regexp-undisplay",
+                                                          "Remove an expression evaluation stop-hook.",
+                                                          "_regexp-undisplay stop-hook-number", 2));
     if (undisplay_regex_cmd_ap.get())
     {
         if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1"))
@@ -420,6 +525,93 @@ CommandInterpreter::LoadCommandDictionar
         }
     }
 
+    std::unique_ptr<CommandObjectRegexCommand>
+    connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                             "gdb-remote",
+                                                             "Connect to a remote GDB server.  If no hostname is provided, localhost is assumed.",
+                                                             "gdb-remote [<hostname>:]<portnum>", 2));
+    if (connect_gdb_remote_cmd_ap.get())
+    {
+        if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") &&
+            connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1"))
+        {
+            CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release());
+            m_command_dict[command_sp->GetCommandName ()] = command_sp;
+        }
+    }
+
+    std::unique_ptr<CommandObjectRegexCommand>
+    connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                             "kdp-remote",
+                                                             "Connect to a remote KDP server.  udp port 41139 is the default port number.",
+                                                             "kdp-remote <hostname>[:<portnum>]", 2));
+    if (connect_kdp_remote_cmd_ap.get())
+    {
+        if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") &&
+            connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139"))
+        {
+            CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release());
+            m_command_dict[command_sp->GetCommandName ()] = command_sp;
+        }
+    }
+
+    std::unique_ptr<CommandObjectRegexCommand>
+    bt_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                     "_regexp-bt",
+                                                     "Show a backtrace.  An optional argument is accepted; if that argument is a number, it specifies the number of frames to display.  If that argument is 'all', full backtraces of all threads are displayed.",
+                                                     "bt [<digit>|all]", 2));
+    if (bt_regex_cmd_ap.get())
+    {
+        // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace
+        // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and
+        // so now "bt 3" is the preferred form, in line with gdb.
+        if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") &&
+            bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") &&
+            bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") &&
+            bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace"))
+        {
+            CommandObjectSP command_sp(bt_regex_cmd_ap.release());
+            m_command_dict[command_sp->GetCommandName ()] = command_sp;
+        }
+    }
+
+    std::unique_ptr<CommandObjectRegexCommand>
+    list_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                     "_regexp-list",
+                                                     "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
+                                                     "_regexp-list [<line>]\n_regexp-attach [<file>:<line>]\n_regexp-attach [<file>:<line>]",
+                                                     2,
+                                                     CommandCompletions::eSourceFileCompletion));
+    if (list_regex_cmd_ap.get())
+    {
+        if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
+            list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") &&
+            list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") &&
+            list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") &&
+            list_regex_cmd_ap->AddRegexCommand("^-([[:digit:]]+)[[:space:]]*$", "source list --reverse --count %1") &&
+            list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") &&
+            list_regex_cmd_ap->AddRegexCommand("^$", "source list"))
+        {
+            CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release());
+            m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp;
+        }
+    }
+
+    std::unique_ptr<CommandObjectRegexCommand>
+    env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+                                                    "_regexp-env",
+                                                    "Implements a shortcut to viewing and setting environment variables.",
+                                                    "_regexp-env\n_regexp-env FOO=BAR", 2));
+    if (env_regex_cmd_ap.get())
+    {
+        if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
+            env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1"))
+        {
+            CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release());
+            m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp;
+        }
+    }
+
 }
 
 int
@@ -440,7 +632,7 @@ CommandObjectSP
 CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
 {
     CommandObject::CommandMap::iterator pos;
-    CommandObjectSP ret_val;
+    CommandObjectSP command_sp;
 
     std::string cmd(cmd_cstr);
 
@@ -448,24 +640,24 @@ CommandInterpreter::GetCommandSP (const
     {
         pos = m_command_dict.find(cmd);
         if (pos != m_command_dict.end())
-            ret_val = pos->second;
+            command_sp = pos->second;
     }
 
     if (include_aliases && HasAliases())
     {
         pos = m_alias_dict.find(cmd);
         if (pos != m_alias_dict.end())
-            ret_val = pos->second;
+            command_sp = pos->second;
     }
 
     if (HasUserCommands())
     {
         pos = m_user_dict.find(cmd);
         if (pos != m_user_dict.end())
-            ret_val = pos->second;
+            command_sp = pos->second;
     }
 
-    if (!exact && !ret_val)
+    if (!exact && !command_sp)
     {
         // We will only get into here if we didn't find any exact matches.
         
@@ -535,13 +727,13 @@ CommandInterpreter::GetCommandSP (const
                 return user_match_sp;
         }
     }
-    else if (matches && ret_val)
+    else if (matches && command_sp)
     {
         matches->AppendString (cmd_cstr);
     }
 
 
-    return ret_val;
+    return command_sp;
 }
 
 bool
@@ -550,11 +742,11 @@ CommandInterpreter::AddCommand (const ch
     if (name && name[0])
     {
         std::string name_sstr(name);
-        if (!can_replace)
-        {
-            if (m_command_dict.find (name_sstr) != m_command_dict.end())
-                return false;
-        }
+        bool found = (m_command_dict.find (name_sstr) != m_command_dict.end());
+        if (found && !can_replace)
+            return false;
+        if (found && m_command_dict[name_sstr]->IsRemovable() == false)
+            return false;
         m_command_dict[name_sstr] = cmd_sp;
         return true;
     }
@@ -573,11 +765,21 @@ CommandInterpreter::AddUserCommand (std:
         
         // do not allow replacement of internal commands
         if (CommandExists(name_cstr))
-            return false;
+        {
+            if (can_replace == false)
+                return false;
+            if (m_command_dict[name]->IsRemovable() == false)
+                return false;
+        }
+        
+        if (UserCommandExists(name_cstr))
+        {
+            if (can_replace == false)
+                return false;
+            if (m_user_dict[name]->IsRemovable() == false)
+                return false;
+        }
         
-        if (can_replace == false && UserCommandExists(name_cstr))
-            return false;
-
         m_user_dict[name] = cmd_sp;
         return true;
     }
@@ -609,8 +811,7 @@ CommandInterpreter::GetCommandSPExact (c
             {
                 if (cmd_obj_sp->IsMultiwordObject())
                 {
-                    cmd_obj_sp = ((CommandObjectMultiword *) cmd_obj_sp.get())->GetSubcommandSP 
-                    (cmd_words.GetArgumentAtIndex (j));
+                    cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j));
                     if (cmd_obj_sp.get() == NULL)
                         // The sub-command name was invalid.  Fail and return the empty 'ret_val'.
                         return ret_val;
@@ -647,9 +848,14 @@ CommandInterpreter::GetCommandObject (co
         command_obj = GetCommandSP (cmd_cstr, true, true, matches).get();
     }
 
-    // Finally, if there wasn't an exact match among the aliases, look for an inexact match
-    // in both the commands and the aliases.
+    // If there wasn't an exact match among the aliases, look for an inexact match
+    // in just the commands.
+
+    if (command_obj == NULL)
+        command_obj = GetCommandSP(cmd_cstr, false, false, matches).get();
 
+    // Finally, if there wasn't an inexact match among the commands, look for an inexact
+    // match in both the commands and aliases.
     if (command_obj == NULL)
         command_obj = GetCommandSP(cmd_cstr, true, false, matches).get();
 
@@ -702,7 +908,7 @@ CommandInterpreter::ProcessAliasOptionsA
                                                                           options_string)));
         else
         {
-            int argc = args.GetArgumentCount();
+            const size_t argc = args.GetArgumentCount();
             for (size_t i = 0; i < argc; ++i)
                 if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
                     option_arg_vector->push_back 
@@ -716,6 +922,40 @@ CommandInterpreter::ProcessAliasOptionsA
 }
 
 bool
+CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
+{
+    bool exact_match  = (m_alias_dict.find(cmd) != m_alias_dict.end());
+    if (exact_match)
+    {
+        full_name.assign(cmd);
+        return exact_match;
+    }
+    else
+    {
+        StringList matches;
+        size_t num_alias_matches;
+        num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
+        if (num_alias_matches == 1)
+        {
+            // Make sure this isn't shadowing a command in the regular command space:
+            StringList regular_matches;
+            const bool include_aliases = false;
+            const bool exact = false;
+            CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, &regular_matches));
+            if (cmd_obj_sp || regular_matches.GetSize() > 0)
+                return false;
+            else
+            {
+                full_name.assign (matches.GetStringAtIndex(0));
+                return true;
+            }
+        }
+        else
+            return false;
+    }
+}
+
+bool
 CommandInterpreter::AliasExists (const char *cmd)
 {
     return m_alias_dict.find(cmd) != m_alias_dict.end();
@@ -812,7 +1052,7 @@ CommandInterpreter::GetHelp (CommandRetu
                              uint32_t cmd_types)
 {
     CommandObject::CommandMap::const_iterator pos;
-    uint32_t max_len = FindLongestCommandWord (m_command_dict);
+    size_t max_len = FindLongestCommandWord (m_command_dict);
     
     if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
     {
@@ -895,8 +1135,7 @@ CommandInterpreter::GetCommandObjectForC
             else if (cmd_obj->IsMultiwordObject ())
             {
                 // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
-                CommandObject *sub_cmd_obj = 
-                                         ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (cmd_word.c_str());
+                CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
                 if (sub_cmd_obj)
                     cmd_obj = sub_cmd_obj;
                 else // cmd_word was not a valid sub-command word, so we are donee
@@ -1154,19 +1393,21 @@ CommandInterpreter::PreprocessCommand (s
                     target = Host::GetDummyTarget(GetDebugger()).get();
                 if (target)
                 {
-                    const bool coerce_to_id = false;
-                    const bool unwind_on_error = true;
-                    const bool keep_in_memory = false;
                     ValueObjectSP expr_result_valobj_sp;
+                    
+                    EvaluateExpressionOptions options;
+                    options.SetCoerceToId(false)
+                    .SetUnwindOnError(true)
+                    .SetIgnoreBreakpoints(true)
+                    .SetKeepInMemory(false)
+                    .SetRunOthers(true)
+                    .SetTimeoutUsec(0);
+                    
                     ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), 
-                                                                               exe_ctx.GetFramePtr(), 
-                                                                               eExecutionPolicyOnlyWhenNeeded,
-                                                                               coerce_to_id,
-                                                                               unwind_on_error, 
-                                                                               keep_in_memory, 
-                                                                               eNoDynamicValues, 
+                                                                               exe_ctx.GetFramePtr(),
                                                                                expr_result_valobj_sp,
-                                                                               0 /* no timeout */);
+                                                                               options);
+                    
                     if (expr_result == eExecutionCompleted)
                     {
                         Scalar scalar;
@@ -1213,6 +1454,9 @@ CommandInterpreter::PreprocessCommand (s
                                 case eExecutionInterrupted:
                                     error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
                                     break;
+                                case eExecutionHitBreakpoint:
+                                    error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
+                                    break;
                                 case eExecutionTimedOut:
                                     error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
                                     break;
@@ -1245,7 +1489,7 @@ CommandInterpreter::HandleCommand (const
     std::string command_string (command_line);
     std::string original_command_string (command_line);
     
-    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
     Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
     
     // Make a scoped cleanup object that will clear the crash description string 
@@ -1260,7 +1504,6 @@ CommandInterpreter::HandleCommand (const
     if (!no_context_switching)
         UpdateExecutionContext (override_context);
     
-    // <rdar://problem/11328896>
     bool add_to_history;
     if (lazy_add_to_history == eLazyBoolCalculate)
         add_to_history = (m_command_source_depth == 0);
@@ -1363,10 +1606,11 @@ CommandInterpreter::HandleCommand (const
         ExtractCommand (command_string, next_word, suffix, quote_char);
         if (cmd_obj == NULL)
         {
-            if (AliasExists (next_word.c_str())) 
+            std::string full_name;
+            if (GetAliasFullName(next_word.c_str(), full_name))
             {
                 std::string alias_result;
-                cmd_obj = BuildAliasResult (next_word.c_str(), command_string, alias_result, result);
+                cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result);
                 revised_command_line.Printf ("%s", alias_result.c_str());
                 if (cmd_obj)
                 {
@@ -1393,7 +1637,7 @@ CommandInterpreter::HandleCommand (const
         {
             if (cmd_obj->IsMultiwordObject ())
             {
-                CommandObject *sub_cmd_obj = ((CommandObjectMultiword *) cmd_obj)->GetSubcommandObject (next_word.c_str());
+                CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
                 if (sub_cmd_obj)
                 {
                     actual_cmd_name_len += next_word.length() + 1;
@@ -1422,21 +1666,15 @@ CommandInterpreter::HandleCommand (const
 
         if (cmd_obj == NULL)
         {
-            uint32_t num_matches = matches.GetSize();
+            const size_t num_matches = matches.GetSize();
             if (matches.GetSize() > 1) {
-                std::string error_msg;
-                error_msg.assign ("Ambiguous command '");
-                error_msg.append(next_word.c_str());
-                error_msg.append ("'.");
-
-                error_msg.append (" Possible matches:");
+                StreamString error_msg;
+                error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
 
                 for (uint32_t i = 0; i < num_matches; ++i) {
-                    error_msg.append ("\n\t");
-                    error_msg.append (matches.GetStringAtIndex(i));
+                    error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
                 }
-                error_msg.append ("\n");
-                result.AppendRawError (error_msg.c_str(), error_msg.size());
+                result.AppendRawError (error_msg.GetString().c_str());
             } else {
                 // We didn't have only one match, otherwise we wouldn't get here.
                 assert(num_matches == 0);
@@ -1604,7 +1842,7 @@ CommandInterpreter::HandleCommand (const
                 error_msg.append (matches.GetStringAtIndex (i));
             }
             error_msg.append ("\n");
-            result.AppendRawError (error_msg.c_str(), error_msg.size());
+            result.AppendRawError (error_msg.c_str());
         }
         else
             result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
@@ -1784,7 +2022,7 @@ CommandInterpreter::HandleCompletion (co
 
         std::string common_prefix;
         matches.LongestCommonPrefix (common_prefix);
-        int partial_name_len = command_partial_str.size();
+        const size_t partial_name_len = command_partial_str.size();
 
         // If we matched a unique single command, add a space...
         // Only do this if the completer told us this was a complete word, however...
@@ -1931,20 +2169,6 @@ CommandInterpreter::Confirm (const char
     return response;        
 }
     
-
-void
-CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
-{
-    CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true);
-
-    if (cmd_obj_sp)
-    {
-        CommandObject *cmd_obj = cmd_obj_sp.get();
-        if (cmd_obj->IsCrossRefObject ())
-            cmd_obj->AddObject (object_type);
-    }
-}
-
 OptionArgVectorSP
 CommandInterpreter::GetAliasOptions (const char *alias_name)
 {
@@ -2038,7 +2262,7 @@ CommandInterpreter::BuildAliasCommandArg
         }
 
         OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
-        int old_size = cmd_args.GetArgumentCount();
+        const size_t old_size = cmd_args.GetArgumentCount();
         std::vector<bool> used (old_size + 1, false);
         
         used[0] = true;
@@ -2288,10 +2512,17 @@ CommandInterpreter::HandleCommands (cons
         CommandReturnObject tmp_result;
         // If override_context is not NULL, pass no_context_switching = true for
         // HandleCommand() since we updated our context already.
+        
+        // We might call into a regex or alias command, in which case the add_to_history will get lost.  This
+        // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
+        if (!add_to_history)
+            m_command_source_depth++;
         bool success = HandleCommand(cmd, add_to_history, tmp_result,
                                      NULL, /* override_context */
                                      true, /* repeat_on_empty_command */
                                      override_context != NULL /* no_context_switching */);
+        if (!add_to_history)
+            m_command_source_depth--;
         
         if (print_results)
         {
@@ -2394,8 +2625,14 @@ CommandInterpreter::HandleCommandsFromFi
 }
 
 ScriptInterpreter *
-CommandInterpreter::GetScriptInterpreter ()
+CommandInterpreter::GetScriptInterpreter (bool can_create)
 {
+    if (m_script_interpreter_ap.get() != NULL)
+        return m_script_interpreter_ap.get();
+    
+    if (!can_create)
+        return NULL;
+ 
     // <rdar://problem/11751427>
     // we need to protect the initialization of the script interpreter
     // otherwise we could end up with two threads both trying to create
@@ -2406,8 +2643,9 @@ CommandInterpreter::GetScriptInterpreter
     static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
     Mutex::Locker interpreter_lock(g_interpreter_mutex);
     
-    if (m_script_interpreter_ap.get() != NULL)
-        return m_script_interpreter_ap.get();
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf("Initializing the ScriptInterpreter now\n");
     
     lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
     switch (script_lang)
@@ -2422,8 +2660,6 @@ CommandInterpreter::GetScriptInterpreter
         case eScriptLanguageNone:
             m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
             break;
-        default:
-            break;
     };
     
     return m_script_interpreter_ap.get();
@@ -2448,7 +2684,7 @@ CommandInterpreter::OutputFormattedHelpT
                                              const char *word_text,
                                              const char *separator,
                                              const char *help_text,
-                                             uint32_t max_word_len)
+                                             size_t max_word_len)
 {
     const uint32_t max_columns = m_debugger.GetTerminalWidth();
 
@@ -2457,7 +2693,7 @@ CommandInterpreter::OutputFormattedHelpT
     strm.IndentMore (indent_size);
     
     StreamString text_strm;
-    text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
+    text_strm.Printf ("%-*s %s %s",  (int)max_word_len, word_text, separator, help_text);
     
     size_t len = text_strm.GetSize();
     const char *text = text_strm.GetData();
@@ -2477,10 +2713,9 @@ CommandInterpreter::OutputFormattedHelpT
         // We need to break it up into multiple lines.
         bool first_line = true;
         int text_width;
-        int start = 0;
-        int end = start;
-        int final_end = strlen (text);
-        int sub_len;
+        size_t start = 0;
+        size_t end = start;
+        const size_t final_end = strlen (text);
         
         while (end < final_end)
         {
@@ -2505,9 +2740,10 @@ CommandInterpreter::OutputFormattedHelpT
                 while (end > start
                        && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                     end--;
+                assert (end > 0);
             }
 
-            sub_len = end - start;
+            const size_t sub_len = end - start;
             if (start != 0)
               strm.EOL();
             if (!first_line)
@@ -2567,54 +2803,53 @@ CommandInterpreter::OutputHelpText (Stre
 }
 
 void
-CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word,
-                                           StringList &commands_found, StringList &commands_help)
+CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
+                                            StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
 {
     CommandObject::CommandMap::const_iterator pos;
-    CommandObject::CommandMap sub_cmd_dict = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict;
-    CommandObject *sub_cmd_obj;
 
-    for (pos = sub_cmd_dict.begin(); pos != sub_cmd_dict.end(); ++pos)
+    if (search_builtin_commands)
     {
-          const char * command_name = pos->first.c_str();
-          sub_cmd_obj = pos->second.get();
-          StreamString complete_command_name;
-          
-          complete_command_name.Printf ("%s %s", prefix, command_name);
-
-          if (sub_cmd_obj->HelpTextContainsWord (search_word))
-          {
-              commands_found.AppendString (complete_command_name.GetData());
-              commands_help.AppendString (sub_cmd_obj->GetHelp());
-          }
-
-          if (sub_cmd_obj->IsMultiwordObject())
-              AproposAllSubCommands (sub_cmd_obj, complete_command_name.GetData(), search_word, commands_found,
-                                     commands_help);
-    }
-
-}
+        for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
+        {
+            const char *command_name = pos->first.c_str();
+            CommandObject *cmd_obj = pos->second.get();
 
-void
-CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
-                                            StringList &commands_help)
-{
-    CommandObject::CommandMap::const_iterator pos;
+            if (cmd_obj->HelpTextContainsWord (search_word))
+            {
+                commands_found.AppendString (command_name);
+                commands_help.AppendString (cmd_obj->GetHelp());
+            }
 
-    for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
+            if (cmd_obj->IsMultiwordObject())
+                cmd_obj->AproposAllSubCommands (command_name,
+                                                search_word,
+                                                commands_found,
+                                                commands_help);
+          
+        }
+    }
+    
+    if (search_user_commands)
     {
-        const char *command_name = pos->first.c_str();
-        CommandObject *cmd_obj = pos->second.get();
-
-        if (cmd_obj->HelpTextContainsWord (search_word))
+        for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
         {
-            commands_found.AppendString (command_name);
-            commands_help.AppendString (cmd_obj->GetHelp());
-        }
+            const char *command_name = pos->first.c_str();
+            CommandObject *cmd_obj = pos->second.get();
 
-        if (cmd_obj->IsMultiwordObject())
-          AproposAllSubCommands (cmd_obj, command_name, search_word, commands_found, commands_help);
-      
+            if (cmd_obj->HelpTextContainsWord (search_word))
+            {
+                commands_found.AppendString (command_name);
+                commands_help.AppendString (cmd_obj->GetHelp());
+            }
+
+            if (cmd_obj->IsMultiwordObject())
+                cmd_obj->AproposAllSubCommands (command_name,
+                                                search_word,
+                                                commands_found,
+                                                commands_help);
+          
+        }
     }
 }
 
@@ -2642,7 +2877,7 @@ CommandInterpreter::DumpHistory (Stream
 void
 CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const
 {
-    const size_t last_idx = std::min<size_t>(m_command_history.size(), end + 1);
+    const size_t last_idx = std::min<size_t>(m_command_history.size(), end==UINT32_MAX ? UINT32_MAX : end + 1);
     for (size_t i = start; i < last_idx; i++)
     {
         if (!m_command_history[i].empty())
@@ -2661,7 +2896,7 @@ CommandInterpreter::FindHistoryString (c
     if (input_str[1] == '-')
     {
         bool success;
-        uint32_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
+        size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
         if (!success)
             return NULL;
         if (idx > m_command_history.size())

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObject.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObject.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObject.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/CommandObject.h"
 
 #include <string>
@@ -167,7 +169,7 @@ CommandObject::ParseOptions
         Error error;
         options->NotifyOptionParsingStarting();
 
-        // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
+        // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1,
         // so we need to push a dummy value into position zero.
         args.Unshift("dummy_string");
         error = args.ParseOptions (*options);
@@ -206,8 +208,77 @@ CommandObject::ParseOptions
 
 
 bool
-CommandObject::CheckFlags (CommandReturnObject &result)
+CommandObject::CheckRequirements (CommandReturnObject &result)
 {
+#ifdef LLDB_CONFIGURATION_DEBUG
+    // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
+    // has shared pointers to the target, process, thread and frame and we don't
+    // want any CommandObject instances to keep any of these objects around
+    // longer than for a single command. Every command should call
+    // CommandObject::Cleanup() after it has completed
+    assert (m_exe_ctx.GetTargetPtr() == NULL);
+    assert (m_exe_ctx.GetProcessPtr() == NULL);
+    assert (m_exe_ctx.GetThreadPtr() == NULL);
+    assert (m_exe_ctx.GetFramePtr() == NULL);
+#endif
+
+    // Lock down the interpreter's execution context prior to running the
+    // command so we guarantee the selected target, process, thread and frame
+    // can't go away during the execution
+    m_exe_ctx = m_interpreter.GetExecutionContext();
+
+    const uint32_t flags = GetFlags().Get();
+    if (flags & (eFlagRequiresTarget   |
+                 eFlagRequiresProcess  |
+                 eFlagRequiresThread   |
+                 eFlagRequiresFrame    |
+                 eFlagTryTargetAPILock ))
+    {
+
+        if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+        {
+            result.AppendError (GetInvalidTargetDescription());
+            return false;
+        }
+
+        if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+        {
+            result.AppendError (GetInvalidProcessDescription());
+            return false;
+        }
+        
+        if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+        {
+            result.AppendError (GetInvalidThreadDescription());
+            return false;
+        }
+        
+        if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+        {
+            result.AppendError (GetInvalidFrameDescription());
+            return false;
+        }
+        
+        if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == NULL))
+        {
+            result.AppendError (GetInvalidRegContextDescription());
+            return false;
+        }
+
+        if (flags & eFlagTryTargetAPILock)
+        {
+            Target *target = m_exe_ctx.GetTargetPtr();
+            if (target)
+            {
+                if (m_api_locker.TryLock (target->GetAPIMutex(), NULL) == false)
+                {
+                    result.AppendError ("failed to get API lock");
+                    return false;
+                }
+            }
+        }
+    }
+
     if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
     {
         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
@@ -224,7 +295,6 @@ CommandObject::CheckFlags (CommandReturn
         else
         {
             StateType state = process->GetState();
-            
             switch (state)
             {
             case eStateInvalid:
@@ -261,6 +331,14 @@ CommandObject::CheckFlags (CommandReturn
     return true;
 }
 
+void
+CommandObject::Cleanup ()
+{
+    m_exe_ctx.Clear();
+    m_api_locker.Unlock();
+}
+
+
 class CommandDictCommandPartialMatch
 {
     public:
@@ -272,13 +350,9 @@ class CommandDictCommandPartialMatch
         {
             // A NULL or empty string matches everything.
             if (m_match_str == NULL || *m_match_str == '\0')
-                return 1;
+                return true;
 
-            size_t found = map_element.first.find (m_match_str, 0);
-            if (found == std::string::npos)
-                return 0;
-            else
-                return found == 0;
+            return map_element.first.find (m_match_str, 0) == 0;
         }
 
     private:
@@ -341,7 +415,7 @@ CommandObject::HandleCompletion
 
 
             // I stick an element on the end of the input, because if the last element is
-            // option that requires an argument, getopt_long will freak out.
+            // option that requires an argument, getopt_long_only will freak out.
 
             input.AppendArgument ("<FAKE-VALUE>");
 
@@ -377,23 +451,19 @@ CommandObject::HandleCompletion
 bool
 CommandObject::HelpTextContainsWord (const char *search_word)
 {
-    const char *short_help;
-    const char *long_help;
-    const char *syntax_help;
     std::string options_usage_help;
 
-
     bool found_word = false;
 
-    short_help = GetHelp();
-    long_help = GetHelpLong();
-    syntax_help = GetSyntax();
+    const char *short_help = GetHelp();
+    const char *long_help = GetHelpLong();
+    const char *syntax_help = GetSyntax();
     
-    if (strcasestr (short_help, search_word))
+    if (short_help && strcasestr (short_help, search_word))
         found_word = true;
-    else if (strcasestr (long_help, search_word))
+    else if (long_help && strcasestr (long_help, search_word))
         found_word = true;
-    else if (strcasestr (syntax_help, search_word))
+    else if (syntax_help && strcasestr (syntax_help, search_word))
         found_word = true;
 
     if (!found_word
@@ -630,6 +700,23 @@ CommandObject::LookupArgumentName (const
 }
 
 static const char *
+RegisterNameHelpTextCallback ()
+{
+    return "Register names can be specified using the architecture specific names.  "
+    "They can also be specified using generic names.  Not all generic entities have "
+    "registers backing them on all architectures.  When they don't the generic name "
+    "will return an error.\n"
+    "The generic names defined in lldb are:\n"
+    "\n"
+    "pc       - program counter register\n"
+    "ra       - return address register\n"
+    "fp       - frame pointer register\n"
+    "sp       - stack pointer register\n"
+    "flags    - the flags register\n"
+    "arg{1-6} - integer argument passing registers.\n";
+}
+
+static const char *
 BreakpointIDHelpTextCallback ()
 {
     return "Breakpoint ID's consist major and minor numbers;  the major number "
@@ -729,6 +816,33 @@ FormatHelpTextCallback ()
 }
 
 static const char *
+LanguageTypeHelpTextCallback ()
+{
+    static char* help_text_ptr = NULL;
+    
+    if (help_text_ptr)
+        return help_text_ptr;
+    
+    StreamString sstr;
+    sstr << "One of the following languages:\n";
+    
+    for (unsigned int l = eLanguageTypeUnknown; l < eNumLanguageTypes; ++l)
+    {
+        sstr << "  " << LanguageRuntime::GetNameForLanguageType(static_cast<LanguageType>(l)) << "\n";
+    }
+    
+    sstr.Flush();
+    
+    std::string data = sstr.GetString();
+    
+    help_text_ptr = new char[data.length()+1];
+    
+    data.copy(help_text_ptr, data.length());
+    
+    return help_text_ptr;
+}
+
+static const char *
 SummaryStringHelpTextCallback()
 {
     return
@@ -846,14 +960,16 @@ CommandObjectParsed::Execute (const char
                 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
         }
 
-        if (!CheckFlags(result))
-            return false;
-            
-        if (!ParseOptions (cmd_args, result))
-            return false;
+        if (CheckRequirements(result))
+        {
+            if (ParseOptions (cmd_args, result))
+            {
+                // Call the command-specific version of 'Execute', passing it the already processed arguments.
+                handled = DoExecute (cmd_args, result);
+            }
+        }
 
-        // Call the command-specific version of 'Execute', passing it the already processed arguments.
-        handled = DoExecute (cmd_args, result);
+        Cleanup();
     }
     return handled;
 }
@@ -874,10 +990,10 @@ CommandObjectRaw::Execute (const char *a
     }
     if (!handled)
     {
-        if (!CheckFlags(result))
-            return false;
-        else
+        if (CheckRequirements(result))
             handled = DoExecute (args_string, result);
+        
+        Cleanup();
     }
     return handled;
 }
@@ -900,6 +1016,7 @@ CommandObject::ArgumentTableEntry
 CommandObject::g_arguments_data[] =
 {
     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
+    { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { NULL, false }, "An expression that resolves to an address." },
     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
     { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { NULL, false }, "Command options to be used as part of an alias (abbreviation) definition.  (See 'help commands alias' for more information.)" },
     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
@@ -910,6 +1027,8 @@ CommandObject::g_arguments_data[] =
     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { NULL, false }, "Then name of a class from the debug information in the program." },
     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
+    { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { NULL, false }, "A directory name." },
+    { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { NULL, false }, "A disassembly flavor recognized by your disassembly plugin.  Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
@@ -919,9 +1038,10 @@ CommandObject::g_arguments_data[] =
     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into a thread's list of frames." },
     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function." },
+    { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function or symbol." },
     { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, NULL },
     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a list." },
-    { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { NULL, false }, "A source language name." },
+    { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, NULL },
     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { NULL, false }, "Line number in a source file." },
     { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." },
     { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
@@ -933,7 +1053,6 @@ CommandObject::g_arguments_data[] =
     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { NULL, false }, "A command that is entered as a single line of text." },
-    { eArgTypePath, "path", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
     { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { NULL, false }, "Permissions given as an octal number (e.g. 755)." },
     { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { NULL, false }, "Permissions given as a string value (e.g. rw-r-xr--)." },
     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." },
@@ -943,7 +1062,7 @@ CommandObject::g_arguments_data[] =
     { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python function." },
     { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { NULL, false }, "Source code written in Python." },
     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." },
-    { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { NULL, false }, "A register name." },
+    { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, NULL },
     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { NULL, false }, "Arguments to be passed to the target program when it starts executing." },
     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectRegexCommand.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/CommandObjectRegexCommand.h"
 
 // C Includes
@@ -28,10 +30,12 @@ CommandObjectRegexCommand::CommandObject
     const char *name,
     const char *help,
     const char *syntax,
-    uint32_t max_matches
+    uint32_t max_matches,
+    uint32_t completion_type_mask
 ) :
     CommandObjectRaw (interpreter, name, help, syntax),
     m_max_matches (max_matches),
+    m_completion_type_mask (completion_type_mask),
     m_entries ()
 {
 }
@@ -56,7 +60,9 @@ CommandObjectRegexCommand::DoExecute
         EntryCollection::const_iterator pos, end = m_entries.end();
         for (pos = m_entries.begin(); pos != end; ++pos)
         {
-            if (pos->regex.Execute (command, m_max_matches))
+            RegularExpression::Match regex_match(m_max_matches);
+
+            if (pos->regex.Execute (command, &regex_match))
             {
                 std::string new_command(pos->command);
                 std::string match_str;
@@ -64,7 +70,7 @@ CommandObjectRegexCommand::DoExecute
                 size_t idx, percent_var_idx;
                 for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
                 {
-                    if (pos->regex.GetMatchAtIndex (command, match_idx, match_str))
+                    if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
                     {
                         const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
                         for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )
@@ -76,14 +82,20 @@ CommandObjectRegexCommand::DoExecute
                     }
                 }
                 // Interpret the new command and return this as the result!
-                result.GetOutputStream().Printf("%s\n", new_command.c_str());
-                return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result);
+                if (m_interpreter.GetExpandRegexAliases())
+                    result.GetOutputStream().Printf("%s\n", new_command.c_str());
+                // Pass in true for "no context switching".  The command that called us should have set up the context
+                // appropriately, we shouldn't have to redo that.
+                return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, NULL, true, true);
             }
         }
         result.SetStatus(eReturnStatusFailed);
-        result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n",
-                                      command,
-                                      m_cmd_name.c_str());
+        if (GetSyntax() != NULL)
+            result.AppendError (GetSyntax());
+        else
+            result.AppendErrorWithFormat ("Command contents '%s' failed to match any regular expression in the '%s' regex command.\n",
+                                          command,
+                                          m_cmd_name.c_str());
         return false;
     }
     result.AppendError("empty command passed to regular expression command");
@@ -106,3 +118,33 @@ CommandObjectRegexCommand::AddRegexComma
     m_entries.pop_back();
     return false;
 }
+
+int
+CommandObjectRegexCommand::HandleCompletion (Args &input,
+                                             int &cursor_index,
+                                             int &cursor_char_position,
+                                             int match_start_point,
+                                             int max_return_elements,
+                                             bool &word_complete,
+                                             StringList &matches)
+{
+    if (m_completion_type_mask)
+    {
+        std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
+        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
+                                                             m_completion_type_mask,
+                                                             completion_str.c_str(),
+                                                             match_start_point,
+                                                             max_return_elements,
+                                                             NULL,
+                                                             word_complete,
+                                                             matches);
+        return matches.GetSize();
+    }
+    else
+    {
+        matches.Clear();
+        word_complete = false;
+    }
+    return 0;
+}

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "CommandObjectScript.h"
 
 // C Includes
@@ -14,13 +16,14 @@
 // Other libraries and framework includes
 // Project includes
 
-#include "lldb/Core/DataVisualization.h"
 #include "lldb/Core/Debugger.h"
-#include "lldb/Interpreter/Args.h"
 
+#include "lldb/DataFormatters/DataVisualization.h"
+
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -33,8 +36,7 @@ CommandObjectScript::CommandObjectScript
     CommandObjectRaw (interpreter, 
                       "script",
                       "Pass an expression to the script interpreter for evaluation and return the results. Drop into the interactive interpreter if no expression is given.",
-                      "script [<script-expression-for-evaluation>]"),
-    m_script_lang (script_lang)
+                      "script [<script-expression-for-evaluation>]")
 {
 }
 
@@ -49,12 +51,26 @@ CommandObjectScript::DoExecute
     CommandReturnObject &result
 )
 {
+#ifdef LLDB_DISABLE_PYTHON
+    // if we ever support languages other than Python this simple #ifdef won't work
+    result.AppendError("your copy of LLDB does not support scripting.");
+    result.SetStatus (eReturnStatusFailed);
+    return false;
+#else
+    if (m_interpreter.GetDebugger().GetScriptLanguage() == lldb::eScriptLanguageNone)
+    {
+        result.AppendError("the script-lang setting is set to none - scripting not available");
+        result.SetStatus (eReturnStatusFailed);
+        return false;
+    }
+    
     ScriptInterpreter *script_interpreter = m_interpreter.GetScriptInterpreter ();
 
     if (script_interpreter == NULL)
     {
         result.AppendError("no script interpreter");
         result.SetStatus (eReturnStatusFailed);
+        return false;
     }
 
     DataVisualization::ForceUpdate(); // script might change Python code we use for formatting.. make sure we keep up to date with it
@@ -67,10 +83,11 @@ CommandObjectScript::DoExecute
     }
 
     // We can do better when reporting the status of one-liner script execution.
-    if (script_interpreter->ExecuteOneLine (command, &result, true))
+    if (script_interpreter->ExecuteOneLine (command, &result))
         result.SetStatus(eReturnStatusSuccessFinishNoResult);
     else
         result.SetStatus(eReturnStatusFailed);
 
     return result.Succeeded();
+#endif
 }

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.h (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandObjectScript.h Thu Jun  6 19:06:43 2013
@@ -35,9 +35,6 @@ public:
 protected:
     virtual bool
     DoExecute (const char *command, CommandReturnObject &result);
-
-private:
-    lldb::ScriptLanguage m_script_lang;
 };
 
 } // namespace lldb_private

Modified: lldb/branches/lldb-platform-work/source/Interpreter/CommandReturnObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/CommandReturnObject.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/CommandReturnObject.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/CommandReturnObject.cpp Thu Jun  6 19:06:43 2013
@@ -104,46 +104,37 @@ CommandReturnObject::AppendWarningWithFo
 }
 
 void
-CommandReturnObject::AppendMessage (const char *in_string, int len)
+CommandReturnObject::AppendMessage (const char *in_string)
 {
     if (!in_string)
         return;
-    if (len < 0)
-        len = ::strlen (in_string);
-    GetOutputStream().Printf("%*.*s\n", len, len, in_string);
+    GetOutputStream().Printf("%s\n", in_string);
 }
 
 void
-CommandReturnObject::AppendWarning (const char *in_string, int len)
+CommandReturnObject::AppendWarning (const char *in_string)
 {
-    if (!in_string)
+    if (!in_string || *in_string == '\0')
         return;
-    if (len < 0)
-        len = ::strlen (in_string);
-    GetErrorStream().Printf("warning: %*.*s\n", len, len, in_string);
+    GetErrorStream().Printf("warning: %s\n", in_string);
 }
 
 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and
 // don't append "\n" to the end of it.
 
 void
-CommandReturnObject::AppendRawWarning (const char *in_string, int len)
+CommandReturnObject::AppendRawWarning (const char *in_string)
 {
-    if (!in_string)
-        return;
-    if (len < 0)
-        len = ::strlen (in_string);
-    GetErrorStream().Printf("%*.*s", len, len, in_string);
+    if (in_string && in_string[0])
+        GetErrorStream().PutCString(in_string);
 }
 
 void
-CommandReturnObject::AppendError (const char *in_string, int len)
+CommandReturnObject::AppendError (const char *in_string)
 {
-    if (!in_string)
+    if (!in_string || *in_string == '\0')
         return;
-    if (len < 0)
-        len = ::strlen (in_string);
-    GetErrorStream().Printf ("error: %*.*s\n", len, len, in_string);
+    GetErrorStream().Printf ("error: %s\n", in_string);
 }
 
 void
@@ -159,13 +150,10 @@ CommandReturnObject::SetError (const Err
 // don't append "\n" to the end of it.
 
 void
-CommandReturnObject::AppendRawError (const char *in_string, int len)
+CommandReturnObject::AppendRawError (const char *in_string)
 {
-    if (!in_string)
-        return;
-    if (len < 0)
-        len = ::strlen (in_string);
-    GetErrorStream().Printf ("%*.*s", len, len, in_string);
+    if (in_string && in_string[0])
+        GetErrorStream().PutCString(in_string);
 }
 
 void

Modified: lldb/branches/lldb-platform-work/source/Interpreter/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/Makefile (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/Makefile Thu Jun  6 19:06:43 2013
@@ -16,172 +16,28 @@ BUILT_SOURCES := LLDBWrapPython.cpp
 include $(LLDB_LEVEL)/Makefile
 -include $(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.d
 
-PYTHON_DIR := $(LibDir)/python/lldb
-ifeq ($(HOST_OS),Darwin)
-PYTHON_DEST_DIR := $(DESTDIR)/$(call realpath,/Library/Python/$(shell python -c 'import sys; print sys.version[:3]')/site-packages)/lldb
-else
-PYTHON_DEST_DIR := $(DESTDIR)/$(call realpath,$(shell python -c 'import sys; print sys.exec_prefix')/lib/python$(shell python -c 'import sys; print sys.version[:3]')/site-packages)/lldb
-endif
-LLDB_SWIG_INCLUDE_DIRS:= -I"$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/include" -I./.
-LIBLLDB := $(LibDir)/liblldb$(SHLIBEXT)
-INST_LIBLLDB := $(PROJ_libdir)/liblldb$(SHLIBEXT)
-
-# Subpackages of the main LLDB package
-LLDB_SUBPACKAGES := FORMATTERS FORMATTERS_CPP FORMATTERS_OBJC RUNTIME RUNTIME_OBJC UTILS
-# lldb.formatters
-LLDB_PACKAGE_FORMATTERS := formatters
-LLDB_PACKAGE_FORMATTERS_FILES := $(addprefix \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/summaries/cocoa/, \
-  cache.py metrics.py attrib_fromdict.py Logger.py)
-# lldb.formatters.cpp
-LLDB_PACKAGE_FORMATTERS_CPP := formatters/cpp
-LLDB_PACKAGE_FORMATTERS_CPP_FILES := $(addprefix \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/synthetic/,gnu_libstdcpp.py libcxx.py)
-# lldb.formatters.objc
-LLDB_PACKAGE_FORMATTERS_OBJC := formatters/objc
-LLDB_PACKAGE_FORMATTERS_OBJC_FILES := \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/summaries/cocoa/Selector.py \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/summaries/objc.py \
-  $(addprefix $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/summaries/cocoa/, \
-    Class.py CFArray.py CFBag.py CFBinaryHeap.py CFBitVector.py \
-    CFDictionary.py CFString.py NSBundle.py NSData.py NSDate.py \
-    NSException.py NSIndexSet.py NSMachPort.py NSNotification.py \
-    NSNumber.py NSSet.py NSURL.py \
-  )
-# lldb.runtime
-LLDB_PACKAGE_RUNTIME := runtime
-LLDB_PACKAGE_RUNTIME_FILES :=
-# lldb.runtime.objc
-LLDB_PACKAGE_RUNTIME_OBJC := runtime/objc
-LLDB_PACKAGE_RUNTIME_OBJC_FILES := \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/summaries/cocoa/objc_runtime.py
-# lldb.utils
-LLDB_PACKAGE_UTILS := utils
-LLDB_PACKAGE_UTILS_FILES := \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/python/symbolication.py
-
-ifeq ($(HOST_OS),Darwin)
-# Additional packages for Darwin/Mac OS X
-LLDB_SUBPACKAGES += MACOSX
-# lldb.macosx
-LLDB_PACKAGE_MACOSX := macosx
-LLDB_PACKAGE_MACOSX_FILES := $(addprefix \
-  $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/, python/crashlog.py darwin/heap_find/heap.py \
-)
-endif
-
-LLDB_ALL_SUBPACKAGE_FILES := $(foreach subpackage,$(LLDB_SUBPACKAGES),$(LLDB_PACKAGE_$(subpackage)_FILES))
-LLDB_ALL_INSTALLED_SUBPACKAGE_FILES := $(foreach subpackage,$(LLDB_SUBPACKAGES),$(addprefix $(LLDB_PACKAGE_$(subpackage))/,$(notdir $(LLDB_PACKAGE_$(subpackage)_FILES))))
-
-comma := ,
-LLDB_COPY_PACKAGE = $(Verb) \
-$(foreach subpackage,$(LLDB_SUBPACKAGES), \
-  init_file="$(PYTHON_DIR)/$(LLDB_PACKAGE_$(subpackage))/__init__.py"; \
-  $(MKDIR) "$(PYTHON_DIR)/$(LLDB_PACKAGE_$(subpackage))"; \
-  $(foreach file,$(LLDB_PACKAGE_$(subpackage)_FILES), \
-    $(CP) "$(file)" "$(PYTHON_DIR)/$(LLDB_PACKAGE_$(subpackage))"; \
-  ) \
-  echo "__all__ = [$(patsubst %,\"%\"$(comma),\
-    $(basename $(notdir $(LLDB_PACKAGE_$(subpackage)_FILES))))]" >$$init_file; \
-  echo "for x in __all__:" >>$$init_file; \
-  echo "    __import__('lldb.$(subst /,.,$(LLDB_PACKAGE_$(subpackage))).'+x)" >>$$init_file; \
-)
-
-LLDB_INSTALL_SUBPACKAGES = $(Verb) \
-$(foreach subpackage,$(LLDB_SUBPACKAGES), \
-  $(MKDIR) $(PYTHON_DEST_DIR)/$(LLDB_PACKAGE_$(subpackage)); \
-  $(DataInstall) $(PYTHON_DIR)/$(LLDB_PACKAGE_$(subpackage))/__init__.py \
-                 $(PYTHON_DEST_DIR)/$(LLDB_PACKAGE_$(subpackage))/__init__.py; \
-) \
-$(foreach file,$(LLDB_ALL_INSTALLED_SUBPACKAGE_FILES), \
-  $(DataInstall) $(PYTHON_DIR)/$(file) $(PYTHON_DEST_DIR)/$(file); \
-)
-
-ifeq ($(HOST_OS),Darwin)
-# Install the heap_find sources, too.
-LLDB_INSTALL_SUBPACKAGES += $(MKDIR) $(PYTHON_DEST_DIR)/macosx/heap/; \
-$(DataInstall) $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/darwin/heap_find/heap/heap_find.cpp \
-               $(PYTHON_DEST_DIR)/macosx/heap/heap_find.cpp; \
-$(DataInstall) $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/examples/darwin/heap_find/heap/Makefile \
-			   $(PYTHON_DEST_DIR)/macosx/heap/Makefile;
-endif
-
-# We need Swig to process stdint.h, but by default it will not inspect system
-# include directories.  The following should cover the standard locations on
-# most platforms.
-LLDB_SWIG_INCLUDE_DIRS += -I"/usr/local/include"
-LLDB_SWIG_INCLUDE_DIRS += -I"/usr/include"
-
-# On Darwin, stdint.h might only be in the compiler subdirectory. Unfortunately,
-# swig doesn't currently seem able to understand Clang's stdint.h, so we have to
-# point at the GCC one.
-ifeq ($(HOST_OS),Darwin)
-LLDB_SWIG_INCLUDE_DIRS += -I"/usr/include/gcc/darwin/4.2"
-endif
-
-ifndef DISABLE_AUTO_DEPENDENCIES
-
-SWIG_DEPEND_OPTIONS = -MMD -MF "$(PROJ_OBJ_DIR)/$*.cpp.d.tmp"
-CPP_DEPEND_MOVEFILE = then $(MV) -f "$(PROJ_OBJ_DIR)/$*.cpp.d.tmp" "$(PROJ_OBJ_DIR)/$*.cpp.d"; \
-                      else $(RM) -f "$(PROJ_OBJ_DIR)/$*.cpp.d.tmp"; exit 1; fi
+# Drop -Wfour-char-constants,  which we are not currently clean with.
+EXTRA_OPTIONS += -Wno-four-char-constants
 
-LLDBWrapPython.cpp: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py \
-                    $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/edit-swig-python-wrapper-file.py
-	$(Echo) Generating LLDBWrapPython.cpp
-	$(Verb) $(MKDIR) $(PYTHON_DIR)
-	$(Verb) if swig -c++ -shadow -python $(LLDB_SWIG_INCLUDE_DIRS) \
-          -D__STDC_LIMIT_MACROS -outdir "$(PYTHON_DIR)"   \
-          $(SWIG_DEPEND_OPTIONS) \
-          -o LLDBWrapPython.cpp "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/lldb.swig" ; \
-          $(CPP_DEPEND_MOVEFILE)
-	$(Verb) python "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py" \
-		  "$(PYTHON_DIR)"
-	$(Verb) python "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/edit-swig-python-wrapper-file.py" \
-		  "$(PROJ_OBJ_DIR)"
-	$(Verb) if test -f "$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.edited"; then \
-		  $(MV) "$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.edited" \
-				"$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp"; fi
-	$(Verb) $(MV) "$(PYTHON_DIR)/lldb.py" "$(PYTHON_DIR)/__init__.py"
-	$(Verb) $(CP) "$(PROJ_SRC_DIR)/embedded_interpreter.py" "$(PYTHON_DIR)"
-	$(Verb) $(RM) -f $(PYTHON_DIR)/_lldb.so
-	$(Verb) $(AliasTool) $(LIBLLDB) $(PYTHON_DIR)/_lldb.so
-	$(LLDB_COPY_PACKAGE)
+# Drop -Wself-assign, -Wmissing-field-initializers and -Wsometimes-uninitialized,
+# which we are not currently clean with (due to SWIG generated cpp source).
+EXTRA_OPTIONS += -Wno-missing-field-initializers -Wno-self-assign -Wno-sometimes-uninitialized
 
-else
+# edit-swig-python-wrapper-file.py needs $(SRCROOT)
+export SRCROOT := $(PROJ_SRC_DIR)/$(LLDB_LEVEL)
 
-LLDBWrapPython.cpp: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py \
-                    $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/edit-swig-python-wrapper-file.py
-	$(Echo) Generating LLDBWrapPython.cpp
-	$(Verb) $(MKDIR) $(PYTHON_DIR)
-	$(Verb) swig -c++ -shadow -python $(LLDB_SWIG_INCLUDE_DIRS) \
-          -D__STDC_LIMIT_MACROS -outdir "$(PYTHON_DIR)"   \
-          -o LLDBWrapPython.cpp "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/lldb.swig"
-	$(Verb) python "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py" \
-		  "$(PYTHON_DIR)"
-	$(Verb) python "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/edit-swig-python-wrapper-file.py" \
-		  "$(PROJ_OBJ_DIR)"
-	$(Verb) if test -f "$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.edited"; then \
-		  $(MV) "$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.edited" \
-				"$(PROJ_OBJ_DIR)/LLDBWrapPython.cpp"; fi
-	$(Verb) $(MV) "$(PYTHON_DIR)/lldb.py" "$(PYTHON_DIR)/__init__.py"
-	$(Verb) $(CP) "$(PROJ_SRC_DIR)/embedded_interpreter.py" "$(PYTHON_DIR)"
-	$(Verb) $(RM) -f $(PYTHON_DIR)/_lldb.so
-	$(Verb) $(AliasTool) $(LIBLLDB) $(PYTHON_DIR)/_lldb.so
-	$(LLDB_COPY_PACKAGE)
+PYTHON_DIR := $(PROJ_OBJ_ROOT)/$(BuildMode)
 
-endif
+LLDBWrapPython.cpp lldb.py: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/modify-python-lldb.py \
+                            $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/edit-swig-python-wrapper-file.py \
+                            $(wildcard $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/Python/interface/*.i)
+	$(Echo) Generating LLDBWrapPython.cpp
+	$(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/build-swig-wrapper-classes.sh" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "$(PROJ_OBJ_DIR)" "$(PROJ_OBJ_DIR)" "$(PYTHON_DIR)" -m $(if $(DISABLE_AUTO_DEPENDENCIES),,-M)
+	$(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/finish-swig-wrapper-classes.sh" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "$(PROJ_OBJ_DIR)" "$(PROJ_OBJ_DIR)" "$(PYTHON_DIR)" -m
 
-install-local:: $(PYTHON_DIR)/__init__.py $(PYTHON_DIR)/embedded_interpreter.py \
-                $(addprefix $(PYTHON_DIR)/,$(LLDB_ALL_INSTALLED_SUBPACKAGE_FILES))
+install-local:: lldb.py
 	$(Echo) Installing $(BuildMode) LLDB python modules
-	$(Verb) $(MKDIR) $(PYTHON_DEST_DIR)
-	$(Verb) $(DataInstall) $(PYTHON_DIR)/__init__.py $(PYTHON_DEST_DIR)/__init__.py
-	$(Verb) $(DataInstall) $(PYTHON_DIR)/embedded_interpreter.py $(PYTHON_DEST_DIR)/embedded_interpreter.py
-	$(Verb) $(RM) -f $(PYTHON_DEST_DIR)/_lldb.so
-	$(Verb) $(AliasTool) $(INST_LIBLLDB) $(PYTHON_DEST_DIR)/_lldb.so
-	$(LLDB_INSTALL_SUBPACKAGES)
+	$(Verb) "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/finish-swig-wrapper-classes.sh" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)" "$(PROJ_OBJ_DIR)" "$(PROJ_OBJ_DIR)" "" -m
 
 clean-local::
-	$(Verb) $(RM) -f LLDBWrapPython.cpp $(PYTHON_DIR)/_lldb.so \
-	          $(PYTHON_DIR)/embedded_interpreter.py $(PYTHON_DIR)/__init__.py \
-			  $(addprefix $(PYTHON_DIR)/,$(LLDB_ALL_INSTALLED_SUBPACKAGE_FILES))
+	$(Verb) $(RM) -f LLDBWrapPython.cpp lldb.py

Removed: lldb/branches/lldb-platform-work/source/Interpreter/NamedOptionValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/NamedOptionValue.cpp?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/NamedOptionValue.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/NamedOptionValue.cpp (removed)
@@ -1,503 +0,0 @@
-//===-- NamedOptionValue.cpp ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Interpreter/NamedOptionValue.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/FormatManager.h"
-#include "lldb/Core/State.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Interpreter/Args.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-//-------------------------------------------------------------------------
-// OptionValue
-//-------------------------------------------------------------------------
-
-// Get this value as a uint64_t value if it is encoded as a boolean,
-// uint64_t or int64_t. Other types will cause "fail_value" to be 
-// returned
-uint64_t
-OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
-{
-    if (success_ptr)
-        *success_ptr = true;
-    switch (GetType())
-    {
-    case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
-    case OptionValue::eTypeSInt64:  return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
-    case OptionValue::eTypeUInt64:  return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
-    default: 
-        break;
-    }
-    if (success_ptr)
-        *success_ptr = false;
-    return fail_value;
-}
-
-
-OptionValueBoolean *
-OptionValue::GetAsBoolean ()
-{
-    if (GetType () == OptionValue::eTypeBoolean)
-        return static_cast<OptionValueBoolean *>(this);
-    return NULL;
-}
-
-OptionValueSInt64 *
-OptionValue::GetAsSInt64 ()
-{
-    if (GetType () == OptionValue::eTypeSInt64)
-        return static_cast<OptionValueSInt64 *>(this);
-    return NULL;
-}
-
-OptionValueUInt64 *
-OptionValue::GetAsUInt64 ()
-{
-    if (GetType () == OptionValue::eTypeUInt64)
-        return static_cast<OptionValueUInt64 *>(this);
-    return NULL;
-}
-
-OptionValueString *
-OptionValue::GetAsString ()
-{
-    if (GetType () == OptionValue::eTypeString)
-        return static_cast<OptionValueString *>(this);
-    return NULL;
-}
-
-OptionValueFileSpec *
-OptionValue::GetAsFileSpec ()
-{
-    if (GetType () == OptionValue::eTypeFileSpec)
-        return static_cast<OptionValueFileSpec *>(this);
-    return NULL;
-
-}
-
-OptionValueFormat *
-OptionValue::GetAsFormat ()
-{
-    if (GetType () == OptionValue::eTypeFormat)
-        return static_cast<OptionValueFormat *>(this);
-    return NULL;
-}
-
-OptionValueUUID *
-OptionValue::GetAsUUID ()
-{
-    if (GetType () == OptionValue::eTypeUUID)
-        return static_cast<OptionValueUUID *>(this);
-    return NULL;
-    
-}
-
-
-OptionValueArray *
-OptionValue::GetAsArray ()
-{
-    if (GetType () == OptionValue::eTypeArray)
-        return static_cast<OptionValueArray *>(this);
-    return NULL;
-}
-
-OptionValueDictionary *
-OptionValue::GetAsDictionary ()
-{
-    if (GetType () == OptionValue::eTypeDictionary)
-        return static_cast<OptionValueDictionary *>(this);
-    return NULL;
-}
-
-const char *
-OptionValue::GetStringValue (const char *fail_value)
-{
-    OptionValueString *option_value = GetAsString ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-uint64_t
-OptionValue::GetUInt64Value (uint64_t fail_value)
-{
-    OptionValueUInt64 *option_value = GetAsUInt64 ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-lldb::Format
-OptionValue::GetFormatValue (lldb::Format fail_value)
-{
-    OptionValueFormat *option_value = GetAsFormat ();
-    if (option_value)
-        return option_value->GetCurrentValue();
-    return fail_value;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueCollection
-//-------------------------------------------------------------------------
-
-void
-OptionValueCollection::GetQualifiedName (Stream &strm)
-{
-    if (m_parent)
-    {
-        m_parent->GetQualifiedName (strm);
-        strm.PutChar('.');
-    }
-    strm << m_name;
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueBoolean
-//-------------------------------------------------------------------------
-void
-OptionValueBoolean::DumpValue (Stream &strm)
-{
-    strm.PutCString (m_current_value ? "true" : "false");
-}
-
-Error
-OptionValueBoolean::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    bool success = false;
-    bool value = Args::StringToBoolean(value_cstr, false, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        if (value_cstr == NULL)
-            error.SetErrorString ("invalid boolean string value: NULL");
-        else if (value_cstr[0] == '\0')
-            error.SetErrorString ("invalid boolean string value <empty>");
-        else
-            error.SetErrorStringWithFormat ("invalid boolean string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueSInt64
-//-------------------------------------------------------------------------
-void
-OptionValueSInt64::DumpValue (Stream &strm)
-{
-    strm.Printf ("%lli", m_current_value);
-}
-
-Error
-OptionValueSInt64::SetValueFromCString (const char *value_cstr)
-{
- 
-    Error error;
-    bool success = false;
-    int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueUInt64
-//-------------------------------------------------------------------------
-
-lldb::OptionValueSP
-OptionValueUInt64::Create (const char *value_cstr, Error &error)
-{
-    lldb::OptionValueSP value_sp (new OptionValueUInt64());
-    error = value_sp->SetValueFromCString (value_cstr);
-    if (error.Fail())
-        value_sp.reset();
-    return value_sp;
-}
-
-
-void
-OptionValueUInt64::DumpValue (Stream &strm)
-{
-    strm.Printf ("0x%llx", m_current_value);
-}
-
-Error
-OptionValueUInt64::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    bool success = false;
-    uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success);
-    if (success)
-    {
-        m_value_was_set = true;
-        m_current_value = value;
-    }
-    else
-    {
-        error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'", value_cstr);
-    }
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueDictionary
-//-------------------------------------------------------------------------
-void
-OptionValueString::DumpValue (Stream &strm)
-{
-    strm.Printf ("\"%s\"", m_current_value.c_str());
-}
-
-Error
-OptionValueString::SetValueFromCString (const char *value_cstr)
-{
-    m_value_was_set = true;
-    SetCurrentValue (value_cstr);
-    return Error ();
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFileSpec
-//-------------------------------------------------------------------------
-void
-OptionValueFileSpec::DumpValue (Stream &strm)
-{
-    if (m_current_value)
-    {
-        if (m_current_value.GetDirectory())
-        {
-            strm << '"' << m_current_value.GetDirectory();
-            if (m_current_value.GetFilename())
-                strm << '/' << m_current_value.GetFilename();
-            strm << '"';
-        }
-        else
-        {
-            strm << '"' << m_current_value.GetFilename() << '"';
-        }
-    }
-}
-
-Error
-OptionValueFileSpec::SetValueFromCString (const char *value_cstr)
-{
-    if (value_cstr && value_cstr[0])
-        m_current_value.SetFile(value_cstr, false);
-    else
-        m_current_value.Clear();
-    m_value_was_set = true;
-    return Error();
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFileSpecList
-//-------------------------------------------------------------------------
-void
-OptionValueFileSpecList::DumpValue (Stream &strm)
-{
-    m_current_value.Dump(&strm, "\n");
-}
-
-Error
-OptionValueFileSpecList::SetValueFromCString (const char *value_cstr)
-{
-    if (value_cstr && value_cstr[0])
-    {
-        FileSpec file (value_cstr, false);
-        m_current_value.Append(file);
-    }
-    m_value_was_set = true;
-    return Error();
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueUUID
-//-------------------------------------------------------------------------
-void
-OptionValueUUID::DumpValue (Stream &strm)
-{
-    m_uuid.Dump (&strm);
-}
-
-Error
-OptionValueUUID::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    if (m_uuid.SetfromCString(value_cstr) == 0)
-        error.SetErrorStringWithFormat ("invalid uuid string value '%s'", value_cstr);
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueFormat
-//-------------------------------------------------------------------------
-void
-OptionValueFormat::DumpValue (Stream &strm)
-{
-    strm.PutCString (FormatManager::GetFormatAsCString (m_current_value));
-}
-
-Error
-OptionValueFormat::SetValueFromCString (const char *value_cstr)
-{
-    Format new_format;
-    Error error (Args::StringToFormat (value_cstr, new_format, NULL));
-    if (error.Success())
-    {
-        m_value_was_set = true;
-        m_current_value = new_format;
-    }
-    return error;
-}
-
-
-//-------------------------------------------------------------------------
-// OptionValueArray
-//-------------------------------------------------------------------------
-void
-OptionValueArray::DumpValue (Stream &strm)
-{
-    const uint32_t size = m_values.size();
-    for (uint32_t i = 0; i<size; ++i)
-    {
-        strm.Printf("[%u] ", i);
-        m_values[i]->DumpValue (strm);
-    }
-}
-
-Error
-OptionValueArray::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    error.SetErrorStringWithFormat ("array option values don't yet support being set by string: '%s'", value_cstr);
-    return error;
-}
-
-//-------------------------------------------------------------------------
-// OptionValueDictionary
-//-------------------------------------------------------------------------
-void
-OptionValueDictionary::DumpValue (Stream &strm)
-{
-    collection::iterator pos, end = m_values.end();
-
-    for (pos = m_values.begin(); pos != end; ++pos)
-    {
-        strm.Printf("%s=", pos->first.GetCString());
-        pos->second->DumpValue (strm);
-    }
-}
-
-Error
-OptionValueDictionary::SetValueFromCString (const char *value_cstr)
-{
-    Error error;
-    error.SetErrorStringWithFormat ("dictionary option values don't yet support being set by string: '%s'", value_cstr);
-    return error;
-}
-
-lldb::OptionValueSP
-OptionValueDictionary::GetValueForKey (const ConstString &key) const
-{
-    lldb::OptionValueSP value_sp;
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-        value_sp = pos->second;
-    return value_sp;
-}
-
-const char *
-OptionValueDictionary::GetStringValueForKey (const ConstString &key)
-{
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        if (pos->second->GetType() == OptionValue::eTypeString)
-            return static_cast<OptionValueString *>(pos->second.get())->GetCurrentValue();
-    }
-    return NULL;
-}
-
-
-bool
-OptionValueDictionary::SetStringValueForKey (const ConstString &key, 
-                                             const char *value, 
-                                             bool can_replace)
-{
-    collection::const_iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        if (!can_replace)
-            return false;
-        if (pos->second->GetType() == OptionValue::eTypeString)
-        {
-            pos->second->SetValueFromCString(value);
-            return true;
-        }
-    }
-    m_values[key] = OptionValueSP (new OptionValueString (value));
-    return true;
-
-}
-
-bool
-OptionValueDictionary::SetValueForKey (const ConstString &key, 
-                                       const lldb::OptionValueSP &value_sp, 
-                                       bool can_replace)
-{
-    // Make sure the value_sp object is allowed to contain
-    // values of the type passed in...
-    if (value_sp && (m_type_mask & value_sp->GetTypeAsMask()))
-    {
-        if (!can_replace)
-        {
-            collection::const_iterator pos = m_values.find (key);
-            if (pos != m_values.end())
-                return false;
-        }
-        m_values[key] = value_sp;
-        return true;
-    }
-    return false;
-}
-
-bool
-OptionValueDictionary::DeleteValueForKey (const ConstString &key)
-{
-    collection::iterator pos = m_values.find (key);
-    if (pos != m_values.end())
-    {
-        m_values.erase(pos);
-        return true;
-    }
-    return false;
-}
-
-

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupArchitecture.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupArchitecture.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupArchitecture.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupArchitecture.cpp Thu Jun  6 19:06:43 2013
@@ -62,7 +62,7 @@ OptionGroupArchitecture::SetOptionValue
                                  const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
 
     switch (short_option)
     {

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupBoolean.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupBoolean.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupBoolean.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupBoolean.cpp Thu Jun  6 19:06:43 2013
@@ -20,21 +20,20 @@ using namespace lldb_private;
 OptionGroupBoolean::OptionGroupBoolean (uint32_t usage_mask,
                                         bool required,
                                         const char *long_option, 
-                                        char short_option,
-                                        uint32_t completion_type,
-                                        lldb::CommandArgumentType argument_type,
+                                        int short_option,
                                         const char *usage_text,
-                                        bool default_value) :
+                                        bool default_value,
+                                        bool no_argument_toggle_default) :
     m_value (default_value, default_value)
 {
     m_option_definition.usage_mask = usage_mask;
     m_option_definition.required = required;
     m_option_definition.long_option = long_option;
     m_option_definition.short_option = short_option;
-    m_option_definition.option_has_arg = required_argument;
+    m_option_definition.option_has_arg = no_argument_toggle_default ? no_argument : required_argument;
     m_option_definition.enum_values = NULL;
-    m_option_definition.completion_type = completion_type;
-    m_option_definition.argument_type = argument_type;
+    m_option_definition.completion_type = 0;
+    m_option_definition.argument_type = eArgTypeBoolean;
     m_option_definition.usage_text = usage_text;
 }
 
@@ -47,7 +46,17 @@ OptionGroupBoolean::SetOptionValue (Comm
                                     uint32_t option_idx,
                                     const char *option_arg)
 {
-    Error error (m_value.SetValueFromCString (option_arg));
+    Error error;
+    if (m_option_definition.option_has_arg == no_argument)
+    {
+        // Not argument, toggle the default value and mark the option as having been set
+        m_value.SetCurrentValue (!m_value.GetDefaultValue());
+        m_value.SetOptionWasSet ();
+    }
+    else
+    {
+        error = m_value.SetValueFromCString (option_arg);
+    }
     return error;
 }
 

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFile.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFile.cpp Thu Jun  6 19:06:43 2013
@@ -20,7 +20,7 @@ using namespace lldb_private;
 OptionGroupFile::OptionGroupFile (uint32_t usage_mask,
                                   bool required,
                                   const char *long_option, 
-                                  char short_option,
+                                  int short_option,
                                   uint32_t completion_type,
                                   lldb::CommandArgumentType argument_type,
                                   const char *usage_text) :
@@ -43,8 +43,8 @@ OptionGroupFile::~OptionGroupFile ()
 
 Error
 OptionGroupFile::SetOptionValue (CommandInterpreter &interpreter,
-                                         uint32_t option_idx,
-                                         const char *option_arg)
+                                 uint32_t option_idx,
+                                 const char *option_arg)
 {
     Error error (m_file.SetValueFromCString (option_arg));
     return error;
@@ -60,7 +60,7 @@ OptionGroupFile::OptionParsingStarting (
 OptionGroupFileList::OptionGroupFileList (uint32_t usage_mask,
                                           bool required,
                                           const char *long_option, 
-                                          char short_option,
+                                          int short_option,
                                           uint32_t completion_type,
                                           lldb::CommandArgumentType argument_type,
                                           const char *usage_text) :
@@ -83,8 +83,8 @@ OptionGroupFileList::~OptionGroupFileLis
 
 Error
 OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter,
-                                 uint32_t option_idx,
-                                 const char *option_arg)
+                                     uint32_t option_idx,
+                                     const char *option_arg)
 {
     Error error (m_file_list.SetValueFromCString (option_arg));
     return error;

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFormat.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFormat.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupFormat.cpp Thu Jun  6 19:06:43 2013
@@ -7,12 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/OptionGroupFormat.h"
 
 // C Includes
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Utility/Utils.h"
 
 using namespace lldb;
@@ -67,7 +73,7 @@ OptionGroupFormat::SetOptionValue (Comma
                                    const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
 
     switch (short_option)
     {
@@ -119,7 +125,7 @@ OptionGroupFormat::SetOptionValue (Comma
                 Format format = eFormatDefault;
                 uint32_t byte_size = 0;
                 
-                while (ParserGDBFormatLetter (gdb_format_cstr[0], format, byte_size))
+                while (ParserGDBFormatLetter (interpreter, gdb_format_cstr[0], format, byte_size))
                 {
                     ++gdb_format_cstr;
                 }
@@ -139,7 +145,7 @@ OptionGroupFormat::SetOptionValue (Comma
                 // Anything that wasn't set correctly should be set to the
                 // previous default
                 if (format == eFormatInvalid)
-                    ParserGDBFormatLetter (m_prev_gdb_format, format, byte_size);
+                    ParserGDBFormatLetter (interpreter, m_prev_gdb_format, format, byte_size);
                 
                 const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX;
                 const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX;
@@ -147,7 +153,7 @@ OptionGroupFormat::SetOptionValue (Comma
                 {
                     // Byte size is enabled
                     if (byte_size == 0)
-                        ParserGDBFormatLetter (m_prev_gdb_size, format, byte_size);
+                        ParserGDBFormatLetter (interpreter, m_prev_gdb_size, format, byte_size);
                 }
                 else
                 {
@@ -161,9 +167,9 @@ OptionGroupFormat::SetOptionValue (Comma
 
                 if (count_enabled)
                 {
-                    // Count is enabled and was not set, set it to the default
+                    // Count is enabled and was not set, set it to the default for gdb format statements (which is 1).
                     if (count == 0)
-                        count = m_count.GetDefaultValue();
+                        count = 1;
                 }
                 else
                 {
@@ -199,8 +205,9 @@ OptionGroupFormat::SetOptionValue (Comma
 }
 
 bool
-OptionGroupFormat::ParserGDBFormatLetter (char format_letter, Format &format, uint32_t &byte_size)
+OptionGroupFormat::ParserGDBFormatLetter (CommandInterpreter &interpreter, char format_letter, Format &format, uint32_t &byte_size)
 {
+    m_has_gdb_format = true;
     switch (format_letter)
     {
         case 'o': format = eFormatOctal;        m_prev_gdb_format = format_letter; return true; 
@@ -209,7 +216,15 @@ OptionGroupFormat::ParserGDBFormatLetter
         case 'u': format = eFormatUnsigned;     m_prev_gdb_format = format_letter; return true;
         case 't': format = eFormatBinary;       m_prev_gdb_format = format_letter; return true;
         case 'f': format = eFormatFloat;        m_prev_gdb_format = format_letter; return true;
-        case 'a': format = eFormatAddressInfo;  m_prev_gdb_format = format_letter; return true;
+        case 'a': format = eFormatAddressInfo;
+        {
+            ExecutionContext exe_ctx(interpreter.GetExecutionContext());
+            Target *target = exe_ctx.GetTargetPtr();
+            if (target)
+                byte_size = target->GetArchitecture().GetAddressByteSize();
+            m_prev_gdb_format = format_letter;
+            return true;
+        }
         case 'i': format = eFormatInstruction;  m_prev_gdb_format = format_letter; return true;
         case 'c': format = eFormatChar;         m_prev_gdb_format = format_letter; return true;
         case 's': format = eFormatCString;      m_prev_gdb_format = format_letter; return true;
@@ -230,4 +245,5 @@ OptionGroupFormat::OptionParsingStarting
     m_format.Clear();
     m_byte_size.Clear();
     m_count.Clear();
+    m_has_gdb_format = false;
 }

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupOutputFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupOutputFile.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupOutputFile.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupOutputFile.cpp Thu Jun  6 19:06:43 2013
@@ -31,8 +31,8 @@ OptionGroupOutputFile::~OptionGroupOutpu
 static OptionDefinition
 g_option_table[] =
 {
-    { LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypePath , "Specify a path for capturing command output."},
-    { LLDB_OPT_SET_1 , false, "append-outfile" , 'A', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
+    { LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypeFilename , "Specify a path for capturing command output."},
+    { LLDB_OPT_SET_1 , false, "append-outfile" , 'apnd', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
 };
 
 uint32_t
@@ -49,11 +49,11 @@ OptionGroupOutputFile::GetDefinitions ()
 
 Error
 OptionGroupOutputFile::SetOptionValue (CommandInterpreter &interpreter,
-                                         uint32_t option_idx,
-                                         const char *option_arg)
+                                       uint32_t option_idx,
+                                       const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
 
     switch (short_option)
     {
@@ -61,7 +61,7 @@ OptionGroupOutputFile::SetOptionValue (C
             error = m_file.SetValueFromCString (option_arg);
             break;
 
-        case 'A':
+        case 'apnd':
             m_append.SetCurrentValue(true);
             break;
 

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupPlatform.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupPlatform.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupPlatform.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/OptionGroupPlatform.h"
 
 // C Includes
@@ -34,9 +36,11 @@ OptionGroupPlatform::CreatePlatformWithO
         platform_sp = Platform::Create (m_platform_name.c_str(), error);
         if (platform_sp)
         {
-            if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
+            if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
             {
-                error.SetErrorStringWithFormat("platform '%s' doesn't support '%s'", platform_sp->GetName(), arch.GetTriple().getTriple().c_str());
+                error.SetErrorStringWithFormat ("platform '%s' doesn't support '%s'",
+                                                platform_sp->GetName().GetCString(),
+                                                arch.GetTriple().getTriple().c_str());
                 platform_sp.reset();
                 return platform_sp;
             }
@@ -84,7 +88,7 @@ g_option_table[] =
     { LLDB_OPT_SET_ALL, false, "platform", 'p', required_argument, NULL, 0, eArgTypePlatform, "Specify name of the platform to use for this target, creating the platform if necessary."},
     { LLDB_OPT_SET_ALL, false, "version" , 'v', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." },
     { LLDB_OPT_SET_ALL, false, "build"   , 'b', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK build number." },
-    { LLDB_OPT_SET_ALL, false, "sysroot" , 's', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
+    { LLDB_OPT_SET_ALL, false, "sysroot" , 'S', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
 };
 
 const OptionDefinition*
@@ -113,7 +117,7 @@ OptionGroupPlatform::SetOptionValue (Com
     if (!m_include_platform_option)
         ++option_idx;
     
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
     
     switch (short_option)
     {
@@ -133,7 +137,7 @@ OptionGroupPlatform::SetOptionValue (Com
             m_sdk_build.SetCString (option_arg);
             break;
             
-        case 's':
+        case 'S':
             m_sdk_sysroot.SetCString (option_arg);
             break;
 

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUInt64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUInt64.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUInt64.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUInt64.cpp Thu Jun  6 19:06:43 2013
@@ -20,7 +20,7 @@ using namespace lldb_private;
 OptionGroupUInt64::OptionGroupUInt64 (uint32_t usage_mask,
                                         bool required,
                                         const char *long_option, 
-                                        char short_option,
+                                        int short_option,
                                         uint32_t completion_type,
                                         lldb::CommandArgumentType argument_type,
                                         const char *usage_text,

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUUID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUUID.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUUID.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupUUID.cpp Thu Jun  6 19:06:43 2013
@@ -47,11 +47,11 @@ OptionGroupUUID::GetDefinitions ()
 
 Error
 OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter,
-                                         uint32_t option_idx,
-                                         const char *option_arg)
+                                 uint32_t option_idx,
+                                 const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
 
     switch (short_option)
     {

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupValueObjectDisplay.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupValueObjectDisplay.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
 
 // C Includes
@@ -31,19 +33,18 @@ OptionGroupValueObjectDisplay::~OptionGr
 static OptionDefinition
 g_option_table[] =
 {
-    { LLDB_OPT_SET_1, false, "dynamic-type",     'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, 
-                                                                              0, eArgTypeNone,      "Show the object as its full dynamic type, not its static type, if available."},
-    { LLDB_OPT_SET_1, false, "synthetic-type",   'S', required_argument, NULL, 0, eArgTypeBoolean,   "Show the object obeying its synthetic provider, if available."},
-    { LLDB_OPT_SET_1, false, "depth",            'D', required_argument, NULL, 0, eArgTypeCount,     "Set the max recurse depth when dumping aggregate types (default is infinity)."},
-    { LLDB_OPT_SET_1, false, "flat",             'F', no_argument,       NULL, 0, eArgTypeNone,      "Display results in a flat format that uses expression paths for each variable or member."},
-    { LLDB_OPT_SET_1, false, "location",         'L', no_argument,       NULL, 0, eArgTypeNone,      "Show variable location information."},
-    { LLDB_OPT_SET_1, false, "objc",             'O', no_argument,       NULL, 0, eArgTypeNone,      "Print as an Objective-C object."},
-    { LLDB_OPT_SET_1, false, "ptr-depth",        'P', required_argument, NULL, 0, eArgTypeCount,     "The number of pointers to be traversed when dumping values (default is zero)."},
-    { LLDB_OPT_SET_1, false, "show-types",       'T', no_argument,       NULL, 0, eArgTypeNone,      "Show variable types when dumping values."},
-    { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', optional_argument, NULL, 0, eArgTypeCount,     "Set the depth at which omitting summary information stops (default is 1)."},
-    { LLDB_OPT_SET_1, false, "raw-output",       'R', no_argument,       NULL, 0, eArgTypeNone,      "Don't use formatting options."},
-    { LLDB_OPT_SET_1, false, "show-all-children",'A', no_argument,       NULL, 0, eArgTypeNone,      "Ignore the upper bound on the number of children to show."},
-    { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
+    { LLDB_OPT_SET_1, false, "dynamic-type",       'd', required_argument, g_dynamic_value_types, 0, eArgTypeNone,      "Show the object as its full dynamic type, not its static type, if available."},
+    { LLDB_OPT_SET_1, false, "synthetic-type",     'S', required_argument, NULL, 0, eArgTypeBoolean,   "Show the object obeying its synthetic provider, if available."},
+    { LLDB_OPT_SET_1, false, "depth",              'D', required_argument, NULL, 0, eArgTypeCount,     "Set the max recurse depth when dumping aggregate types (default is infinity)."},
+    { LLDB_OPT_SET_1, false, "flat",               'F', no_argument,       NULL, 0, eArgTypeNone,      "Display results in a flat format that uses expression paths for each variable or member."},
+    { LLDB_OPT_SET_1, false, "location",           'L', no_argument,       NULL, 0, eArgTypeNone,      "Show variable location information."},
+    { LLDB_OPT_SET_1, false, "object-description", 'O', no_argument,       NULL, 0, eArgTypeNone,      "Print as an Objective-C object."},
+    { LLDB_OPT_SET_1, false, "ptr-depth",          'P', required_argument, NULL, 0, eArgTypeCount,     "The number of pointers to be traversed when dumping values (default is zero)."},
+    { LLDB_OPT_SET_1, false, "show-types",         'T', no_argument,       NULL, 0, eArgTypeNone,      "Show variable types when dumping values."},
+    { LLDB_OPT_SET_1, false, "no-summary-depth",   'Y', optional_argument, NULL, 0, eArgTypeCount,     "Set the depth at which omitting summary information stops (default is 1)."},
+    { LLDB_OPT_SET_1, false, "raw-output",         'R', no_argument,       NULL, 0, eArgTypeNone,      "Don't use formatting options."},
+    { LLDB_OPT_SET_1, false, "show-all-children",  'A', no_argument,       NULL, 0, eArgTypeNone,      "Ignore the upper bound on the number of children to show."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
 uint32_t
@@ -65,7 +66,7 @@ OptionGroupValueObjectDisplay::SetOption
                                                const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
     bool success = false;
 
     switch (short_option)
@@ -73,7 +74,7 @@ OptionGroupValueObjectDisplay::SetOption
         case 'd':
             {
                 int32_t result;
-                result = Args::StringToOptionEnum (option_arg, TargetInstanceSettings::g_dynamic_value_types, 2, error);
+                result = Args::StringToOptionEnum (option_arg, g_dynamic_value_types, 2, error);
                 if (error.Success())
                     use_dynamic = (lldb::DynamicValueType) result;
             }
@@ -145,3 +146,36 @@ OptionGroupValueObjectDisplay::OptionPar
         use_dynamic = lldb::eNoDynamicValues;
     }
 }
+
+ValueObject::DumpValueObjectOptions
+OptionGroupValueObjectDisplay::GetAsDumpOptions (bool objc_is_compact,
+                                                 lldb::Format format,
+                                                 lldb::TypeSummaryImplSP summary_sp)
+{
+    ValueObject::DumpValueObjectOptions options;
+    options.SetMaximumPointerDepth(ptr_depth);
+    if (use_objc)
+        options.SetShowSummary(false);
+    else
+        options.SetOmitSummaryDepth(no_summary_depth);
+    options.SetMaximumDepth(max_depth)
+    .SetShowTypes(show_types)
+    .SetShowLocation(show_location)
+    .SetUseObjectiveC(use_objc)
+    .SetUseDynamicType(use_dynamic)
+    .SetUseSyntheticValue(use_synth)
+    .SetFlatOutput(flat_output)
+    .SetIgnoreCap(ignore_cap)
+    .SetFormat(format)
+    .SetSummary(summary_sp);
+    
+    if (objc_is_compact)
+        options.SetHideRootType(use_objc)
+        .SetHideName(use_objc)
+        .SetHideValue(use_objc);
+    
+    if (be_raw)
+        options.SetRawDisplay(true);
+
+    return options;
+}

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupVariable.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupVariable.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupVariable.cpp Thu Jun  6 19:06:43 2013
@@ -7,14 +7,18 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/OptionGroupVariable.h"
 
 // C Includes
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Target/Target.h"
+#include "lldb/Core/Error.h"
+#include "lldb/DataFormatters/DataVisualization.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Utility/Utils.h"
 
 using namespace lldb;
@@ -24,20 +28,40 @@ using namespace lldb_private;
 static OptionDefinition
 g_option_table[] =
 {
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args",         'a', no_argument,       NULL, 0, eArgTypeNone,    "Omit function arguments."},
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals",       'l', no_argument,       NULL, 0, eArgTypeNone,    "Omit local variables."},
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals",    'g', no_argument,       NULL, 0, eArgTypeNone,    "Show the current frame source file global and static variables."},
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument,       NULL, 0, eArgTypeNone,    "Show variable declaration information (source file and line where the variable was declared)."},
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex",           'r', no_argument,       NULL, 0, eArgTypeRegularExpression,    "The <variable-name> argument for name lookups are regular expressions."},
-    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope",           's', no_argument,       NULL, 0, eArgTypeNone,    "Show variable scope (argument, local, global, static)."},
-    { LLDB_OPT_SET_1, false, "summary",         'y', required_argument, NULL, 0, eArgTypeName,  "Specify the summary that the variable output should use."},
-    { LLDB_OPT_SET_2, false, "summary-string",  'z', required_argument, NULL, 0, eArgTypeName,  "Specify a summary string to use to format the variable output."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args",         'a', no_argument,       NULL, 0, eArgTypeNone, "Omit function arguments."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals",       'l', no_argument,       NULL, 0, eArgTypeNone, "Omit local variables."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals",    'g', no_argument,       NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument,       NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex",           'r', no_argument,       NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope",           's', no_argument,       NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
+    { LLDB_OPT_SET_1,                  false, "summary",         'y', required_argument, NULL, 0, eArgTypeName, "Specify the summary that the variable output should use."},
+    { LLDB_OPT_SET_2,                  false, "summary-string",  'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
 };
 
+static Error
+ValidateNamedSummary (const char* str, void*)
+{
+    if (!str || !str[0])
+        return Error("must specify a valid named summary");
+    TypeSummaryImplSP summary_sp;
+    if (DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(str), summary_sp) == false)
+        return Error("must specify a valid named summary");
+    return Error();
+}
+
+static Error
+ValidateSummaryString (const char* str, void*)
+{
+    if (!str || !str[0])
+        return Error("must specify a non-empty summary string");
+    return Error();
+}
 
 OptionGroupVariable::OptionGroupVariable (bool show_frame_options) :
     OptionGroup(),
-    include_frame_options (show_frame_options)
+    include_frame_options (show_frame_options),
+    summary(ValidateNamedSummary),
+    summary_string(ValidateSummaryString)
 {
 }
 
@@ -53,7 +77,7 @@ OptionGroupVariable::SetOptionValue (Com
     Error error;
     if (!include_frame_options)
         option_idx += 3;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
     switch (short_option)
     {
         case 'r':   use_regex    = true;  break;
@@ -65,10 +89,10 @@ OptionGroupVariable::SetOptionValue (Com
             show_scope = true;
             break;
         case 'y':
-            summary.SetCurrentValue(option_arg);
+            error = summary.SetCurrentValue(option_arg);
             break;
         case 'z':
-            summary_string.SetCurrentValue(option_arg);
+            error = summary_string.SetCurrentValue(option_arg);
             break;
         default:
             error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);

Modified: lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/OptionGroupWatchpoint.cpp Thu Jun  6 19:06:43 2013
@@ -73,7 +73,7 @@ OptionGroupWatchpoint::SetOptionValue (C
                                        const char *option_arg)
 {
     Error error;
-    char short_option = (char) g_option_table[option_idx].short_option;
+    const int short_option = g_option_table[option_idx].short_option;
     switch (short_option)
     {
         case 'w':

Modified: lldb/branches/lldb-platform-work/source/Interpreter/Options.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/Options.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/Options.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/Options.cpp Thu Jun  6 19:06:43 2013
@@ -7,13 +7,15 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/Options.h"
 
 // C Includes
 // C++ Includes
 #include <algorithm>
 #include <bitset>
-#include <set>
+#include <map>
 
 // Other libraries and framework includes
 // Project includes
@@ -58,7 +60,7 @@ Options::NotifyOptionParsingFinished ()
 void
 Options::OptionSeen (int option_idx)
 {
-    m_seen_options.insert ((char) option_idx);
+    m_seen_options.insert (option_idx);
 }
 
 // Returns true is set_a is a subset of set_b;  Otherwise returns false.
@@ -266,33 +268,54 @@ Options::GetLongOptions ()
             return NULL;
 
         uint32_t i;
-        uint32_t j;
         const OptionDefinition *opt_defs = GetDefinitions();
 
-        std::bitset<256> option_seen;
+        std::map<int, uint32_t> option_seen;
 
         m_getopt_table.resize(num_options + 1);
-        for (i = 0, j = 0; i < num_options; ++i)
+        for (i = 0; i < num_options; ++i)
         {
-            char short_opt = opt_defs[i].short_option;
+            const int short_opt = opt_defs[i].short_option;
 
-            if (option_seen.test(short_opt) == false)
-            {
-                m_getopt_table[j].name    = opt_defs[i].long_option;
-                m_getopt_table[j].has_arg = opt_defs[i].option_has_arg;
-                m_getopt_table[j].flag    = NULL;
-                m_getopt_table[j].val     = opt_defs[i].short_option;
-                option_seen.set(short_opt);
-                ++j;
+            m_getopt_table[i].name    = opt_defs[i].long_option;
+            m_getopt_table[i].has_arg = opt_defs[i].option_has_arg;
+            m_getopt_table[i].flag    = NULL;
+            m_getopt_table[i].val     = short_opt;
+
+            if (option_seen.find(short_opt) == option_seen.end())
+            {
+                option_seen[short_opt] = i;
+            }
+            else if (short_opt)
+            {
+                m_getopt_table[i].val = 0;
+                std::map<int, uint32_t>::const_iterator pos = option_seen.find(short_opt);
+                StreamString strm;
+                if (isprint8(short_opt))
+                    Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option -%c that conflicts with option[%u] --%s, short option won't be used for --%s\n",
+                                i,
+                                opt_defs[i].long_option,
+                                short_opt,
+                                pos->second,
+                                m_getopt_table[pos->second].name,
+                                opt_defs[i].long_option);
+                else
+                    Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option 0x%x that conflicts with option[%u] --%s, short option won't be used for --%s\n",
+                                i,
+                                opt_defs[i].long_option,
+                                short_opt,
+                                pos->second,
+                                m_getopt_table[pos->second].name,
+                                opt_defs[i].long_option);
             }
         }
 
-        //getopt_long requires a NULL final entry in the table:
-
-        m_getopt_table[j].name    = NULL;
-        m_getopt_table[j].has_arg = 0;
-        m_getopt_table[j].flag    = NULL;
-        m_getopt_table[j].val     = 0;
+        //getopt_long_only requires a NULL final entry in the table:
+
+        m_getopt_table[i].name    = NULL;
+        m_getopt_table[i].has_arg = 0;
+        m_getopt_table[i].flag    = NULL;
+        m_getopt_table[i].val     = 0;
     }
 
     if (m_getopt_table.empty())
@@ -389,6 +412,57 @@ Options::SupportsLongOption (const char
     return false;
 }
 
+enum OptionDisplayType
+{
+    eDisplayBestOption,
+    eDisplayShortOption,
+    eDisplayLongOption
+};
+
+static bool
+PrintOption (const OptionDefinition &opt_def,
+             OptionDisplayType display_type,
+             const char *header,
+             const char *footer,
+             bool show_optional,
+             Stream &strm)
+{
+    const bool has_short_option = isprint8(opt_def.short_option) != 0;
+
+    if (display_type == eDisplayShortOption && !has_short_option)
+        return false;
+
+    if (header && header[0])
+        strm.PutCString(header);
+    
+    if (show_optional && !opt_def.required)
+    strm.PutChar('[');
+    const bool show_short_option = has_short_option && display_type != eDisplayLongOption;
+    if (show_short_option)
+        strm.Printf ("-%c", opt_def.short_option);
+    else
+        strm.Printf ("--%s", opt_def.long_option);
+    switch (opt_def.option_has_arg)
+    {
+        case no_argument:
+            break;
+        case required_argument:
+            strm.Printf (" <%s>", CommandObject::GetArgumentName (opt_def.argument_type));
+            break;
+            
+        case optional_argument:
+            strm.Printf ("%s[<%s>]",
+                         show_short_option ? "" : "=",
+                         CommandObject::GetArgumentName (opt_def.argument_type));
+            break;
+    }
+    if (show_optional && !opt_def.required)
+        strm.PutChar(']');
+    if (footer && footer[0])
+        strm.PutCString(footer);
+    return true;
+}
+
 void
 Options::GenerateOptionUsage
 (
@@ -439,18 +513,18 @@ Options::GenerateOptionUsage
 
         // Different option sets may require different args.
         StreamString args_str;
-        cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
+        if (cmd)
+            cmd->GetFormattedCommandArguments(args_str, opt_set_mask);
 
         // First go through and print all options that take no arguments as
         // a single string. If a command has "-a" "-b" and "-c", this will show
         // up as [-abc]
 
-        std::set<char> options;
-        std::set<char>::const_iterator options_pos, options_end;
-        bool first;
-        for (i = 0, first = true; i < num_options; ++i)
+        std::set<int> options;
+        std::set<int>::const_iterator options_pos, options_end;
+        for (i = 0; i < num_options; ++i)
         {
-            if (opt_defs[i].usage_mask & opt_set_mask)
+            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
             {
                 // Add current option to the end of out_stream.
 
@@ -471,17 +545,17 @@ Options::GenerateOptionUsage
                      options_pos != options_end;
                      ++options_pos)
                 {
-                    if (i==0 && ::isupper (*options_pos))
+                    if (i==0 && ::islower (*options_pos))
                         continue;
-                    if (i==1 && ::islower (*options_pos))
+                    if (i==1 && ::isupper (*options_pos))
                         continue;
-                    strm << *options_pos;
+                    strm << (char)*options_pos;
                 }
         }
 
         for (i = 0, options.clear(); i < num_options; ++i)
         {
-            if (opt_defs[i].usage_mask & opt_set_mask)
+            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
             {
                 // Add current option to the end of out_stream.
 
@@ -502,11 +576,11 @@ Options::GenerateOptionUsage
                      options_pos != options_end;
                      ++options_pos)
                 {
-                    if (i==0 && ::isupper (*options_pos))
+                    if (i==0 && ::islower (*options_pos))
                         continue;
-                    if (i==1 && ::islower (*options_pos))
+                    if (i==1 && ::isupper (*options_pos))
                         continue;
-                    strm << *options_pos;
+                    strm << (char)*options_pos;
                 }
             strm.PutChar(']');
         }
@@ -515,26 +589,10 @@ Options::GenerateOptionUsage
         
         for (i = 0; i < num_options; ++i)
         {
-            if (opt_defs[i].usage_mask & opt_set_mask)
+            if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
             {
-                // Add current option to the end of out_stream.
-                CommandArgumentType arg_type = opt_defs[i].argument_type;
-                
-                if (opt_defs[i].required)
-                {
-                    if (opt_defs[i].option_has_arg == required_argument)
-                    {
-                        strm.Printf (" -%c <%s>",
-                                     opt_defs[i].short_option, 
-                                     CommandObject::GetArgumentName (arg_type));
-                    }
-                    else if (opt_defs[i].option_has_arg == optional_argument)
-                    {
-                        strm.Printf (" -%c [<%s>]",
-                                     opt_defs[i].short_option,
-                                     CommandObject::GetArgumentName (arg_type));
-                    }
-                }
+                if (opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+                    PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
             }
         }
 
@@ -546,17 +604,8 @@ Options::GenerateOptionUsage
             {
                 // Add current option to the end of out_stream.
 
-                CommandArgumentType arg_type = opt_defs[i].argument_type;
-                
-                if (! opt_defs[i].required)
-                {
-                    if (opt_defs[i].option_has_arg == required_argument)
-                        strm.Printf (" [-%c <%s>]", opt_defs[i].short_option,
-                                     CommandObject::GetArgumentName (arg_type));
-                    else if (opt_defs[i].option_has_arg == optional_argument)
-                        strm.Printf (" [-%c [<%s>]]", opt_defs[i].short_option,
-                                     CommandObject::GetArgumentName (arg_type));
-                }
+                if (!opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+                    PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
             }
         }
         
@@ -569,7 +618,8 @@ Options::GenerateOptionUsage
         }
     }
     
-    if (cmd->WantsRawCommandString() &&
+    if (cmd &&
+        cmd->WantsRawCommandString() &&
         arguments_str.GetSize() > 0)
     {        
         strm.PutChar('\n');
@@ -586,86 +636,69 @@ Options::GenerateOptionUsage
     // This variable is used to keep track of which options' info we've printed out, because some options can be in
     // more than one usage level, but we only want to print the long form of its information once.
 
-    OptionSet options_seen;
-    OptionSet::iterator pos;
+    std::multimap<int, uint32_t> options_seen;
     strm.IndentMore (5);
 
-    std::vector<char> sorted_options;
-
-
     // Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
     // when writing out detailed help for each option.
 
     for (i = 0; i < num_options; ++i)
-    {
-        pos = options_seen.find (opt_defs[i].short_option);
-        if (pos == options_seen.end())
-        {
-            options_seen.insert (opt_defs[i].short_option);
-            sorted_options.push_back (opt_defs[i].short_option);
-        }
-    }
-
-    std::sort (sorted_options.begin(), sorted_options.end());
+        options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
 
     // Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
     // and write out the detailed help information for that option.
 
-    int first_option_printed = 1;
-    size_t end = sorted_options.size();
-    for (size_t j = 0; j < end; ++j)
-    {
-        char option = sorted_options[j];
-        bool found = false;
-        for (i = 0; i < num_options && !found; ++i)
-        {
-            if (opt_defs[i].short_option == option)
-            {
-                found = true;
-                //Print out the help information for this option.
-
-                // Put a newline separation between arguments
-                if (first_option_printed)
-                    first_option_printed = 0;
-                else
-                    strm.EOL();
-                
-                CommandArgumentType arg_type = opt_defs[i].argument_type;
-                
-                StreamString arg_name_str;
-                arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
+    bool first_option_printed = false;;
 
-                strm.Indent ();
-                strm.Printf ("-%c", opt_defs[i].short_option);
-                if (arg_type != eArgTypeNone)
-                    strm.Printf (" <%s>",  CommandObject::GetArgumentName (arg_type));
-                strm.Printf ("  ( --%s", opt_defs[i].long_option);
-                if (arg_type != eArgTypeNone)
-                    strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
-                strm.PutCString(" )\n");
-                
-                strm.IndentMore (5);
-                
-                if (opt_defs[i].usage_text)
-                    OutputFormattedUsageText (strm,
-                                              opt_defs[i].usage_text,
-                                              screen_width);
-                if (opt_defs[i].enum_values != NULL)
-                {
-                    strm.Indent ();
-                    strm.Printf("Values: ");
-                    for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++) 
-                    {
-                        if (k == 0)
-                            strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
-                        else
-                            strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
-                    }
-                    strm.EOL();
-                }
-                strm.IndentLess (5);
+    for (auto pos : options_seen)
+    {
+        i = pos.second;
+        //Print out the help information for this option.
+
+        // Put a newline separation between arguments
+        if (first_option_printed)
+            strm.EOL();
+        else
+            first_option_printed = true;
+        
+        CommandArgumentType arg_type = opt_defs[i].argument_type;
+        
+        StreamString arg_name_str;
+        arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
+
+        strm.Indent ();
+        if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option))
+        {
+            PrintOption (opt_defs[i], eDisplayShortOption, NULL, NULL, false, strm);
+            PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
+        }
+        else
+        {
+            // Short option is not printable, just print long option
+            PrintOption (opt_defs[i], eDisplayLongOption, NULL, NULL, false, strm);
+        }
+        strm.EOL();
+        
+        strm.IndentMore (5);
+        
+        if (opt_defs[i].usage_text)
+            OutputFormattedUsageText (strm,
+                                      opt_defs[i].usage_text,
+                                      screen_width);
+        if (opt_defs[i].enum_values != NULL)
+        {
+            strm.Indent ();
+            strm.Printf("Values: ");
+            for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++) 
+            {
+                if (k == 0)
+                    strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
+                else
+                    strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
             }
+            strm.EOL();
         }
+        strm.IndentLess (5);
     }
 
     // Restore the indent level
@@ -762,7 +795,7 @@ Options::HandleOptionCompletion
             }
             else if (opt_defs_index != OptionArgElement::eUnrecognizedArg)
             {
-                // We recognized it, if it an incomplete long option, complete it anyway (getopt_long is
+                // We recognized it, if it an incomplete long option, complete it anyway (getopt_long_only is
                 // happy with shortest unique string, but it's still a nice thing to do.)  Otherwise return
                 // The string so the upper level code will know this is a full match and add the " ".
                 if (cur_opt_str && strlen (cur_opt_str) > 2
@@ -785,7 +818,7 @@ Options::HandleOptionCompletion
                 // FIXME - not handling wrong options yet:
                 // Check to see if they are writing a long option & complete it.
                 // I think we will only get in here if the long option table has two elements
-                // that are not unique up to this point.  getopt_long does shortest unique match
+                // that are not unique up to this point.  getopt_long_only does shortest unique match
                 // for long options already.
 
                 if (cur_opt_str && strlen (cur_opt_str) > 2
@@ -867,7 +900,7 @@ Options::HandleOptionArgumentCompletion
 )
 {
     const OptionDefinition *opt_defs = GetDefinitions();
-    std::auto_ptr<SearchFilter> filter_ap;
+    std::unique_ptr<SearchFilter> filter_ap;
 
     int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
     int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;

Copied: lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp (from r182522, lldb/trunk/source/Interpreter/PythonDataObjects.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp?p2=lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp&p1=lldb/trunk/source/Interpreter/PythonDataObjects.cpp&r1=182522&r2=183468&rev=183468&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/PythonDataObjects.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/PythonDataObjects.cpp Thu Jun  6 19:06:43 2013
@@ -21,6 +21,10 @@
 #include <Python.h>
 #endif
 
+#include <stdio.h>
+
+#include "lldb/Core/Stream.h"
+#include "lldb/Host/File.h"
 #include "lldb/Interpreter/PythonDataObjects.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
 
@@ -37,6 +41,31 @@ PythonObject::PythonObject (const lldb::
         Reset ((PyObject *)script_object_sp->GetObject());
 }
 
+void
+PythonObject::Dump (Stream &strm) const
+{
+    if (m_py_obj)
+    {
+        FILE *file = ::tmpfile();
+        if (file)
+        {
+            ::PyObject_Print (m_py_obj, file, 0);
+            const long length = ftell (file);
+            if (length)
+            {
+                ::rewind(file);
+                std::vector<char> file_contents (length,'\0');
+                const size_t length_read = ::fread (file_contents.data(), 1, file_contents.size(), file);
+                if (length_read > 0)
+                    strm.Write (file_contents.data(), length_read);
+            }
+            ::fclose (file);
+        }
+    }
+    else
+        strm.PutCString ("NULL");
+}
+
 //----------------------------------------------------------------------
 // PythonString
 //----------------------------------------------------------------------

Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreter.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreter.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/ScriptInterpreter.h"
 
 #include <string>
@@ -79,6 +81,12 @@ ScriptInterpreter::LanguageToString (lld
     return return_value;
 }
 
+std::unique_ptr<ScriptInterpreterLocker>
+ScriptInterpreter::AcquireInterpreterLock ()
+{
+    return std::unique_ptr<ScriptInterpreterLocker>(new ScriptInterpreterLocker());
+}
+
 void
 ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
 {

Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterNone.cpp Thu Jun  6 19:06:43 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Interpreter/ScriptInterpreterNone.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StringList.h"
@@ -26,7 +28,7 @@ ScriptInterpreterNone::~ScriptInterprete
 }
 
 bool
-ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, bool enable_io)
+ScriptInterpreterNone::ExecuteOneLine (const char *command, CommandReturnObject *, const ExecuteScriptOptions&)
 {
     m_interpreter.GetDebugger().GetErrorStream().PutCString ("error: there is no embedded script interpreter in this mode.\n");
     return false;

Modified: lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Interpreter/ScriptInterpreterPython.cpp Thu Jun  6 19:06:43 2013
@@ -52,9 +52,12 @@ static ScriptInterpreter::SWIGPythonCalc
 static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = NULL;
 static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = NULL;
 static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue  = NULL;
+static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = NULL;
 static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = NULL;
+static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = NULL;
 static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = NULL;
 static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = NULL;
+static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = NULL;
 
 // these are the Pythonic implementations of the required callbacks
 // these are scripting-language specific, which is why they belong here
@@ -62,169 +65,124 @@ static ScriptInterpreter::SWIGPythonCall
 // on linkage-time resolution because the SWIG stuff and this file
 // get built at different times
 extern "C" bool
-LLDBSwigPythonBreakpointCallbackFunction 
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame, 
- const lldb::BreakpointLocationSP& sb_bp_loc
- );
+LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name,
+                                          const char *session_dictionary_name,
+                                          const lldb::StackFrameSP& sb_frame,
+                                          const lldb::BreakpointLocationSP& sb_bp_loc);
 
 extern "C" bool
-LLDBSwigPythonWatchpointCallbackFunction 
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame, 
- const lldb::WatchpointSP& sb_wp
- );
+LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name,
+                                          const char *session_dictionary_name,
+                                          const lldb::StackFrameSP& sb_frame,
+                                          const lldb::WatchpointSP& sb_wp);
 
 extern "C" bool
-LLDBSwigPythonCallTypeScript 
-(
- const char *python_function_name,
- void *session_dictionary,
- const lldb::ValueObjectSP& valobj_sp,
- void** pyfunct_wrapper,
- std::string& retval
- );
+LLDBSwigPythonCallTypeScript (const char *python_function_name,
+                              void *session_dictionary,
+                              const lldb::ValueObjectSP& valobj_sp,
+                              void** pyfunct_wrapper,
+                              std::string& retval);
 
 extern "C" void*
-LLDBSwigPythonCreateSyntheticProvider 
-(
- const std::string python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP& valobj_sp
- );
+LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name,
+                                       const char *session_dictionary_name,
+                                       const lldb::ValueObjectSP& valobj_sp);
 
 
-extern "C" uint32_t       LLDBSwigPython_CalculateNumChildren        (void *implementor);
-extern "C" void*          LLDBSwigPython_GetChildAtIndex             (void *implementor, uint32_t idx);
-extern "C" int            LLDBSwigPython_GetIndexOfChildWithName     (void *implementor, const char* child_name);
-extern "C" void*          LLDBSWIGPython_CastPyObjectToSBValue       (void* data);
-extern "C" bool           LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+extern "C" uint32_t
+LLDBSwigPython_CalculateNumChildren (void *implementor);
 
-extern "C" bool           LLDBSwigPythonCallCommand 
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger,
- const char* args,
- std::string& err_msg,
- lldb_private::CommandReturnObject& cmd_retobj
- );
+extern "C" void *
+LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
 
-extern "C" bool           LLDBSwigPythonCallModuleInit 
-(
- const std::string python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger
- );
+extern "C" int
+LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
 
-static int
-_check_and_flush (FILE *stream)
-{
-  int prev_fail = ferror (stream);
-  return fflush (stream) || prev_fail ? EOF : 0;
-}
+extern "C" void *
+LLDBSWIGPython_CastPyObjectToSBValue (void* data);
 
-static Predicate<lldb::tid_t> &
-PythonMutexPredicate ()
-{
-    static lldb_private::Predicate<lldb::tid_t> g_interpreter_is_running (LLDB_INVALID_THREAD_ID);
-    return g_interpreter_is_running;
-}
+extern lldb::ValueObjectSP
+LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data);
 
-bool
-ScriptInterpreterPython::Locker::CurrentThreadHasPythonLock ()
-{
-    TimeValue timeout;
+extern "C" bool
+LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
 
-    timeout = TimeValue::Now();  // Don't wait any time.
+extern "C" bool
+LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
 
-    return PythonMutexPredicate().WaitForValueEqualTo (Host::GetCurrentThreadID(), &timeout, NULL);
-}
+extern "C" bool
+LLDBSwigPythonCallCommand (const char *python_function_name,
+                           const char *session_dictionary_name,
+                           lldb::DebuggerSP& debugger,
+                           const char* args,
+                           std::string& err_msg,
+                           lldb_private::CommandReturnObject& cmd_retobj);
 
-bool
-ScriptInterpreterPython::Locker::TryGetPythonLock (uint32_t seconds_to_wait)
-{
-    
-    TimeValue timeout;
-    
-    if (seconds_to_wait != UINT32_MAX)
-    {
-        timeout = TimeValue::Now();
-        timeout.OffsetWithSeconds (seconds_to_wait);
-    }
-    
-    return PythonMutexPredicate().WaitForValueEqualToAndSetValueTo (LLDB_INVALID_THREAD_ID, 
-                                                                    Host::GetCurrentThreadID(), &timeout, NULL);
-}
+extern "C" bool
+LLDBSwigPythonCallModuleInit (const char *python_module_name,
+                              const char *session_dictionary_name,
+                              lldb::DebuggerSP& debugger);
 
-void
-ScriptInterpreterPython::Locker::ReleasePythonLock ()
+extern "C" void*
+LLDBSWIGPythonCreateOSPlugin (const char *python_class_name,
+                              const char *session_dictionary_name,
+                              const lldb::ProcessSP& process_sp);
+
+static int
+_check_and_flush (FILE *stream)
 {
-    PythonMutexPredicate().SetValue (LLDB_INVALID_THREAD_ID, eBroadcastAlways);
+  int prev_fail = ferror (stream);
+  return fflush (stream) || prev_fail ? EOF : 0;
 }
 
 ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter,
                                          uint16_t on_entry,
                                          uint16_t on_leave,
                                          FILE* wait_msg_handle) :
-    m_need_session( (on_leave & TearDownSession) == TearDownSession ),
-    m_release_lock ( false ), // decide in constructor body
+    ScriptInterpreterLocker (),
+    m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
     m_python_interpreter(py_interpreter),
     m_tmp_fh(wait_msg_handle)
 {
     if (m_python_interpreter && !m_tmp_fh)
         m_tmp_fh = (m_python_interpreter->m_dbg_stdout ? m_python_interpreter->m_dbg_stdout : stdout);
-    
-    if ( (on_entry & AcquireLock) == AcquireLock )
+
+    DoAcquireLock();
+    if ((on_entry & InitSession) == InitSession)
     {
-        if (CurrentThreadHasPythonLock())
+        if (DoInitSession((on_entry & InitGlobals) == InitGlobals) == false)
         {
-            if ( (on_leave & FreeLock) == FreeLock )
-                m_release_lock = true;
-        }
-        else
-        {
-            DoAcquireLock();
-            if ( (on_leave & FreeLock) == FreeLock )
-                m_release_lock = true;
-            if ( (on_leave & FreeAcquiredLock) == FreeAcquiredLock )
-                m_release_lock = true;
+            // Don't teardown the session if we didn't init it.
+            m_teardown_session = false;
         }
     }
-    if ( (on_entry & InitSession) == InitSession )
-        DoInitSession();
 }
 
 bool
 ScriptInterpreterPython::Locker::DoAcquireLock()
 {
-    if (!CurrentThreadHasPythonLock())
-    {
-        while (!TryGetPythonLock (1))
-            if (m_tmp_fh)
-                fprintf (m_tmp_fh, 
-                         "Python interpreter locked on another thread; waiting to acquire lock...\n");
-    }
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+    m_GILState = PyGILState_Ensure();
+    if (log)
+        log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
     return true;
 }
 
 bool
-ScriptInterpreterPython::Locker::DoInitSession()
+ScriptInterpreterPython::Locker::DoInitSession(bool init_lldb_globals)
 {
     if (!m_python_interpreter)
         return false;
-    m_python_interpreter->EnterSession ();
-    return true;
+    return m_python_interpreter->EnterSession (init_lldb_globals);
 }
 
 bool
 ScriptInterpreterPython::Locker::DoFreeLock()
 {
-    ReleasePythonLock ();
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+    if (log)
+        log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
+    PyGILState_Release(m_GILState);
     return true;
 }
 
@@ -239,30 +197,11 @@ ScriptInterpreterPython::Locker::DoTearD
 
 ScriptInterpreterPython::Locker::~Locker()
 {
-    if (m_need_session)
+    if (m_teardown_session)
         DoTearDownSession();
-    if (m_release_lock)
-        DoFreeLock();
+    DoFreeLock();
 }
 
-class ForceDisableSyntheticChildren
-{
-public:
-    ForceDisableSyntheticChildren (Target* target) :
-        m_target(target)
-    {
-        m_old_value = target->GetSuppressSyntheticValue();
-        target->SetSuppressSyntheticValue(true);
-    }
-    ~ForceDisableSyntheticChildren ()
-    {
-        m_target->SetSuppressSyntheticValue(m_old_value);
-    }
-private:
-    Target* m_target;
-    bool m_old_value;
-};
-
 ScriptInterpreterPython::PythonInputReaderManager::PythonInputReaderManager (ScriptInterpreterPython *interpreter) :
 m_interpreter(interpreter),
 m_debugger_sp(),
@@ -308,37 +247,31 @@ m_error(false)
 
 ScriptInterpreterPython::PythonInputReaderManager::~PythonInputReaderManager()
 {
-    if (m_interpreter)
-    {
-        if (m_interpreter->m_embedded_thread_input_reader_sp)
-            m_interpreter->m_embedded_thread_input_reader_sp->SetIsDone (true);
-        m_interpreter->m_embedded_python_pty.CloseSlaveFileDescriptor();
-    }
-    
-    
-    if (m_reader_sp)
+    // Nothing to do if either m_interpreter or m_reader_sp is invalid.
+    if (!m_interpreter || !m_reader_sp)
+        return;
+
+    m_reader_sp->SetIsDone (true);
+    if (m_debugger_sp)
+        m_debugger_sp->PopInputReader(m_reader_sp);
+
+    // Only mess with m_interpreter's counterpart if, indeed, they are the same object.
+    if (m_reader_sp.get() == m_interpreter->m_embedded_thread_input_reader_sp.get())
     {
-        m_reader_sp->SetIsDone (true);
-        if (m_debugger_sp)
-            m_debugger_sp->PopInputReader(m_reader_sp);
-    }
-    
-    if (m_interpreter)
+        m_interpreter->m_embedded_thread_pty.CloseSlaveFileDescriptor();
         m_interpreter->m_embedded_thread_input_reader_sp.reset();
+    }
 }
 
 size_t
-ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback
-(
- void *baton, 
- InputReader &reader, 
- InputReaderAction notification,
- const char *bytes, 
- size_t bytes_len
- )
+ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback (void *baton,
+                                                                        InputReader &reader,
+                                                                        InputReaderAction notification,
+                                                                        const char *bytes, 
+                                                                        size_t bytes_len)
 {
     lldb::thread_t embedded_interpreter_thread;
-    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
     
     if (baton == NULL)
         return 0;
@@ -348,8 +281,6 @@ ScriptInterpreterPython::PythonInputRead
     if (script_interpreter->m_script_lang != eScriptLanguagePython)
         return 0;
     
-    StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
-    
     switch (notification)
     {
         case eInputReaderActivate:
@@ -360,26 +291,23 @@ ScriptInterpreterPython::PythonInputRead
                 input_fd = STDIN_FILENO;
             
             script_interpreter->SaveTerminalState(input_fd);
-            
-            {
-                ScriptInterpreterPython::Locker locker(script_interpreter,
-                                                       ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
-                                                       ScriptInterpreterPython::Locker::FreeAcquiredLock);
-            }
-            
+
             char error_str[1024];
-            if (script_interpreter->m_embedded_python_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, 
+            if (script_interpreter->m_embedded_thread_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, 
                                                                                     sizeof(error_str)))
             {
                 if (log)
                     log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in opening master pty (fd = %d).",
-                                 script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor());
+                                 script_interpreter->m_embedded_thread_pty.GetMasterFileDescriptor());
                 {
                     StreamString run_string;
                     char error_str[1024];
-                    const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
+                    const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
                     if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
                     {
+                        ScriptInterpreterPython::Locker locker(script_interpreter,
+                                                               ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
+                                                               ScriptInterpreterPython::Locker::FreeAcquiredLock);
                         run_string.Printf ("run_one_line (%s, 'save_stderr = sys.stderr')", script_interpreter->m_dictionary_name.c_str());
                         PyRun_SimpleString (run_string.GetData());
                         run_string.Clear ();
@@ -404,7 +332,7 @@ ScriptInterpreterPython::PythonInputRead
                 if (IS_VALID_LLDB_HOST_THREAD(embedded_interpreter_thread))
                 {
                     if (log)
-                        log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", embedded_interpreter_thread);
+                        log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", (void *)embedded_interpreter_thread);
                     Error detach_error;
                     Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
                 }
@@ -430,29 +358,33 @@ ScriptInterpreterPython::PythonInputRead
             break;
             
         case eInputReaderReactivate:
-        {
-            // Don't try and acquire the interpreter lock here because code like
-            // this:
-            //
-            // (lldb) script
-            // >>> v = lldb.frame.EvaluateExpression("collection->get_at_index(12)")
-            //
-            // This will cause the process to run. The interpreter lock is taken
-            // by the input reader for the "script" command. If we try and acquire
-            // the lock here, when the process runs it might deactivate this input
-            // reader (if STDIN is hooked up to the inferior process) and 
-            // reactivate it when the process stops which will deadlock.
-            //ScriptInterpreterPython::Locker locker(script_interpreter,
-            //                                       ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
-            //                                       ScriptInterpreterPython::Locker::FreeAcquiredLock);
-        }
+//        {
+//            ScriptInterpreterPython::Locker locker(script_interpreter,
+//                                                   ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+//                                                   ScriptInterpreterPython::Locker::FreeAcquiredLock);
+//        }
             break;
             
         case eInputReaderAsynchronousOutputWritten:
             break;
             
         case eInputReaderInterrupt:
-            reader.SetIsDone(true);
+            {
+                PyThreadState* state = _PyThreadState_Current;
+                if (!state)
+                    state = script_interpreter->m_command_thread_state;
+                if (state)
+                {
+                    long tid = state->thread_id;
+                    _PyThreadState_Current = state;
+                    int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+                    if (log)
+                        log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
+                                    tid,num_threads,state);
+                }
+                else if (log)
+                    log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
+            }
             break;
             
         case eInputReaderEndOfFile:
@@ -460,14 +392,14 @@ ScriptInterpreterPython::PythonInputRead
             break;
             
         case eInputReaderGotToken:
-            if (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor() != -1)
+            if (script_interpreter->m_embedded_thread_pty.GetMasterFileDescriptor() != -1)
             {
                 if (log)
                     log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, GotToken, bytes='%s', byte_len = %lu", bytes,
                                  bytes_len);
                 if (bytes && bytes_len)
-                    ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), bytes, bytes_len);
-                ::write (script_interpreter->m_embedded_python_pty.GetMasterFileDescriptor(), "\n", 1);
+                    ::write (script_interpreter->m_embedded_thread_pty.GetMasterFileDescriptor(), bytes, bytes_len);
+                ::write (script_interpreter->m_embedded_thread_pty.GetMasterFileDescriptor(), "\n", 1);
             }
             else
             {
@@ -477,33 +409,30 @@ ScriptInterpreterPython::PythonInputRead
                                  bytes_len);
                 reader.SetIsDone (true);
             }
-            
             break;
             
         case eInputReaderDone:
-        {
-            StreamString run_string;
-            char error_str[1024];
-            const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
-            if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
             {
-                run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str());
-                PyRun_SimpleString (run_string.GetData());
-                run_string.Clear();
+                StreamString run_string;
+                char error_str[1024];
+                const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
+                if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
+                {
+                    ScriptInterpreterPython::Locker locker(script_interpreter,
+                                                           ScriptInterpreterPython::Locker::AcquireLock,
+                                                           ScriptInterpreterPython::Locker::FreeAcquiredLock);
+                    run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin; sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
+                    PyRun_SimpleString (run_string.GetData());
+                    run_string.Clear();
+                }
+                // Restore terminal settings if they were validly saved
+                if (log)
+                    log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
                 
-                run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
-                PyRun_SimpleString (run_string.GetData());
-                run_string.Clear();
-            }
-        }
-            
-            // Restore terminal settings if they were validly saved
-            if (log)
-                log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
-            
-            script_interpreter->RestoreTerminalState ();
-            
-            script_interpreter->m_embedded_python_pty.CloseMasterFileDescriptor();
+                script_interpreter->RestoreTerminalState ();
+                
+                script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor();
+            }            
             break;
     }
     
@@ -512,8 +441,10 @@ ScriptInterpreterPython::PythonInputRead
 
 ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
     ScriptInterpreter (interpreter, eScriptLanguagePython),
+    m_embedded_thread_pty (),
     m_embedded_python_pty (),
     m_embedded_thread_input_reader_sp (),
+    m_embedded_python_input_reader_sp (),
     m_dbg_stdout (interpreter.GetDebugger().GetOutputFile().GetStream()),
     m_new_sysout (NULL),
     m_old_sysout (NULL),
@@ -522,7 +453,8 @@ ScriptInterpreterPython::ScriptInterpret
     m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
     m_terminal_state (),
     m_session_is_active (false),
-    m_valid_session (true)
+    m_valid_session (true),
+    m_command_thread_state (NULL)
 {
 
     static int g_initialized = false;
@@ -532,14 +464,14 @@ ScriptInterpreterPython::ScriptInterpret
         g_initialized = true;
         ScriptInterpreterPython::InitializePrivate ();
     }
-    
-    Locker locker(this,
-                  ScriptInterpreterPython::Locker::AcquireLock,
-                  ScriptInterpreterPython::Locker::FreeAcquiredLock);
 
     m_dictionary_name.append("_dict");
     StreamString run_string;
     run_string.Printf ("%s = dict()", m_dictionary_name.c_str());
+
+    Locker locker(this,
+                  ScriptInterpreterPython::Locker::AcquireLock,
+                  ScriptInterpreterPython::Locker::FreeAcquiredLock);
     PyRun_SimpleString (run_string.GetData());
 
     run_string.Clear();
@@ -560,8 +492,7 @@ ScriptInterpreterPython::ScriptInterpret
     // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
     // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
     run_string.Clear();
-    //run_string.Printf ("run_one_line (%s, 'from lldb.formatters import *; from lldb.formatters.objc import *; from lldb.formatters.cpp import *')", m_dictionary_name.c_str());
-    run_string.Printf ("run_one_line (%s, 'import lldb.runtime.objc, lldb.formatters, lldb.formatters.objc, lldb.formatters.cpp')", m_dictionary_name.c_str());
+    run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
     PyRun_SimpleString (run_string.GetData());
 
     int new_count = Debugger::TestDebuggerRefCount();
@@ -570,7 +501,7 @@ ScriptInterpreterPython::ScriptInterpret
         Debugger::Terminate();
 
     run_string.Clear();
-    run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %llu')", m_dictionary_name.c_str(),
+    run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
                        interpreter.GetDebugger().GetID());
     PyRun_SimpleString (run_string.GetData());
     
@@ -578,6 +509,11 @@ ScriptInterpreterPython::ScriptInterpret
     {
         m_new_sysout = PyFile_FromFile (m_dbg_stdout, (char *) "", (char *) "w", _check_and_flush);
     }
+    
+    // get the output file handle from the debugger (if any)
+    File& out_file = interpreter.GetDebugger().GetOutputFile();
+    if (out_file.IsValid())
+        ResetOutputFileHandle(out_file.GetStream());
 }
 
 ScriptInterpreterPython::~ScriptInterpreterPython ()
@@ -587,10 +523,19 @@ ScriptInterpreterPython::~ScriptInterpre
     if (m_embedded_thread_input_reader_sp.get() != NULL)
     {
         m_embedded_thread_input_reader_sp->SetIsDone (true);
-        m_embedded_python_pty.CloseSlaveFileDescriptor();
+        m_embedded_thread_pty.CloseSlaveFileDescriptor();
         const InputReaderSP reader_sp = m_embedded_thread_input_reader_sp;
+        debugger.PopInputReader (reader_sp);
         m_embedded_thread_input_reader_sp.reset();
+    }
+    
+    if (m_embedded_python_input_reader_sp.get() != NULL)
+    {
+        m_embedded_python_input_reader_sp->SetIsDone (true);
+        m_embedded_python_pty.CloseSlaveFileDescriptor();
+        const InputReaderSP reader_sp = m_embedded_python_input_reader_sp;
         debugger.PopInputReader (reader_sp);
+        m_embedded_python_input_reader_sp.reset();
     }
     
     if (m_new_sysout)
@@ -640,6 +585,10 @@ ScriptInterpreterPython::RestoreTerminal
 void
 ScriptInterpreterPython::LeaveSession ()
 {
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+    if (log)
+        log->PutCString("ScriptInterpreterPython::LeaveSession()");
+
     // checking that we have a valid thread state - since we use our own threading and locking
     // in some (rare) cases during cleanup Python may end up believing we have no thread state
     // and PyImport_AddModule will crash if that is the case - since that seems to only happen
@@ -664,33 +613,44 @@ ScriptInterpreterPython::LeaveSession ()
     m_session_is_active = false;
 }
 
-void
-ScriptInterpreterPython::EnterSession ()
+bool
+ScriptInterpreterPython::EnterSession (bool init_lldb_globals)
 {
     // If we have already entered the session, without having officially 'left' it, then there is no need to 
     // 'enter' it again.
-    
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
     if (m_session_is_active)
-        return;
+    {
+        if (log)
+            log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i) session is already active, returning without doing anything", init_lldb_globals);
+        return false;
+    }
+
+    if (log)
+        log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i)", init_lldb_globals);
+    
 
     m_session_is_active = true;
 
     StreamString run_string;
 
-    run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %llu", m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
-    run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%llu)", GetCommandInterpreter().GetDebugger().GetID());
-    run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
-    run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
-    run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
-    run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
-    // Make sure STDIN is closed since when we run this as an embedded 
-    // interpreter we don't want someone to call "line = sys.stdin.readline()"
-    // and lock up. We don't have multiple windows and when the interpreter is
-    // embedded we don't know we should be feeding input to the embedded 
-    // interpreter or to the python sys.stdin. We also don't want to let python
-    // play with the real stdin from this process, so we need to close it...
-    //run_string.PutCString ("; sys.stdin.close()");
-    run_string.PutCString ("')");
+    if (init_lldb_globals)
+    {
+        run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
+        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
+        run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
+        run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
+        run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
+        run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
+        run_string.PutCString ("')");
+    }
+    else
+    {
+        // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
+        run_string.Printf (    "run_one_line (%s, \"lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
+        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
+        run_string.PutCString ("\")");
+    }
 
     PyRun_SimpleString (run_string.GetData());
     run_string.Clear();
@@ -711,6 +671,8 @@ ScriptInterpreterPython::EnterSession ()
 
     if (PyErr_Occurred())
         PyErr_Clear ();
+    
+    return true;
 }
 
 static PyObject*
@@ -772,7 +734,7 @@ GenerateUniqueName (const char* base_nam
 }
 
 bool
-ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, bool enable_io)
+ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options)
 {
     if (!m_valid_session)
         return false;
@@ -783,7 +745,7 @@ ScriptInterpreterPython::ExecuteOneLine
     // method to pass the command string directly down to Python.
 
     Locker locker(this,
-                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                   ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
 
     bool success = false;
@@ -827,7 +789,7 @@ ScriptInterpreterPython::ExecuteOneLine
                         {
                             PyObject *pvalue = NULL;
                             { // scope for PythonInputReaderManager
-                                PythonInputReaderManager py_input(enable_io ? this : NULL);
+                                PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
                                 pvalue = PyObject_CallObject (pfunc, pargs);
                             }
                             Py_DECREF (pargs);
@@ -836,7 +798,7 @@ ScriptInterpreterPython::ExecuteOneLine
                                 Py_DECREF (pvalue);
                                 success = true;
                             }
-                            else if (PyErr_Occurred ())
+                            else if (options.GetMaskoutErrors() && PyErr_Occurred ())
                             {
                                 PyErr_Print();
                                 PyErr_Clear();
@@ -873,7 +835,7 @@ ScriptInterpreterPython::InputReaderCall
 )
 {
     lldb::thread_t embedded_interpreter_thread;
-    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
 
     if (baton == NULL)
         return 0;
@@ -883,13 +845,12 @@ ScriptInterpreterPython::InputReaderCall
     if (script_interpreter->m_script_lang != eScriptLanguagePython)
         return 0;
     
-    StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
-    bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-    
     switch (notification)
     {
     case eInputReaderActivate:
         {
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
             if (!batch_mode)
             {
                 out_stream->Printf ("Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.\n");
@@ -905,7 +866,7 @@ ScriptInterpreterPython::InputReaderCall
 
             {
                 ScriptInterpreterPython::Locker locker(script_interpreter,
-                                                       ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+                                                       ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
                                                        ScriptInterpreterPython::Locker::FreeAcquiredLock);
             }
 
@@ -922,7 +883,7 @@ ScriptInterpreterPython::InputReaderCall
                 if (IS_VALID_LLDB_HOST_THREAD(embedded_interpreter_thread))
                 {
                     if (log)
-                        log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", embedded_interpreter_thread);
+                        log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", (void *)embedded_interpreter_thread);
                     Error detach_error;
                     Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
                 }
@@ -949,20 +910,9 @@ ScriptInterpreterPython::InputReaderCall
 
     case eInputReaderReactivate:
         {
-            // Don't try and acquire the interpreter lock here because code like
-            // this:
-            //
-            // (lldb) script
-            // >>> v = lldb.frame.EvaluateExpression("collection->get_at_index(12)")
-            //
-            // This will cause the process to run. The interpreter lock is taken
-            // by the input reader for the "script" command. If we try and acquire
-            // the lock here, when the process runs it might deactivate this input
-            // reader (if STDIN is hooked up to the inferior process) and 
-            // reactivate it when the process stops which will deadlock.
-            //ScriptInterpreterPython::Locker locker(script_interpreter,
-            //                                       ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
-            //                                       ScriptInterpreterPython::Locker::FreeAcquiredLock);
+            ScriptInterpreterPython::Locker locker (script_interpreter,
+                                                    ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+                                                    ScriptInterpreterPython::Locker::FreeAcquiredLock);
         }
         break;
         
@@ -1004,7 +954,12 @@ ScriptInterpreterPython::InputReaderCall
         break;
         
     case eInputReaderDone:
-        script_interpreter->LeaveSession ();
+        {
+            Locker locker(script_interpreter,
+                          ScriptInterpreterPython::Locker::AcquireLock,
+                          ScriptInterpreterPython::Locker::FreeAcquiredLock);
+            script_interpreter->LeaveSession ();
+        }
 
         // Restore terminal settings if they were validly saved
         if (log)
@@ -1048,7 +1003,7 @@ ScriptInterpreterPython::ExecuteInterpre
         if (error.Success())
         {
             debugger.PushInputReader (reader_sp);
-            m_embedded_thread_input_reader_sp = reader_sp;
+            m_embedded_python_input_reader_sp = reader_sp;
         }
     }
 }
@@ -1057,11 +1012,11 @@ bool
 ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
                                                    ScriptInterpreter::ScriptReturnType return_type,
                                                    void *ret_value,
-                                                   bool enable_io)
+                                                   const ExecuteScriptOptions &options)
 {
 
     Locker locker(this,
-                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                   ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
 
     PyObject *py_return = NULL;
@@ -1094,7 +1049,7 @@ ScriptInterpreterPython::ExecuteOneLineW
     if (in_string != NULL)
     {
         { // scope for PythonInputReaderManager
-            PythonInputReaderManager py_input(enable_io ? this : NULL);
+            PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
             py_return = PyRun_String (in_string, Py_eval_input, globals, locals);
             if (py_return == NULL)
             { 
@@ -1198,8 +1153,6 @@ ScriptInterpreterPython::ExecuteOneLineW
                     success = PyArg_Parse (py_return, format, (char *) ret_value);
                     break;
                 }
-                default:
-                  {}
             }
             Py_DECREF (py_return);
             if (success)
@@ -1212,22 +1165,25 @@ ScriptInterpreterPython::ExecuteOneLineW
     py_error = PyErr_Occurred();
     if (py_error != NULL)
     {
-        if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
-            PyErr_Print ();
-        PyErr_Clear();
         ret_success = false;
+        if (options.GetMaskoutErrors())
+        {
+            if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
+                PyErr_Print ();
+            PyErr_Clear();
+        }
     }
 
     return ret_success;
 }
 
 bool
-ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, bool enable_io)
+ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options)
 {
     
     
     Locker locker(this,
-                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+                  ScriptInterpreterPython::Locker::AcquireLock      | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                   ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
 
     bool success = false;
@@ -1265,7 +1221,7 @@ ScriptInterpreterPython::ExecuteMultiple
             if (compiled_code)
             {
                 { // scope for PythonInputReaderManager
-                    PythonInputReaderManager py_input(enable_io ? this : NULL);
+                    PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
                     py_return = PyEval_EvalCode (compiled_code, globals, locals);
                 }
                 if (py_return != NULL)
@@ -1282,10 +1238,13 @@ ScriptInterpreterPython::ExecuteMultiple
     py_error = PyErr_Occurred ();
     if (py_error != NULL)
     {
-        if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
-            PyErr_Print ();
-        PyErr_Clear();
         success = false;
+        if (options.GetMaskoutErrors())
+        {
+            if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
+                PyErr_Print ();
+            PyErr_Clear();
+        }
     }
 
     return success;
@@ -1293,6 +1252,12 @@ ScriptInterpreterPython::ExecuteMultiple
 
 static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
 
+static const char *g_bkpt_command_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+                                                        "def function(frame,bp_loc,internal_dict):\n"
+                                                        "    \"\"\"frame: the SBFrame for the location at which you stopped\n"
+                                                        "       bp_loc: an SBBreakpointLocation for the breakpoint location information\n"
+                                                        "       internal_dict: an LLDB support object not to be used\"\"\"";
+
 size_t
 ScriptInterpreterPython::GenerateBreakpointOptionsCommandCallback
 (
@@ -1305,17 +1270,17 @@ ScriptInterpreterPython::GenerateBreakpo
 {
     static StringList commands_in_progress;
     
-    StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
-    bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-    
     switch (notification)
     {
     case eInputReaderActivate:
         {
+            
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
             commands_in_progress.Clear();
             if (!batch_mode)
             {
-                out_stream->Printf ("%s\n", g_reader_instructions);
+                out_stream->Printf ("%s\n", g_bkpt_command_reader_instructions);
                 if (reader.GetPrompt())
                     out_stream->Printf ("%s", reader.GetPrompt());
                 out_stream->Flush ();
@@ -1327,10 +1292,14 @@ ScriptInterpreterPython::GenerateBreakpo
         break;
 
     case eInputReaderReactivate:
-        if (reader.GetPrompt() && !batch_mode)
         {
-            out_stream->Printf ("%s", reader.GetPrompt());
-            out_stream->Flush ();
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+            if (reader.GetPrompt() && !batch_mode)
+            {
+                out_stream->Printf ("%s", reader.GetPrompt());
+                out_stream->Flush ();
+            }
         }
         break;
 
@@ -1339,6 +1308,8 @@ ScriptInterpreterPython::GenerateBreakpo
         
     case eInputReaderGotToken:
         {
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
             std::string temp_string (bytes, bytes_len);
             commands_in_progress.AppendString (temp_string.c_str());
             if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
@@ -1362,8 +1333,11 @@ ScriptInterpreterPython::GenerateBreakpo
 
     case eInputReaderDone:
         {
+            bool batch_mode = notification == eInputReaderDone ? 
+                reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode() :
+                true;
             BreakpointOptions *bp_options = (BreakpointOptions *)baton;
-            std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
+            std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
             data_ap->user_source.AppendList (commands_in_progress);
             if (data_ap.get())
             {
@@ -1378,6 +1352,7 @@ ScriptInterpreterPython::GenerateBreakpo
                     }
                     else if (!batch_mode)
                     {
+                        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
                         out_stream->Printf ("Warning: No command attached to breakpoint.\n");
                         out_stream->Flush();
                     }
@@ -1386,6 +1361,7 @@ ScriptInterpreterPython::GenerateBreakpo
                 {
 		            if (!batch_mode)
                     {
+                        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
                         out_stream->Printf ("Warning:  Unable to find script intepreter; no command attached to breakpoint.\n");
                         out_stream->Flush();
                     }
@@ -1411,13 +1387,13 @@ ScriptInterpreterPython::GenerateWatchpo
 {
     static StringList commands_in_progress;
     
-    StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
-    bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-    
     switch (notification)
     {
     case eInputReaderActivate:
         {
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+            
             commands_in_progress.Clear();
             if (!batch_mode)
             {
@@ -1433,10 +1409,14 @@ ScriptInterpreterPython::GenerateWatchpo
         break;
 
     case eInputReaderReactivate:
-        if (reader.GetPrompt() && !batch_mode)
         {
-            out_stream->Printf ("%s", reader.GetPrompt());
-            out_stream->Flush ();
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
+            if (reader.GetPrompt() && !batch_mode)
+            {
+                out_stream->Printf ("%s", reader.GetPrompt());
+                out_stream->Flush ();
+            }
         }
         break;
 
@@ -1445,6 +1425,8 @@ ScriptInterpreterPython::GenerateWatchpo
         
     case eInputReaderGotToken:
         {
+            StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
+            bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
             std::string temp_string (bytes, bytes_len);
             commands_in_progress.AppendString (temp_string.c_str());
             if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
@@ -1468,8 +1450,11 @@ ScriptInterpreterPython::GenerateWatchpo
 
     case eInputReaderDone:
         {
+            bool batch_mode = notification == eInputReaderDone ?
+                reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode() :
+                true;
             WatchpointOptions *wp_options = (WatchpointOptions *)baton;
-            std::auto_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
+            std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
             data_ap->user_source.AppendList (commands_in_progress);
             if (data_ap.get())
             {
@@ -1484,6 +1469,7 @@ ScriptInterpreterPython::GenerateWatchpo
                     }
                     else if (!batch_mode)
                     {
+                        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
                         out_stream->Printf ("Warning: No command attached to breakpoint.\n");
                         out_stream->Flush();
                     }
@@ -1492,6 +1478,7 @@ ScriptInterpreterPython::GenerateWatchpo
                 {
 		            if (!batch_mode)
                     {
+                        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
                         out_stream->Printf ("Warning:  Unable to find script intepreter; no command attached to breakpoint.\n");
                         out_stream->Flush();
                     }
@@ -1520,7 +1507,7 @@ ScriptInterpreterPython::CollectDataForB
                 bp_options,                 // baton
                 eInputReaderGranularityLine, // token size, for feeding data to callback function
                 "DONE",                     // end token
-                "> ",                       // prompt
+                "    ",                     // prompt
                 true);                      // echo input
     
         if (err.Success())
@@ -1576,7 +1563,7 @@ void
 ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                        const char *oneliner)
 {
-    std::auto_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
+    std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
 
     // It's necessary to set both user_source and script_source to the oneliner.
     // The former is used to generate callback description (as in breakpoint command list)
@@ -1599,7 +1586,7 @@ void
 ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                        const char *oneliner)
 {
-    std::auto_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
+    std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
 
     // It's necessary to set both user_source and script_source to the oneliner.
     // The former is used to generate callback description (as in watchpoint command list)
@@ -1623,7 +1610,7 @@ ScriptInterpreterPython::ExportFunctionD
     // Convert StringList to one long, newline delimited, const char *.
     std::string function_def_string(function_def.CopyList());
 
-    return ExecuteMultipleLines (function_def_string.c_str(), false);
+    return ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
 }
 
 bool
@@ -1647,10 +1634,11 @@ ScriptInterpreterPython::GenerateFunctio
     
     // Wrap everything up inside the function, increasing the indentation.
     
+    auto_generated_function.AppendString("     if True:");
     for (int i = 0; i < num_lines; ++i)
     {
         sstr.Clear ();
-        sstr.Printf ("     %s", input.GetStringAtIndex (i));
+        sstr.Printf ("       %s", input.GetStringAtIndex (i));
         auto_generated_function.AppendString (sstr.GetData());
     }
     auto_generated_function.AppendString ("     for key in new_keys:");  // Iterate over all the keys from session dict
@@ -1740,7 +1728,8 @@ ScriptInterpreterPython::GenerateTypeSyn
     auto_generated_class.AppendString (sstr.GetData());
         
     // Wrap everything up inside the class, increasing the indentation.
-    
+    // we don't need to play any fancy indentation tricks here because there is no
+    // surrounding code whose indentation we need to honor
     for (int i = 0; i < num_lines; ++i)
     {
         sstr.Clear ();
@@ -1762,10 +1751,300 @@ ScriptInterpreterPython::GenerateTypeSyn
 }
 
 lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
+ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
+{
+    if (class_name == NULL || class_name[0] == '\0')
+        return lldb::ScriptInterpreterObjectSP();
+    
+    if (!process_sp)
+        return lldb::ScriptInterpreterObjectSP();
+        
+    void* ret_val;
+    
+    {
+        Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+        ret_val = g_swig_create_os_plugin    (class_name,
+                                              m_dictionary_name.c_str(),
+                                              process_sp);
+    }
+    
+    return MakeScriptObject(ret_val);
+}
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+{
+    Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+    
+    static char callee_name[] = "get_register_info";
+    
+    if (!os_plugin_object_sp)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+    
+    if (implementor == NULL || implementor == Py_None)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == NULL || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    return MakeScriptObject(py_return);
+}
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
+{
+    Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+
+    static char callee_name[] = "get_thread_info";
+    
+    if (!os_plugin_object_sp)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+    
+    if (implementor == NULL || implementor == Py_None)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == NULL || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, NULL);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    return MakeScriptObject(py_return);
+}
+
+// GetPythonValueFormatString provides a system independent type safe way to
+// convert a variable's type into a python value format. Python value formats
+// are defined in terms of builtin C types and could change from system to
+// as the underlying typedef for uint* types, size_t, off_t and other values
+// change.
+
+template <typename T>
+const char *GetPythonValueFormatString(T t)
+{
+    assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
+    return NULL;
+}
+template <> const char *GetPythonValueFormatString (char *)             { return "s"; }
+template <> const char *GetPythonValueFormatString (char)               { return "b"; }
+template <> const char *GetPythonValueFormatString (unsigned char)      { return "B"; }
+template <> const char *GetPythonValueFormatString (short)              { return "h"; }
+template <> const char *GetPythonValueFormatString (unsigned short)     { return "H"; }
+template <> const char *GetPythonValueFormatString (int)                { return "i"; }
+template <> const char *GetPythonValueFormatString (unsigned int)       { return "I"; }
+template <> const char *GetPythonValueFormatString (long)               { return "l"; }
+template <> const char *GetPythonValueFormatString (unsigned long)      { return "k"; }
+template <> const char *GetPythonValueFormatString (long long)          { return "L"; }
+template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
+template <> const char *GetPythonValueFormatString (float t)            { return "f"; }
+template <> const char *GetPythonValueFormatString (double t)           { return "d"; }
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+                                                       lldb::tid_t tid)
+{
+    Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+
+    static char callee_name[] = "get_register_data";
+    static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
+    
+    if (!os_plugin_object_sp)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+    
+    if (implementor == NULL || implementor == Py_None)
+        return lldb::ScriptInterpreterObjectSP();
+
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == NULL || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);
+
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    return MakeScriptObject(py_return);
+}
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+                                                lldb::tid_t tid,
+                                                lldb::addr_t context)
+{
+    Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+    
+    static char callee_name[] = "create_thread";
+    std::string param_format;
+    param_format += GetPythonValueFormatString(tid);
+    param_format += GetPythonValueFormatString(context);
+    
+    if (!os_plugin_object_sp)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+    
+    if (implementor == NULL || implementor == Py_None)
+        return lldb::ScriptInterpreterObjectSP();
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == NULL || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return lldb::ScriptInterpreterObjectSP();
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, &param_format[0], tid, context);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    return MakeScriptObject(py_return);
+}
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
                                                           lldb::ValueObjectSP valobj)
 {
-    if (class_name.empty())
+    if (class_name == NULL || class_name[0] == '\0')
         return lldb::ScriptInterpreterObjectSP();
     
     if (!valobj.get())
@@ -1788,10 +2067,9 @@ ScriptInterpreterPython::CreateSynthetic
 
     {
         Locker py_lock(this);
-        ForceDisableSyntheticChildren no_synthetics(target);
-        ret_val = g_swig_synthetic_script    (class_name, 
-                                              python_interpreter->m_dictionary_name.c_str(),
-                                              valobj);
+        ret_val = g_swig_synthetic_script (class_name,
+                                           python_interpreter->m_dictionary_name.c_str(),
+                                           valobj);
     }
     
     return MakeScriptObject(ret_val);
@@ -2017,7 +2295,7 @@ ScriptInterpreterPython::RunEmbeddedPyth
 {
     ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
     
-    LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
     
     if (log)
         log->Printf ("%p ScriptInterpreterPython::RunEmbeddedPythonInterpreter () thread starting...", baton);
@@ -2025,14 +2303,18 @@ ScriptInterpreterPython::RunEmbeddedPyth
     char error_str[1024];
     const char *pty_slave_name = script_interpreter->m_embedded_python_pty.GetSlaveName (error_str, sizeof (error_str));
 
-    Locker locker(script_interpreter,
-                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
-                  ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
-
     if (pty_slave_name != NULL)
     {
         StreamString run_string;
-        
+
+        // Ensure we have the GIL before running any Python code.
+        // Since we're only running a few one-liners and then dropping to the interpreter (which will release the GIL when needed),
+        // we can just release the GIL after finishing our work.
+        // If finer-grained locking is desirable, we can lock and unlock the GIL only when calling a python function.
+        Locker locker(script_interpreter,
+                      ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
+                      ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
+
         run_string.Printf ("run_one_line (%s, 'save_stderr = sys.stderr')", script_interpreter->m_dictionary_name.c_str());
         PyRun_SimpleString (run_string.GetData());
         run_string.Clear ();
@@ -2052,40 +2334,29 @@ ScriptInterpreterPython::RunEmbeddedPyth
 
         // The following call drops into the embedded interpreter loop and stays there until the
         // user chooses to exit from the Python interpreter.
+        // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before
+        // a system call that can hang, and lock it when the syscall has returned.
 
-        // When in the embedded interpreter, the user can call arbitrary system and Python stuff, which may require
-        // the ability to run multi-threaded stuff, so we need to surround the call to the embedded interpreter with
-        // calls to Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS.
-
-        // We ALSO need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and 
-        // PyGILState_Release.  This is because this embedded interpreter is being run on a DIFFERENT THREAD than
-        // the thread on which the call to Py_Initialize (and PyEval_InitThreads) was called.  Those initializations 
-        // called PyGILState_Ensure on *that* thread, but it also needs to be called on *this* thread.  Otherwise,
-        // if the user calls Python code that does threading stuff, the interpreter state will be off, and things could
-        // hang (it's happened before).
+        // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and 
+        // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want
+        // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off,
+        // and things could hang (it's happened before).
 
-        Py_BEGIN_ALLOW_THREADS
-        PyGILState_STATE gstate = PyGILState_Ensure();
-        
         run_string.Printf ("run_python_interpreter (%s)", script_interpreter->m_dictionary_name.c_str());
         PyRun_SimpleString (run_string.GetData());
         run_string.Clear ();
-        
-        PyGILState_Release (gstate);
-        Py_END_ALLOW_THREADS
-        
+
         run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str());
         PyRun_SimpleString (run_string.GetData());
         run_string.Clear();
-        
+
         run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
         PyRun_SimpleString (run_string.GetData());
         run_string.Clear();
-        
     }
     
-    if (script_interpreter->m_embedded_thread_input_reader_sp)
-        script_interpreter->m_embedded_thread_input_reader_sp->SetIsDone (true);
+    if (script_interpreter->m_embedded_python_input_reader_sp)
+        script_interpreter->m_embedded_python_input_reader_sp->SetIsDone (true);
     
     script_interpreter->m_embedded_python_pty.CloseSlaveFileDescriptor();
 
@@ -2096,9 +2367,12 @@ ScriptInterpreterPython::RunEmbeddedPyth
 
     // Clean up the input reader and make the debugger pop it off the stack.
     Debugger &debugger = script_interpreter->GetCommandInterpreter().GetDebugger();
-    const InputReaderSP reader_sp = script_interpreter->m_embedded_thread_input_reader_sp;
-    script_interpreter->m_embedded_thread_input_reader_sp.reset();
-    debugger.PopInputReader (reader_sp);
+    const InputReaderSP reader_sp = script_interpreter->m_embedded_python_input_reader_sp;
+    if (reader_sp)
+    {
+        debugger.PopInputReader (reader_sp);
+        script_interpreter->m_embedded_python_input_reader_sp.reset();
+    }
     
     return NULL;
 }
@@ -2116,7 +2390,7 @@ ScriptInterpreterPython::PythonInputRead
     return NULL;
 }
 
-uint32_t
+size_t
 ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
 {
     if (!implementor_sp)
@@ -2134,8 +2408,7 @@ ScriptInterpreterPython::CalculateNumChi
     
     {
         Locker py_lock(this);
-        ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
-        ret_val = g_swig_calc_children       (implementor);
+        ret_val = g_swig_calc_children (implementor);
     }
     
     return ret_val;
@@ -2155,21 +2428,18 @@ ScriptInterpreterPython::GetChildAtIndex
     if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
         return lldb::ValueObjectSP();
     
-    void* child_ptr = NULL;
-    lldb::SBValue* value_sb = NULL;
     lldb::ValueObjectSP ret_val;
     
     {
         Locker py_lock(this);
-        ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
-        child_ptr = g_swig_get_child_index       (implementor,idx);
+        void* child_ptr = g_swig_get_child_index (implementor,idx);
         if (child_ptr != NULL && child_ptr != Py_None)
         {
-            value_sb = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
-            if (value_sb == NULL)
+            lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
+            if (sb_value_ptr == NULL)
                 Py_XDECREF(child_ptr);
             else
-                ret_val = value_sb->get_sp();
+                ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
         }
         else
         {
@@ -2198,8 +2468,7 @@ ScriptInterpreterPython::GetIndexOfChild
     
     {
         Locker py_lock(this);
-        ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
-        ret_val = g_swig_get_index_child       (implementor, child_name);
+        ret_val = g_swig_get_index_child (implementor, child_name);
     }
     
     return ret_val;
@@ -2223,16 +2492,97 @@ ScriptInterpreterPython::UpdateSynthProv
     
     {
         Locker py_lock(this);
-        ForceDisableSyntheticChildren no_synthetics(GetCommandInterpreter().GetDebugger().GetSelectedTarget().get());
-        ret_val = g_swig_update_provider       (implementor);
+        ret_val = g_swig_update_provider (implementor);
     }
     
     return ret_val;
 }
 
 bool
+ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
+{
+    bool ret_val = false;
+    
+    if (!implementor_sp)
+        return ret_val;
+    
+    void* implementor = implementor_sp->GetObject();
+    
+    if (!implementor)
+        return ret_val;
+    
+    if (!g_swig_mighthavechildren_provider)
+        return ret_val;
+    
+    {
+        Locker py_lock(this);
+        ret_val = g_swig_mighthavechildren_provider (implementor);
+    }
+    
+    return ret_val;
+}
+
+static std::string
+ReadPythonBacktrace (PyObject* py_backtrace)
+{
+    PyObject* traceback_module = NULL,
+    *stringIO_module = NULL,
+    *stringIO_builder = NULL,
+    *stringIO_buffer = NULL,
+    *printTB = NULL,
+    *printTB_args = NULL,
+    *printTB_result = NULL,
+    *stringIO_getvalue = NULL,
+    *printTB_string = NULL;
+
+    std::string retval("backtrace unavailable");
+    
+    if (py_backtrace && py_backtrace != Py_None)
+    {
+        traceback_module = PyImport_ImportModule("traceback");
+        stringIO_module = PyImport_ImportModule("StringIO");
+        
+        if (traceback_module && traceback_module != Py_None && stringIO_module && stringIO_module != Py_None)
+        {
+            stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
+            if (stringIO_builder && stringIO_builder != Py_None)
+            {
+                stringIO_buffer = PyObject_CallObject(stringIO_builder, NULL);
+                if (stringIO_buffer && stringIO_buffer != Py_None)
+                {
+                    printTB = PyObject_GetAttrString(traceback_module, "print_tb");
+                    if (printTB && printTB != Py_None)
+                    {
+                        printTB_args = Py_BuildValue("OOO",py_backtrace,Py_None,stringIO_buffer);
+                        printTB_result = PyObject_CallObject(printTB, printTB_args);
+                        stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
+                        if (stringIO_getvalue && stringIO_getvalue != Py_None)
+                        {
+                            printTB_string = PyObject_CallObject (stringIO_getvalue,NULL);
+                            if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
+                                retval.assign(PyString_AsString(printTB_string));
+                        }
+                    }
+                }
+            }
+        }
+    }
+    Py_XDECREF(traceback_module);
+    Py_XDECREF(stringIO_module);
+    Py_XDECREF(stringIO_builder);
+    Py_XDECREF(stringIO_buffer);
+    Py_XDECREF(printTB);
+    Py_XDECREF(printTB_args);
+    Py_XDECREF(printTB_result);
+    Py_XDECREF(stringIO_getvalue);
+    Py_XDECREF(printTB_string);
+    return retval;
+}
+
+bool
 ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
                                               bool can_reload,
+                                              bool init_session,
                                               lldb_private::Error& error)
 {
     if (!pathname || !pathname[0])
@@ -2250,40 +2600,62 @@ ScriptInterpreterPython::LoadScriptingMo
     lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
 
     {
-        Locker py_lock(this);
-        
         FileSpec target_file(pathname, true);
+        std::string basename(target_file.GetFilename().GetCString());
+        
+        StreamString command_stream;
+
+        // Before executing Pyton code, lock the GIL.
+        Locker py_lock (this,
+                        Locker::AcquireLock      | (init_session ? Locker::InitSession     : 0),
+                        Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
         
-        // TODO: would we want to reject any other value?
         if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
             target_file.GetFileType() == FileSpec::eFileTypeUnknown)
         {
-            error.SetErrorString("invalid pathname");
-            return false;
+            // if not a valid file of any sort, check if it might be a filename still
+            // dot can't be used but / and \ can, and if either is found, reject
+            if (strchr(pathname,'\\') || strchr(pathname,'/'))
+            {
+                error.SetErrorString("invalid pathname");
+                return false;
+            }
+            basename = pathname; // not a filename, probably a package of some sort, let it go through
         }
-        
-        const char* directory = target_file.GetDirectory().GetCString();
-        std::string basename(target_file.GetFilename().GetCString());
-        
-        // now make sure that Python has "directory" in the search path
-        StreamString command_stream;
-        command_stream.Printf("if not (sys.path.__contains__('%s')):\n    sys.path.append('%s');\n\n",
-                              directory,
-                              directory);
-        bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), false);
-        if (!syspath_retval)
+        else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
+                 target_file.GetFileType() == FileSpec::eFileTypeRegular ||
+                 target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
+        {
+            const char* directory = target_file.GetDirectory().GetCString();
+            
+            // now make sure that Python has "directory" in the search path
+            StreamString command_stream;
+            command_stream.Printf("if not (sys.path.__contains__('%s')):\n    sys.path.insert(1,'%s');\n\n",
+                                  directory,
+                                  directory);
+            bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
+            if (!syspath_retval)
+            {
+                error.SetErrorString("Python sys.path handling failed");
+                return false;
+            }
+            
+            // strip .py or .pyc extension
+            ConstString extension = target_file.GetFileNameExtension();
+            if (extension)
+            {
+                if (::strcmp(extension.GetCString(), "py") == 0)
+                    basename.resize(basename.length()-3);
+                else if(::strcmp(extension.GetCString(), "pyc") == 0)
+                    basename.resize(basename.length()-4);
+            }
+        }
+        else
         {
-            error.SetErrorString("Python sys.path handling failed");
+            error.SetErrorString("no known way to import this module specification");
             return false;
         }
         
-        // strip .py or .pyc extension
-        ConstString extension = target_file.GetFileNameExtension();
-        if (::strcmp(extension.GetCString(), "py") == 0)
-            basename.resize(basename.length()-3);
-        else if(::strcmp(extension.GetCString(), "pyc") == 0)
-            basename.resize(basename.length()-4);
-        
         // check if the module is already import-ed
         command_stream.Clear();
         command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
@@ -2291,7 +2663,9 @@ ScriptInterpreterPython::LoadScriptingMo
         // this call will fail if the module does not exist (because the parameter to it is not a string
         // but an actual Python module object, which is non-existant if the module was not imported before)
         bool was_imported = (ExecuteOneLineWithReturn(command_stream.GetData(),
-                                                      ScriptInterpreterPython::eScriptReturnTypeInt, &refcount, false) && refcount > 0);
+                                                      ScriptInterpreterPython::eScriptReturnTypeInt,
+                                                      &refcount,
+                                                      ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)) && refcount > 0);
         if (was_imported == true && can_reload == false)
         {
             error.SetErrorString("module already imported");
@@ -2300,18 +2674,57 @@ ScriptInterpreterPython::LoadScriptingMo
 
         // now actually do the import
         command_stream.Clear();
-        command_stream.Printf("import %s",basename.c_str());
-        bool import_retval = ExecuteOneLine(command_stream.GetData(), NULL, false);
-        if (!import_retval)
+        if (was_imported)
+            command_stream.Printf("reload(%s)",basename.c_str());
+        else
+            command_stream.Printf("import %s",basename.c_str());
+        bool import_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false).SetMaskoutErrors(false));
+        PyObject* py_error = PyErr_Occurred(); // per Python docs: "you do not need to Py_DECREF()" the return of this function
+        
+        if (py_error || !import_retval) // check for failure of the import
         {
-            error.SetErrorString("Python import statement failed");
+            if (py_error) // if we have a Python error..
+            {
+                PyObject *type = NULL,*value = NULL,*traceback = NULL;
+                PyErr_Fetch (&type,&value,&traceback);
+
+                if (PyErr_GivenExceptionMatches (py_error, PyExc_ImportError)) // and it is an ImportError
+                {
+                    if (value && value != Py_None)
+                        error.SetErrorString(PyString_AsString(PyObject_Str(value)));
+                    else
+                        error.SetErrorString("ImportError raised by imported module");
+                }
+                else // any other error
+                {
+                    // get the backtrace
+                    std::string bt = ReadPythonBacktrace(traceback);
+                    
+                    if (value && value != Py_None)
+                        error.SetErrorStringWithFormat("Python error raised while importing module: %s - traceback: %s", PyString_AsString(PyObject_Str(value)),bt.c_str());
+                    else
+                        error.SetErrorStringWithFormat("Python raised an error while importing module - traceback: %s",bt.c_str());
+                }
+                
+                Py_XDECREF(type);
+                Py_XDECREF(value);
+                Py_XDECREF(traceback);
+            }
+            else // we failed but have no error to explain why
+            {
+                error.SetErrorString("unknown error while importing module");
+            }
+            
+            // anyway, clear the error indicator and return false
+            PyErr_Clear();
             return false;
         }
         
+        // if we are here, everything worked
         // call __lldb_init_module(debugger,dict)
-        if (!g_swig_call_module_init (basename,
-                                        m_dictionary_name.c_str(),
-                                        debugger_sp))
+        if (!g_swig_call_module_init (basename.c_str(),
+                                      m_dictionary_name.c_str(),
+                                      debugger_sp))
         {
             error.SetErrorString("calling __lldb_init_module failed");
             return false;
@@ -2376,9 +2789,19 @@ ScriptInterpreterPython::RunScriptBasedC
     std::string err_msg;
 
     {
-        Locker py_lock(this);
+        Locker py_lock(this,
+                       Locker::AcquireLock | Locker::InitSession,
+                       Locker::FreeLock    | Locker::TearDownSession);
+
         SynchronicityHandler synch_handler(debugger_sp,
                                            synchronicity);
+
+        // we need to save the thread state when we first start the command
+        // because we might decide to interrupt it while some action is taking
+        // place outside of Python (e.g. printing to screen, waiting for the network, ...)
+        // in that case, _PyThreadState_Current will be NULL - and we would be unable
+        // to set the asynchronous exception - not a desirable situation
+        m_command_thread_state = _PyThreadState_Current;
         
         PythonInputReaderManager py_input(this);
         
@@ -2401,22 +2824,42 @@ ScriptInterpreterPython::RunScriptBasedC
 // in Python, a special attribute __doc__ contains the docstring
 // for an object (function, method, class, ...) if any is defined
 // Otherwise, the attribute's value is None
-std::string
-ScriptInterpreterPython::GetDocumentationForItem(const char* item)
+bool
+ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& dest)
 {
+	dest.clear();
+	if (!item || !*item)
+		return false;
     std::string command(item);
     command += ".__doc__";
     
     char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
     
     if (ExecuteOneLineWithReturn (command.c_str(),
-                                 ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
-                                 &result_ptr, false) && result_ptr)
+                                  ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
+                                  &result_ptr,
+                                  ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
     {
-        return std::string(result_ptr);
+        if (result_ptr)
+            dest.assign(result_ptr);
+        return true;
     }
     else
-        return std::string("");
+    {
+        StreamString str_stream;
+        str_stream.Printf("Function %s was not found. Containing module might be missing.",item);
+        dest.assign(str_stream.GetData());
+        return false;
+    }
+}
+
+std::unique_ptr<ScriptInterpreterLocker>
+ScriptInterpreterPython::AcquireInterpreterLock ()
+{
+    std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
+                                                              Locker::AcquireLock | Locker::InitSession,
+                                                              Locker::FreeLock | Locker::TearDownSession));
+    return py_lock;
 }
 
 void
@@ -2431,9 +2874,12 @@ ScriptInterpreterPython::InitializeInter
     g_swig_get_child_index = LLDBSwigPython_GetChildAtIndex;
     g_swig_get_index_child = LLDBSwigPython_GetIndexOfChildWithName;
     g_swig_cast_to_sbvalue = LLDBSWIGPython_CastPyObjectToSBValue;
+    g_swig_get_valobj_sp_from_sbvalue = LLDBSWIGPython_GetValueObjectSPFromSBValue;
     g_swig_update_provider = LLDBSwigPython_UpdateSynthProviderInstance;
+    g_swig_mighthavechildren_provider = LLDBSwigPython_MightHaveChildrenSynthProviderInstance;
     g_swig_call_command = LLDBSwigPythonCallCommand;
     g_swig_call_module_init = LLDBSwigPythonCallModuleInit;
+    g_swig_create_os_plugin = LLDBSWIGPythonCreateOSPlugin;
 }
 
 void
@@ -2446,7 +2892,18 @@ ScriptInterpreterPython::InitializePriva
     TerminalState stdin_tty_state;
     stdin_tty_state.Save(STDIN_FILENO, false);
 
-    PyEval_InitThreads ();
+    PyGILState_STATE gstate;
+    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+    bool threads_already_initialized = false;
+    if (PyEval_ThreadsInitialized ()) {
+        gstate = PyGILState_Ensure ();
+        if (log)
+            log->Printf("Ensured PyGILState. Previous state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
+        threads_already_initialized = true;
+    } else {
+        // InitThreads acquires the GIL if it hasn't been called before.
+        PyEval_InitThreads ();
+    }
     Py_InitializeEx (0);
 
     // Initialize SWIG after setting up python
@@ -2489,6 +2946,15 @@ ScriptInterpreterPython::InitializePriva
 
     PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line; from termios import *");
 
+    if (threads_already_initialized) {
+        if (log)
+            log->Printf("Releasing PyGILState. Returning to state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
+        PyGILState_Release (gstate);
+    } else {
+        // We initialized the threads in this function, just unlock the GIL.
+        PyEval_SaveThread();
+    }
+
     stdin_tty_state.Restore();
 }
 

Modified: lldb/branches/lldb-platform-work/source/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Makefile?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Makefile (original)
+++ lldb/branches/lldb-platform-work/source/Makefile Thu Jun  6 19:06:43 2013
@@ -8,14 +8,30 @@
 ##===----------------------------------------------------------------------===##
 
 LLDB_LEVEL := ..
-DIRS := API Breakpoint Commands Core Expression Host Interpreter Plugins Symbol Target Utility
+DIRS := API Breakpoint Commands Core DataFormatters Expression Host Interpreter Plugins Symbol Target Utility
 LIBRARYNAME := lldbInitAndLog
 BUILD_ARCHIVE = 1
 
+# Although LLVM makefiles provide $(HOST_OS), we cannot use that here because it is defined by including the $(LLDB_LEVEL)/Makefile
+# below. Instead, we use uname -s to detect the HOST_OS and generate LLDB_vers.c only on Mac. On Linux, the version number is
+# calculated in the same way as Clang's version.
+ifeq (Darwin,$(shell uname -s)) 
 BUILT_SOURCES = LLDB_vers.c
+endif
+
 SOURCES := lldb-log.cpp lldb.cpp
 
 include $(LLDB_LEVEL)/Makefile
 
+ifeq ($(HOST_OS),Darwin)
 LLDB_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj
 	"$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" > LLDB_vers.c
+else
+LLDB_REVISION := $(strip \
+        $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(LLVM_SRC_ROOT)/tools/lldb))
+
+LLDB_REPOSITORY := $(strip \
+        $(shell $(LLVM_SRC_ROOT)/utils/GetRepositoryPath $(LLVM_SRC_ROOT)/tools/lldb))
+
+CPP.Defines += -DLLDB_REVISION='"$(LLDB_REVISION)"' -DLLDB_REPOSITORY='"$(LLDB_REPOSITORY)"'
+endif

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Thu Jun  6 19:06:43 2013
@@ -35,12 +35,7 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static const char *pluginName = "ABIMacOSX_arm";
-static const char *pluginDesc = "Mac OS X ABI for arm targets";
-static const char *pluginShort = "abi.macosx-arm";
-
-
-static RegisterInfo g_register_infos[] = 
+static RegisterInfo g_register_infos[] =
 {
     //  NAME       ALT       SZ OFF ENCODING         FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE            VALUE REGS    INVALIDATE REGS
     //  ========== =======   == === =============    ============    ======================= =================== =========================== ======================= ====================== ==========    ===============
@@ -332,10 +327,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread
     if (!reg_ctx)
         return false;
         
-    addr_t sp = reg_ctx->GetSP(0);
-    
-    if (!sp)
-        return false;
+    addr_t sp = 0;
 
     for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
     {
@@ -405,6 +397,14 @@ ABIMacOSX_arm::GetArgumentValues (Thread
                 }
                 else
                 {
+                    if (sp == 0)
+                    {
+                        // Read the stack pointer if it already hasn't been read
+                        sp = reg_ctx->GetSP(0);
+                        if (sp == 0)
+                            return false;
+                    }
+
                     // Arguments 5 on up are on the stack
                     const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
                     Error error;
@@ -421,7 +421,7 @@ ABIMacOSX_arm::GetArgumentValues (Thread
 
 ValueObjectSP
 ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
-                               lldb_private::ClangASTType &ast_type) const
+                                         lldb_private::ClangASTType &ast_type) const
 {
     Value value;
     ValueObjectSP return_valobj_sp;
@@ -507,6 +507,86 @@ ABIMacOSX_arm::GetReturnValueObjectImpl
     return return_valobj_sp;
 }
 
+Error
+ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+    
+    clang_type_t value_type = new_value_sp->GetClangType();
+    if (!value_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+    
+    clang::ASTContext *ast_context = new_value_sp->GetClangAST();
+    if (!ast_context)
+    {
+        error.SetErrorString ("Null clang AST for return value.");
+        return error;
+    }
+    Thread *thread = frame_sp->GetThread().get();
+    
+    bool is_signed;
+    uint32_t count;
+    bool is_complex;
+    
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+    bool set_it_simple = false;
+    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    {
+        DataExtractor data;
+        size_t num_bytes = new_value_sp->GetData(data);
+        lldb::offset_t offset = 0;
+        if (num_bytes <= 8)
+        {
+            const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
+            if (num_bytes <= 4)
+            {
+                uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+        
+                if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
+                    set_it_simple = true;
+            }
+            else
+            {
+                uint32_t raw_value = data.GetMaxU32(&offset, 4);
+        
+                if (reg_ctx->WriteRegisterFromUnsigned (r0_info, raw_value))
+                {
+                    const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
+                    uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+                
+                    if (reg_ctx->WriteRegisterFromUnsigned (r1_info, raw_value))
+                        set_it_simple = true;
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+        }
+    }
+    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    {
+        if (is_complex)
+            error.SetErrorString ("We don't support returning complex values at present");
+        else
+            error.SetErrorString ("We don't support returning float values at present");
+    }
+    
+    if (!set_it_simple)
+        error.SetErrorString ("We only support setting simple integer return types at present.");
+    
+    return error;
+}
+
 bool
 ABIMacOSX_arm::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
 {
@@ -548,6 +628,8 @@ ABIMacOSX_arm::CreateFunctionEntryUnwind
     // All other registers are the same.
     
     unwind_plan.SetSourceName ("arm at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+
     return true;
 }
 
@@ -571,9 +653,30 @@ ABIMacOSX_arm::CreateDefaultUnwindPlan (
     
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("arm-apple-ios default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+
     return true;
 }
 
+// ARMv7 on iOS general purpose reg rules:
+//    r0-r3 not preserved  (used for argument passing)
+//    r4-r6 preserved
+//    r7    preserved (frame pointer)
+//    r8    preserved
+//    r9    not preserved (usable as volatile scratch register with iOS 3.x and later)
+//    r10-r11 preserved
+//    r12   not presrved
+//    r13   preserved (stack pointer)
+//    r14   not preserved (link register)
+//    r15   preserved (pc)
+//    cpsr  not preserved (different rules for different bits)
+
+// ARMv7 on iOS floating point rules:
+//    d0-d7   not preserved   (aka s0-s15, q0-q3)
+//    d8-d15  preserved       (aka s16-s31, q4-q7)
+//    d16-d31 not preserved   (aka q8-q15)
+
 bool
 ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
 {
@@ -611,28 +714,28 @@ ABIMacOSX_arm::RegisterIsVolatile (const
             switch (name[1])
             {
                 case '0': 
-                    return name[2] == '\0'; // d0
+                    return name[2] == '\0'; // d0 is volatile
 
                 case '1':
                     switch (name[2])
                     {
                     case '\0':
-                        return true; // d1;
+                        return true; // d1 is volatile
                     case '6':
                     case '7':
                     case '8':
                     case '9':
-                        return name[3] == '\0'; // d16 - d19
+                        return name[3] == '\0'; // d16 - d19 are volatile
                     default:
                         break;
                     }
                     break;
-                    
+
                 case '2':
                     switch (name[2])
                     {
                     case '\0':
-                        return true; // d2;
+                        return true; // d2 is volatile
                     case '0':
                     case '1':
                     case '2':
@@ -643,7 +746,7 @@ ABIMacOSX_arm::RegisterIsVolatile (const
                     case '7':
                     case '8':
                     case '9':
-                        return name[3] == '\0'; // d20 - d29
+                        return name[3] == '\0'; // d20 - d29 are volatile
                     default:
                         break;
                     }
@@ -653,10 +756,10 @@ ABIMacOSX_arm::RegisterIsVolatile (const
                     switch (name[2])
                     {
                     case '\0':
-                        return true; // d3;
+                        return true; // d3 is volatile
                     case '0':
                     case '1':
-                        return name[3] == '\0'; // d30 - d31
+                        return name[3] == '\0'; // d30 - d31 are volatile
                     default:
                         break;
                     }
@@ -664,7 +767,61 @@ ABIMacOSX_arm::RegisterIsVolatile (const
                 case '5':
                 case '6':
                 case '7':
-                    return name[2] == '\0'; // d4 - d7
+                    return name[2] == '\0'; // d4 - d7 are volatile
+
+                default:
+                    break;
+            }
+        }
+        else if (name[0] == 's')
+        {
+            switch (name[1])
+            {
+                case '0': 
+                    return name[2] == '\0'; // s0 is volatile
+
+                case '1':
+                    switch (name[2])
+                    {
+                    case '\0':
+                        return true; // s1 is volatile
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                        return name[3] == '\0'; // s10 - s15 are volatile
+                    default:
+                        break;
+                    }
+                    break;
+
+                case '2':
+                    switch (name[2])
+                    {
+                    case '\0':
+                        return true; // s2 is volatile
+                    default:
+                        break;
+                    }
+                    break;
+
+                case '3':
+                    switch (name[2])
+                    {
+                    case '\0':
+                        return true; // s3 is volatile
+                    default:
+                        break;
+                    }
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                    return name[2] == '\0'; // s4 - s9 are volatile
 
                 default:
                     break;
@@ -679,8 +836,8 @@ ABIMacOSX_arm::RegisterIsVolatile (const
 void
 ABIMacOSX_arm::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "Mac OS X ABI for arm targets",
                                    CreateInstance);    
 }
 
@@ -690,19 +847,20 @@ ABIMacOSX_arm::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+ABIMacOSX_arm::GetPluginNameStatic()
+{
+    static ConstString g_name("macosx-arm");
+    return g_name;
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 ABIMacOSX_arm::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-ABIMacOSX_arm::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h Thu Jun  6 19:06:43 2013
@@ -41,6 +41,9 @@ public:
     GetArgumentValues (lldb_private::Thread &thread,
                        lldb_private::ValueList &values) const;
     
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
 protected:
     virtual lldb::ValueObjectSP
     GetReturnValueObjectImpl (lldb_private::Thread &thread,
@@ -90,6 +93,12 @@ public:
         return pc & ~(lldb::addr_t)1;
     }
 
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return false;
+    }
+
     virtual const lldb_private::RegisterInfo *
     GetRegisterInfoArray (uint32_t &count);
 
@@ -105,15 +114,15 @@ public:
     static lldb::ABISP
     CreateInstance (const lldb_private::ArchSpec &arch);
     
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
     
-    virtual const char *
-    GetShortPluginName();
-    
     virtual uint32_t
     GetPluginVersion();
     

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Thu Jun  6 19:06:43 2013
@@ -30,10 +30,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static const char *pluginName = "ABIMacOSX_i386";
-static const char *pluginDesc = "Mac OS X ABI for i386 targets";
-static const char *pluginShort = "abi.macosx-i386";
-
 enum
 {
     gcc_eax = 0,
@@ -453,7 +449,6 @@ ABIMacOSX_i386::PrepareNormalCall (Threa
                 switch (scalar.GetType())
                 {
                 case Scalar::e_void:
-                default:
                     return false;
                 case Scalar::e_sint: 
                 case Scalar::e_uint:
@@ -687,6 +682,86 @@ ABIMacOSX_i386::GetArgumentValues (Threa
     return true;
 }
 
+Error
+ABIMacOSX_i386::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+    
+    clang_type_t value_type = new_value_sp->GetClangType();
+    if (!value_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+    
+    clang::ASTContext *ast_context = new_value_sp->GetClangAST();
+    if (!ast_context)
+    {
+        error.SetErrorString ("Null clang AST for return value.");
+        return error;
+    }
+    Thread *thread = frame_sp->GetThread().get();
+    
+    bool is_signed;
+    uint32_t count;
+    bool is_complex;
+    
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+    bool set_it_simple = false;
+    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    {
+        DataExtractor data;
+        size_t num_bytes = new_value_sp->GetData(data);
+        lldb::offset_t offset = 0;
+        if (num_bytes <= 8)
+        {
+            const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
+            if (num_bytes <= 4)
+            {
+                uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
+        
+                if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
+                    set_it_simple = true;
+            }
+            else
+            {
+                uint32_t raw_value = data.GetMaxU32(&offset, 4);
+        
+                if (reg_ctx->WriteRegisterFromUnsigned (eax_info, raw_value))
+                {
+                    const RegisterInfo *edx_info = reg_ctx->GetRegisterInfoByName("edx", 0);
+                    uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
+                
+                    if (reg_ctx->WriteRegisterFromUnsigned (edx_info, raw_value))
+                        set_it_simple = true;
+                }
+            }
+        }
+        else
+        {
+            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+        }
+    }
+    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    {
+        if (is_complex)
+            error.SetErrorString ("We don't support returning complex values at present");
+        else
+            error.SetErrorString ("We don't support returning float values at present");
+    }
+    
+    if (!set_it_simple)
+        error.SetErrorString ("We only support setting simple integer return types at present.");
+    
+    return error;
+}
+
 ValueObjectSP
 ABIMacOSX_i386::GetReturnValueObjectImpl (Thread &thread,
                                 ClangASTType &ast_type) const
@@ -814,6 +889,7 @@ ABIMacOSX_i386::CreateFunctionEntryUnwin
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("i386 at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
     return true;
 }
 
@@ -839,21 +915,25 @@ ABIMacOSX_i386::CreateDefaultUnwindPlan
 
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("i386 default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
     return true;
 }
 
 bool
 ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
 {
-    return RegisterIsCalleeSaved (reg_info);
+    return !RegisterIsCalleeSaved (reg_info);
 }
 
+// v. http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+
 bool
 ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
 {
     if (reg_info)
     {
-        // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+        // Saved registers are ebx, ebp, esi, edi, esp, eip
         const char *name = reg_info->name;
         if (name[0] == 'e')
         {
@@ -861,22 +941,28 @@ ABIMacOSX_i386::RegisterIsCalleeSaved (c
             {
             case 'b': 
                 if (name[2] == 'x' || name[2] == 'p')
-                    return name[0] == '\0';
+                    return name[3] == '\0';
                 break;
             case 'd':
                 if (name[2] == 'i')
-                    return name[0] == '\0';
+                    return name[3] == '\0';
                 break;
             case 'i': 
                 if (name[2] == 'p')
-                    return name[0] == '\0';
+                    return name[3] == '\0';
                 break;
             case 's':
                 if (name[2] == 'i' || name[2] == 'p')
-                    return name[0] == '\0';
+                    return name[3] == '\0';
                 break;
             }
         }
+        if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
+            return true;
+        if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
+            return true;
+        if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
+            return true;
     }
     return false;
 }
@@ -884,8 +970,8 @@ ABIMacOSX_i386::RegisterIsCalleeSaved (c
 void
 ABIMacOSX_i386::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "Mac OS X ABI for i386 targets",
                                    CreateInstance);    
 }
 
@@ -895,19 +981,21 @@ ABIMacOSX_i386::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+ABIMacOSX_i386::GetPluginNameStatic ()
+{
+    static ConstString g_short_name("abi.macosx-i386");
+    return g_short_name;
+    
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 ABIMacOSX_i386::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-ABIMacOSX_i386::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h Thu Jun  6 19:06:43 2013
@@ -51,6 +51,9 @@ public:
     GetArgumentValues (lldb_private::Thread &thread,
                        lldb_private::ValueList &values) const;
     
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
 protected:
     virtual lldb::ValueObjectSP
     GetReturnValueObjectImpl (lldb_private::Thread &thread,
@@ -90,7 +93,13 @@ public:
         // Just make sure the address is a valid 32 bit address. 
         return pc <= UINT32_MAX;
     }
-    
+
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return true;
+    }
+
     virtual const lldb_private::RegisterInfo *
     GetRegisterInfoArray (uint32_t &count);
 
@@ -109,12 +118,12 @@ public:
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    static lldb_private::ConstString
+    GetPluginNameStatic ();
+
+    virtual lldb_private::ConstString
     GetPluginName();
     
-    virtual const char *
-    GetShortPluginName();
-    
     virtual uint32_t
     GetPluginVersion();
     

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Thu Jun  6 19:06:43 2013
@@ -33,11 +33,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static const char *pluginName = "ABISysV_x86_64";
-static const char *pluginDesc = "System V ABI for x86_64 targets";
-static const char *pluginShort = "abi.sysv-x86_64";
-
-
 enum gcc_dwarf_regnums
 {
     gcc_dwarf_rax = 0,
@@ -81,22 +76,22 @@ enum gcc_dwarf_regnums
     gcc_dwarf_stmm5,
     gcc_dwarf_stmm6,
     gcc_dwarf_stmm7,
-    gcc_dwarf_ymm0 = gcc_dwarf_xmm0,
-    gcc_dwarf_ymm1 = gcc_dwarf_xmm1,
-    gcc_dwarf_ymm2 = gcc_dwarf_xmm2,
-    gcc_dwarf_ymm3 = gcc_dwarf_xmm3,
-    gcc_dwarf_ymm4 = gcc_dwarf_xmm4,
-    gcc_dwarf_ymm5 = gcc_dwarf_xmm5,
-    gcc_dwarf_ymm6 = gcc_dwarf_xmm6,
-    gcc_dwarf_ymm7 = gcc_dwarf_xmm7,
-    gcc_dwarf_ymm8 = gcc_dwarf_xmm8,
-    gcc_dwarf_ymm9 = gcc_dwarf_xmm9,
-    gcc_dwarf_ymm10 = gcc_dwarf_xmm10,
-    gcc_dwarf_ymm11 = gcc_dwarf_xmm11,
-    gcc_dwarf_ymm12 = gcc_dwarf_xmm12,
-    gcc_dwarf_ymm13 = gcc_dwarf_xmm13,
-    gcc_dwarf_ymm14 = gcc_dwarf_xmm14,
-    gcc_dwarf_ymm15 = gcc_dwarf_xmm15
+    gcc_dwarf_ymm0,
+    gcc_dwarf_ymm1,
+    gcc_dwarf_ymm2,
+    gcc_dwarf_ymm3,
+    gcc_dwarf_ymm4,
+    gcc_dwarf_ymm5,
+    gcc_dwarf_ymm6,
+    gcc_dwarf_ymm7,
+    gcc_dwarf_ymm8,
+    gcc_dwarf_ymm9,
+    gcc_dwarf_ymm10,
+    gcc_dwarf_ymm11,
+    gcc_dwarf_ymm12,
+    gcc_dwarf_ymm13,
+    gcc_dwarf_ymm14,
+    gcc_dwarf_ymm15
 };
 
 enum gdb_regnums
@@ -158,22 +153,22 @@ enum gdb_regnums
     gdb_xmm14   =  54,
     gdb_xmm15   =  55,
     gdb_mxcsr   =  56,
-    gdb_ymm0    =  gdb_xmm0,
-    gdb_ymm1    =  gdb_xmm1,
-    gdb_ymm2    =  gdb_xmm2,
-    gdb_ymm3    =  gdb_xmm3,
-    gdb_ymm4    =  gdb_xmm4,
-    gdb_ymm5    =  gdb_xmm5,
-    gdb_ymm6    =  gdb_xmm6,
-    gdb_ymm7    =  gdb_xmm7,
-    gdb_ymm8    =  gdb_xmm8,
-    gdb_ymm9    =  gdb_xmm9,
-    gdb_ymm10   =  gdb_xmm10,
-    gdb_ymm11   =  gdb_xmm11,
-    gdb_ymm12   =  gdb_xmm12,
-    gdb_ymm13   =  gdb_xmm13,
-    gdb_ymm14   =  gdb_xmm14,
-    gdb_ymm15   =  gdb_xmm15
+    gdb_ymm0    =  57,
+    gdb_ymm1    =  58,
+    gdb_ymm2    =  59,
+    gdb_ymm3    =  60,
+    gdb_ymm4    =  61,
+    gdb_ymm5    =  62,
+    gdb_ymm6    =  63,
+    gdb_ymm7    =  64,
+    gdb_ymm8    =  65,
+    gdb_ymm9    =  66,
+    gdb_ymm10   =  67,
+    gdb_ymm11   =  68,
+    gdb_ymm12   =  69,
+    gdb_ymm13   =  70,
+    gdb_ymm14   =  71,
+    gdb_ymm15   =  72
 };
 
 
@@ -315,10 +310,10 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
                                     addr_t *arg5_ptr,
                                     addr_t *arg6_ptr) const
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
     if (log)
-        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%llx\n  func_addr = 0x%llx\n  return_addr = 0x%llx\n  arg1_ptr = %p (0x%llx)\n  arg2_ptr = %p (0x%llx)\n  arg3_ptr = %p (0x%llx)\n)",
+        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%" PRIx64 "\n  func_addr = 0x%" PRIx64 "\n  return_addr = 0x%" PRIx64 "\n  arg1_ptr = %p (0x%" PRIx64 ")\n  arg2_ptr = %p (0x%" PRIx64 ")\n  arg3_ptr = %p (0x%" PRIx64 ")\n)",
                     (void*)&thread,
                     (uint64_t)sp,
                     (uint64_t)func_addr,
@@ -336,7 +331,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
     {
         reg_info = reg_ctx->GetRegisterInfoByName("rdi", 0);
         if (log)
-            log->Printf("About to write arg1 (0x%llx) into %s", (uint64_t)*arg1_ptr, reg_info->name);
+            log->Printf("About to write arg1 (0x%" PRIx64 ") into %s", (uint64_t)*arg1_ptr, reg_info->name);
 
         if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg1_ptr))
             return false;
@@ -345,7 +340,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
         {
             reg_info = reg_ctx->GetRegisterInfoByName("rsi", 0);
             if (log)
-                log->Printf("About to write arg2 (0x%llx) into %s", (uint64_t)*arg2_ptr, reg_info->name);
+                log->Printf("About to write arg2 (0x%" PRIx64 ") into %s", (uint64_t)*arg2_ptr, reg_info->name);
             if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg2_ptr))
                 return false;
 
@@ -353,7 +348,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
             {
                 reg_info = reg_ctx->GetRegisterInfoByName("rdx", 0);
                 if (log)
-                    log->Printf("About to write arg3 (0x%llx) into %s", (uint64_t)*arg3_ptr, reg_info->name);
+                    log->Printf("About to write arg3 (0x%" PRIx64 ") into %s", (uint64_t)*arg3_ptr, reg_info->name);
                 if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg3_ptr))
                     return false;
 
@@ -361,7 +356,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
                 {
                     reg_info = reg_ctx->GetRegisterInfoByName("rcx", 0);
                     if (log)
-                        log->Printf("About to write arg4 (0x%llx) into %s", (uint64_t)*arg4_ptr, reg_info->name);
+                        log->Printf("About to write arg4 (0x%" PRIx64 ") into %s", (uint64_t)*arg4_ptr, reg_info->name);
                     if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg4_ptr))
                         return false;
 
@@ -369,7 +364,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
                     {
                         reg_info = reg_ctx->GetRegisterInfoByName("r8", 0);
                         if (log)
-                            log->Printf("About to write arg5 (0x%llx) into %s", (uint64_t)*arg5_ptr, reg_info->name);
+                            log->Printf("About to write arg5 (0x%" PRIx64 ") into %s", (uint64_t)*arg5_ptr, reg_info->name);
                         if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg5_ptr))
                             return false;
 
@@ -377,7 +372,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
                         {
                             reg_info = reg_ctx->GetRegisterInfoByName("r9", 0);
                             if (log)
-                                log->Printf("About to write arg6 (0x%llx) into %s", (uint64_t)*arg6_ptr, reg_info->name);
+                                log->Printf("About to write arg6 (0x%" PRIx64 ") into %s", (uint64_t)*arg6_ptr, reg_info->name);
                             if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg6_ptr))
                                 return false;
                         }
@@ -391,7 +386,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
     // First, align the SP
 
     if (log)
-        log->Printf("16-byte aligning SP: 0x%llx to 0x%llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+        log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
 
     sp &= ~(0xfull); // 16-byte alignment
 
@@ -402,7 +397,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
     reg_value.SetUInt64 (return_addr);
 
     if (log)
-        log->Printf("Pushing the return address onto the stack: new SP 0x%llx, return address 0x%llx", (uint64_t)sp, (uint64_t)return_addr);
+        log->Printf("Pushing the return address onto the stack: new SP 0x%" PRIx64 ", return address 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
 
     const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfoByName("rip");
     Error error (reg_ctx->WriteRegisterValueToMemory(pc_reg_info, sp, pc_reg_info->byte_size, reg_value));
@@ -412,7 +407,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
     // %rsp is set to the actual stack value.
 
     if (log)
-        log->Printf("Writing SP (0x%llx) down", (uint64_t)sp);
+        log->Printf("Writing SP (0x%" PRIx64 ") down", (uint64_t)sp);
     
     if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoByName("rsp"), sp))
         return false;
@@ -420,7 +415,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
     // %rip is set to the address of the called function.
     
     if (log)
-        log->Printf("Writing new IP (0x%llx) down", (uint64_t)func_addr);
+        log->Printf("Writing new IP (0x%" PRIx64 ") down", (uint64_t)func_addr);
 
     if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
         return false;
@@ -470,7 +465,7 @@ ABISysV_x86_64::GetArgumentValues (Threa
     // For now, assume that the types in the AST values come from the Target's 
     // scratch AST.    
     
-    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+    clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
     
     // Extract the register context so we can read arguments from registers
     
@@ -522,7 +517,7 @@ ABISysV_x86_64::GetArgumentValues (Threa
                 
                 if (ClangASTContext::IsIntegerType (value_type, is_signed))
                 {
-                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
                     
                     ReadIntegerArgument(value->GetScalar(),
                                         bit_width, 
@@ -550,142 +545,276 @@ ABISysV_x86_64::GetArgumentValues (Threa
     return true;
 }
 
+Error
+ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value_sp)
+{
+    Error error;
+    if (!new_value_sp)
+    {
+        error.SetErrorString("Empty value object for return value.");
+        return error;
+    }
+    
+    clang_type_t value_type = new_value_sp->GetClangType();
+    if (!value_type)
+    {
+        error.SetErrorString ("Null clang type for return value.");
+        return error;
+    }
+    
+    clang::ASTContext *ast = new_value_sp->GetClangAST();
+    if (!ast)
+    {
+        error.SetErrorString ("Null clang AST for return value.");
+        return error;
+    }
+    Thread *thread = frame_sp->GetThread().get();
+    
+    bool is_signed;
+    uint32_t count;
+    bool is_complex;
+    
+    RegisterContext *reg_ctx = thread->GetRegisterContext().get();
+
+    bool set_it_simple = false;
+    if (ClangASTContext::IsIntegerType (value_type, is_signed) || ClangASTContext::IsPointerType(value_type))
+    {
+        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
+
+        DataExtractor data;
+        size_t num_bytes = new_value_sp->GetData(data);
+        lldb::offset_t offset = 0;
+        if (num_bytes <= 8)
+        {
+            uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
+            
+            if (reg_ctx->WriteRegisterFromUnsigned (reg_info, raw_value))
+                set_it_simple = true;
+        }
+        else
+        {
+            error.SetErrorString("We don't support returning longer than 64 bit integer values at present.");
+        }
+
+    }
+    else if (ClangASTContext::IsFloatingPointType (value_type, count, is_complex))
+    {
+        if (is_complex)
+            error.SetErrorString ("We don't support returning complex values at present");
+        else
+        {
+            size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
+            if (bit_width <= 64)
+            {
+                const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+                RegisterValue xmm0_value;
+                DataExtractor data;
+                size_t num_bytes = new_value_sp->GetData(data);
+
+                unsigned char buffer[16];
+                ByteOrder byte_order = data.GetByteOrder();
+                
+                data.CopyByteOrderedData (0, num_bytes, buffer, 16, byte_order);
+                xmm0_value.SetBytes(buffer, 16, byte_order);
+                reg_ctx->WriteRegister(xmm0_info, xmm0_value);
+                set_it_simple = true;
+            }
+            else
+            {
+                // FIXME - don't know how to do 80 bit long doubles yet.
+                error.SetErrorString ("We don't support returning float values > 64 bits at present");
+            }
+        }
+    }
+    
+    if (!set_it_simple)
+    {
+        // Okay we've got a structure or something that doesn't fit in a simple register.
+        // We should figure out where it really goes, but we don't support this yet.
+        error.SetErrorString ("We only support setting simple integer and float return types at present.");
+    }
+    
+    return error;
+}
+
+
 ValueObjectSP
 ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
-                                ClangASTType &ast_type) const
+                                            ClangASTType &ast_type) const
 {
     ValueObjectSP return_valobj_sp;
     Value value;
     
-    clang_type_t value_type = ast_type.GetOpaqueQualType();
-    if (!value_type) 
+    clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+    if (!return_value_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = ast_type.GetASTContext();
-    if (!ast_context)
+    clang::ASTContext *ast = ast_type.GetASTContext();
+    if (!ast)
         return return_valobj_sp;
 
-    value.SetContext (Value::eContextTypeClangType, value_type);
+    value.SetContext (Value::eContextTypeClangType, return_value_type);
     
     RegisterContext *reg_ctx = thread.GetRegisterContext().get();
     if (!reg_ctx)
         return return_valobj_sp;
     
-    bool is_signed;
-    bool is_complex;
-    uint32_t count;
-
-    if (ClangASTContext::IsIntegerType (value_type, is_signed))
+    const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL);
+    if (type_flags & ClangASTContext::eTypeIsScalar)
     {
-        // For now, assume that the types in the AST values come from the Target's 
-        // scratch AST.    
-        
-        
-        // Extract the register context so we can read arguments from registers
-        
-        size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-        unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
-        
-        switch (bit_width)
+        value.SetValueType(Value::eValueTypeScalar);
+
+        bool success = false;
+        if (type_flags & ClangASTContext::eTypeIsInteger)
         {
-        default:
-        case 128:
-            // Scalar can't hold 128-bit literals, so we don't handle this
-            return return_valobj_sp;
-        case 64:
-            if (is_signed)
-                value.GetScalar() = (int64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
-            else
-                value.GetScalar() = (uint64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
-            break;
-        case 32:
-            if (is_signed)
-                value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
-            else
-                value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
-            break;
-        case 16:
-            if (is_signed)
-                value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
-            else
-                value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
-            break;
-        case 8:
-            if (is_signed)
-                value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
-            else
-                value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
-            break;
+            // Extract the register context so we can read arguments from registers
+            
+            const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+            uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
+            const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0;
+            switch (byte_size)
+            {
+            default:
+                break;
+
+            case sizeof(uint64_t):
+                if (is_signed)
+                    value.GetScalar() = (int64_t)(raw_value);
+                else
+                    value.GetScalar() = (uint64_t)(raw_value);
+                success = true;
+                break;
+
+            case sizeof(uint32_t):
+                if (is_signed)
+                    value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+                else
+                    value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint16_t):
+                if (is_signed)
+                    value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+                else
+                    value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+                success = true;
+                break;
+
+            case sizeof(uint8_t):
+                if (is_signed)
+                    value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+                else
+                    value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+                success = true;
+                break;
+            }
         }
-    }
-    else if (ClangASTContext::IsFloatingPointType(value_type, count, is_complex))
-    {
-        // Don't handle complex yet.
-        if (is_complex)
-            return return_valobj_sp;
-        
-        size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
-        if (bit_width <= 64)
+        else if (type_flags & ClangASTContext::eTypeIsFloat)
         {
-            const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
-            RegisterValue xmm0_value;
-            if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
+            if (type_flags & ClangASTContext::eTypeIsComplex)
             {
-                DataExtractor data;
-                if (xmm0_value.GetData(data))
+                // Don't handle complex yet.
+            }
+            else
+            {
+                const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+                if (byte_size <= sizeof(long double))
                 {
-                    uint32_t offset = 0;
-                    switch (bit_width)
+                    const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+                    RegisterValue xmm0_value;
+                    if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
                     {
-                        default:
-                            return return_valobj_sp;
-                        case 32:
-                            value.GetScalar() = (float) data.GetFloat(&offset);
-                            break;
-                        case 64:
-                            value.GetScalar() = (double) data.GetDouble(&offset);
-                            break;
+                        DataExtractor data;
+                        if (xmm0_value.GetData(data))
+                        {
+                            lldb::offset_t offset = 0;
+                            if (byte_size == sizeof(float))
+                            {
+                                value.GetScalar() = (float) data.GetFloat(&offset);
+                                success = true;
+                            }
+                            else if (byte_size == sizeof(double))
+                            {
+                                value.GetScalar() = (double) data.GetDouble(&offset);
+                                success = true;
+                            }
+                            else if (byte_size == sizeof(long double))
+                            {
+                                // Don't handle long double since that can be encoded as 80 bit floats...
+                            }
+                        }
                     }
                 }
             }
         }
-        else if (bit_width == 128)
-        {
-            // FIXME: x86_64 returns long doubles in stmm0, which is in some 80 bit long double
-            // format, and so we'll have to write some code to convert that into 128 bit long doubles.
-//            const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("stmm0", 0);
-//            RegisterValue st0_value;
-//            if (reg_ctx->ReadRegister (st0_info, st0_value))
-//            {
-//                DataExtractor data;
-//                if (st0_value.GetData(data))
-//                {
-//                    uint32_t offset = 0;
-//                    value.GetScalar() = (long double) data.GetLongDouble (&offset);
-//                    return true;
-//                }
-//            }
-            
-            return return_valobj_sp;
-        }
+        
+        if (success)
+            return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                               ast_type.GetASTContext(),
+                                                               value,
+                                                               ConstString(""));
+
     }
-    else if (ClangASTContext::IsPointerType (value_type))
+    else if (type_flags & ClangASTContext::eTypeIsPointer)
     {
         unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
         value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
+        value.SetValueType(Value::eValueTypeScalar);
+        return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+                                                           ast_type.GetASTContext(),
+                                                           value,
+                                                           ConstString(""));
     }
-    else
+    else if (type_flags & ClangASTContext::eTypeIsVector)
     {
-        return return_valobj_sp;
+        const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+        if (byte_size > 0)
+        {
+
+            const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("ymm0", 0);
+            if (altivec_reg == NULL)
+            {
+                altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+                if (altivec_reg == NULL)
+                    altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+            }
+            
+            if (altivec_reg)
+            {
+                if (byte_size <= altivec_reg->byte_size)
+                {
+                    ProcessSP process_sp (thread.GetProcess());
+                    if (process_sp)
+                    {
+                        std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+                        const ByteOrder byte_order = process_sp->GetByteOrder();
+                        RegisterValue reg_value;
+                        if (reg_ctx->ReadRegister(altivec_reg, reg_value))
+                        {
+                            Error error;
+                            if (reg_value.GetAsMemoryData (altivec_reg,
+                                                           heap_data_ap->GetBytes(),
+                                                           heap_data_ap->GetByteSize(),
+                                                           byte_order,
+                                                           error))
+                            {
+                                DataExtractor data (DataBufferSP (heap_data_ap.release()),
+                                                    byte_order,
+                                                    process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
+                                return_valobj_sp = ValueObjectConstResult::Create (&thread,
+                                                                                   ast,
+                                                                                   return_value_type,
+                                                                                   ConstString(""),
+                                                                                   data);
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
     
-    // If we get here, we have a valid Value, so make our ValueObject out of it:
-    
-    return_valobj_sp = ValueObjectConstResult::Create(
-                                    thread.GetStackFrameAtIndex(0).get(),
-                                    ast_type.GetASTContext(),
-                                    value,
-                                    ConstString(""));
     return return_valobj_sp;
 }
 
@@ -699,20 +828,20 @@ ABISysV_x86_64::GetReturnValueObjectImpl
     if (return_valobj_sp)
         return return_valobj_sp;
     
-    clang_type_t ret_value_type = ast_type.GetOpaqueQualType();
-    if (!ret_value_type) 
+    clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+    if (!return_value_type)
         return return_valobj_sp;
     
-    clang::ASTContext *ast_context = ast_type.GetASTContext();
-    if (!ast_context)
+    clang::ASTContext *ast = ast_type.GetASTContext();
+    if (!ast)
         return return_valobj_sp;
         
     RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
     if (!reg_ctx_sp)
         return return_valobj_sp;
         
-    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, ret_value_type);
-    if (ClangASTContext::IsAggregateType(ret_value_type))
+    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type);
+    if (ClangASTContext::IsAggregateType(return_value_type))
     {
         Target *target = exe_ctx.GetTargetPtr();
         bool is_memory = true;
@@ -745,7 +874,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
             uint32_t fp_bytes = 0;       // Tracks how much of the xmm registers we've consumed so far
             uint32_t integer_bytes = 0;  // Tracks how much of the rax/rds registers we've consumed so far
             
-            uint32_t num_children = ClangASTContext::GetNumFields (ast_context, ret_value_type);
+            uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type);
             
             // Since we are in the small struct regime, assume we are not in memory.
             is_memory = false;
@@ -758,8 +887,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
                 bool is_complex;
                 uint32_t count;
                 
-                clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, ret_value_type, idx, name, &field_bit_offset, NULL, NULL);
-                size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, field_clang_type);
+                clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL);
+                size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type);
 
                 // If there are any unaligned fields, this is stored in memory.
                 if (field_bit_offset % field_bit_width != 0)
@@ -841,8 +970,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
                             else
                             {
                                 uint64_t next_field_bit_offset = 0;
-                                clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
-                                                                                                       ret_value_type, 
+                                clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+                                                                                                       return_value_type,
                                                                                                        idx + 1, 
                                                                                                        name, 
                                                                                                        &next_field_bit_offset,
@@ -867,8 +996,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
                             else
                             {
                                 uint64_t prev_field_bit_offset = 0;
-                                clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, 
-                                                                                                       ret_value_type, 
+                                clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+                                                                                                       return_value_type,
                                                                                                        idx - 1, 
                                                                                                        name, 
                                                                                                        &prev_field_bit_offset,
@@ -921,7 +1050,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
                 
                 // These two tests are just sanity checks.  If I somehow get the
                 // type calculation wrong above it is better to just return nothing
-                // than to assert or crash.
+                // than to assert or crash.
                 if (!copy_from_extractor)
                     return return_valobj_sp;
                 if (copy_from_offset + field_byte_width > copy_from_extractor->GetByteSize())
@@ -938,13 +1067,19 @@ ABISysV_x86_64::GetReturnValueObjectImpl
             {
                 // The result is in our data buffer.  Let's make a variable object out of it:
                 return_valobj_sp = ValueObjectConstResult::Create (&thread, 
-                                                                   ast_context, 
-                                                                   ret_value_type, 
+                                                                   ast,
+                                                                   return_value_type,
                                                                    ConstString(""),
                                                                    return_ext);
             }
         }
         
+        
+        // FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
+        // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
+        // return, and if we are at the first instruction and if so stash away the return location.  Then we would
+        // only return the memory return value if we know it is valid.
+        
         if (is_memory)
         {
             unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
@@ -995,6 +1130,7 @@ ABISysV_x86_64::CreateFunctionEntryUnwin
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("x86_64 at-func-entry default");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
     return true;
 }
 
@@ -1046,6 +1182,8 @@ ABISysV_x86_64::CreateDefaultUnwindPlan
 
     unwind_plan.AppendRow (row);
     unwind_plan.SetSourceName ("x86_64 default unwind plan");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
     return true;
 }
 
@@ -1057,14 +1195,23 @@ ABISysV_x86_64::RegisterIsVolatile (cons
 
 
 
-
+// See "Register Usage" in the 
+// "System V Application Binary Interface"
+// "AMD64 Architecture Processor Supplement" 
+// (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
+// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
+// current version is 0.99.6 released 2012-05-15 at http://x86-64.org/documentation/abi.pdf
 
 bool
 ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
 {
     if (reg_info)
     {
-        // Volatile registers include: rbx, rbp, rsp, r12, r13, r14, r15, rip
+        // Preserved registers are :
+        //    rbx, rsp, rbp, r12, r13, r14, r15
+        //    mxcsr (partially preserved)
+        //    x87 control word
+
         const char *name = reg_info->name;
         if (name[0] == 'r')
         {
@@ -1075,6 +1222,16 @@ ABISysV_x86_64::RegisterIsCalleeSaved (c
                     return name[3] == '\0';
                 break;
 
+            default:
+                break;
+            }
+        }
+
+        // Accept shorter-variant versions, rbx/ebx, rip/ eip, etc.
+        if (name[0] == 'r' || name[0] == 'e')
+        {
+            switch (name[1])
+            {
             case 'b': // rbp, rbx
                 if (name[2] == 'p' || name[2] == 'x')
                     return name[3] == '\0';
@@ -1090,10 +1247,14 @@ ABISysV_x86_64::RegisterIsCalleeSaved (c
                     return name[3] == '\0';
                 break;
 
-            default:
-                break;
             }
         }
+        if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')   // sp
+            return true;
+        if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0')   // fp
+            return true;
+        if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0')   // pc
+            return true;
     }
     return false;
 }
@@ -1103,8 +1264,8 @@ ABISysV_x86_64::RegisterIsCalleeSaved (c
 void
 ABISysV_x86_64::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "System V ABI for x86_64 targets",
                                    CreateInstance);
 }
 
@@ -1114,19 +1275,20 @@ ABISysV_x86_64::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+ABISysV_x86_64::GetPluginNameStatic()
+{
+    static ConstString g_name("sysv-x86_64");
+    return g_name;
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 ABISysV_x86_64::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-ABISysV_x86_64::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t

Modified: lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h Thu Jun  6 19:06:43 2013
@@ -45,10 +45,14 @@ public:
     GetArgumentValues (lldb_private::Thread &thread,
                        lldb_private::ValueList &values) const;
     
+    virtual lldb_private::Error
+    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value);
+
 protected:
     lldb::ValueObjectSP
     GetReturnValueObjectSimple (lldb_private::Thread &thread,
-                    lldb_private::ClangASTType &ast_type) const;
+                                lldb_private::ClangASTType &ast_type) const;
+    
 public:    
     virtual lldb::ValueObjectSP
     GetReturnValueObjectImpl (lldb_private::Thread &thread,
@@ -87,7 +91,13 @@ public:
         // aren't fixed width...
         return true;
     }
-    
+
+    virtual bool
+    FunctionCallsChangeCFA ()
+    {
+        return true;
+    }
+
     virtual const lldb_private::RegisterInfo *
     GetRegisterInfoArray (uint32_t &count);
     //------------------------------------------------------------------
@@ -102,15 +112,15 @@ public:
     static lldb::ABISP
     CreateInstance (const lldb_private::ArchSpec &arch);
 
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
 
-    virtual const char *
-    GetShortPluginName();
-
     virtual uint32_t
     GetPluginVersion();
 

Removed: lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp (removed)
@@ -1,525 +0,0 @@
-//===-- DisassemblerLLVM.cpp ------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DisassemblerLLVM.h"
-
-#include "llvm-c/EnhancedDisassembly.h"
-#include "llvm/Support/TargetSelect.h"
-
-#include "lldb/Core/Address.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Disassembler.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-
-#include <assert.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-static int 
-DataExtractorByteReader (uint8_t *byte, uint64_t address, void *arg)
-{
-    DataExtractor &extractor = *((DataExtractor *)arg);
-
-    if (extractor.ValidOffset(address))
-    {
-        *byte = *(extractor.GetDataStart() + address);
-        return 0;
-    }
-    else
-    {
-        return -1;
-    }
-}
-
-namespace {
-    struct RegisterReaderArg {
-        const lldb::addr_t instructionPointer;
-        const EDDisassemblerRef disassembler;
-
-        RegisterReaderArg(lldb::addr_t ip,
-                          EDDisassemblerRef dis) :
-            instructionPointer(ip),
-            disassembler(dis)
-        {
-        }
-    };
-}
-
-static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg)
-{
-    uint64_t instructionPointer = ((RegisterReaderArg*)arg)->instructionPointer;
-    EDDisassemblerRef disassembler = ((RegisterReaderArg*)arg)->disassembler;
-
-    if (EDRegisterIsProgramCounter(disassembler, regID)) {
-        *value = instructionPointer;
-        return 0;
-    }
-
-    return -1;
-}
-
-InstructionLLVM::InstructionLLVM (const Address &addr, 
-                                  AddressClass addr_class,
-                                  EDDisassemblerRef disassembler,
-                                  llvm::Triple::ArchType arch_type) :
-    Instruction (addr, addr_class),
-    m_disassembler (disassembler),
-    m_inst (NULL),
-    m_arch_type (arch_type)
-{
-}
-
-InstructionLLVM::~InstructionLLVM()
-{
-    if (m_inst)
-    {
-        EDReleaseInst(m_inst);
-        m_inst = NULL;
-    }
-}
-
-static void
-PadString(Stream *s, const std::string &str, size_t width)
-{
-    int diff = width - str.length();
-
-    if (diff > 0)
-        s->Printf("%s%*.*s", str.c_str(), diff, diff, "");
-    else
-        s->Printf("%s ", str.c_str());
-}
-static void
-AddSymbolicInfo (const ExecutionContext *exe_ctx, 
-                 StreamString &comment, 
-                 uint64_t operand_value, 
-                 const Address &inst_addr)
-{
-    Address so_addr;
-    Target *target = NULL;
-    if (exe_ctx)
-        target = exe_ctx->GetTargetPtr();
-    if (target && !target->GetSectionLoadList().IsEmpty())
-    {
-        if (target->GetSectionLoadList().ResolveLoadAddress(operand_value, so_addr))
-            so_addr.Dump (&comment, 
-                          exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 
-                          Address::DumpStyleResolvedDescriptionNoModule, 
-                          Address::DumpStyleSectionNameOffset);
-    }
-    else
-    {
-        ModuleSP module_sp (inst_addr.GetModule());
-        if (module_sp)
-        {
-            if (module_sp->ResolveFileAddress(operand_value, so_addr))
-                so_addr.Dump (&comment, 
-                              exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL, 
-                              Address::DumpStyleResolvedDescriptionNoModule, 
-                              Address::DumpStyleSectionNameOffset);
-        }
-    }
-}
-
-#include "llvm/ADT/StringRef.h"
-static inline void StripSpaces(llvm::StringRef &Str)
-{
-    while (!Str.empty() && isspace(Str[0]))
-        Str = Str.substr(1);
-    while (!Str.empty() && isspace(Str.back()))
-        Str = Str.substr(0, Str.size()-1);
-}
-static inline void RStrip(llvm::StringRef &Str, char c)
-{
-    if (!Str.empty() && Str.back() == c)
-        Str = Str.substr(0, Str.size()-1);
-}
-// Aligns the raw disassembly (passed as 'str') with the rest of edis'ed disassembly output.
-// This is called from non-raw mode when edis of the current m_inst fails for some reason.
-static void
-Align(Stream *s, const char *str, size_t opcodeColWidth, size_t operandColWidth)
-{
-    llvm::StringRef raw_disasm(str);
-    StripSpaces(raw_disasm);
-    // Split the raw disassembly into opcode and operands.
-    std::pair<llvm::StringRef, llvm::StringRef> p = raw_disasm.split('\t');
-    PadString(s, p.first, opcodeColWidth);
-    if (!p.second.empty())
-        PadString(s, p.second, operandColWidth);
-}
-
-#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
-
-void
-InstructionLLVM::CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx)
-{
-    const int num_tokens = EDNumTokens(m_inst);
-    if (num_tokens > 0)
-    {
-        const char *token_cstr = NULL;
-        int currentOpIndex = -1;
-        StreamString comment;
-        uint32_t addr_nibble_size = 8;
-        addr_t base_addr = LLDB_INVALID_ADDRESS;
-        Target *target = exe_ctx ? exe_ctx->GetTargetPtr() : NULL;
-        if (target && !target->GetSectionLoadList().IsEmpty())
-            base_addr = GetAddress().GetLoadAddress (target);
-        if (base_addr == LLDB_INVALID_ADDRESS)
-            base_addr = GetAddress().GetFileAddress ();
-        addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2;
-
-        lldb::addr_t PC = base_addr + EDInstByteSize(m_inst);
-        
-        // When executing an ARM instruction, PC reads as the address of the
-        // current instruction plus 8.  And for Thumb, it is plus 4.
-        if (m_arch_type == llvm::Triple::arm)
-            PC = base_addr + 8;
-        else if (m_arch_type == llvm::Triple::thumb)
-            PC = base_addr + 4;
-        
-        RegisterReaderArg rra(PC, m_disassembler);
-
-        for (int token_idx = 0; token_idx < num_tokens; ++token_idx)
-        {
-            EDTokenRef token;
-            if (EDGetToken(&token, m_inst, token_idx))
-                break;
-            
-            if (EDTokenIsOpcode(token) == 1)
-            {
-                if (EDGetTokenString(&token_cstr, token) == 0) // 0 on success
-                {
-                    if (token_cstr)
-                    m_opcode_name.assign(token_cstr);
-                }
-            }
-            else
-            {                
-                int operandIndex = EDOperandIndexForToken(token);
-
-                if (operandIndex >= 0)
-                {
-                    if (operandIndex != currentOpIndex)
-                    {
-                        currentOpIndex = operandIndex;
-                        EDOperandRef operand;
-                        
-                        if (!EDGetOperand(&operand, m_inst, currentOpIndex))
-                        {
-                            if (EDOperandIsMemory(operand))
-                            {
-                                uint64_t operand_value;
-                                
-                                if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra))
-                                {
-                                    comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);                                    
-                                    AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
-                                }
-                            }
-                        }
-                    }
-                }
-                if (m_mnemocics.empty() && EDTokenIsWhitespace (token) == 1)
-                    continue;
-                if (EDGetTokenString (&token_cstr, token))
-                    break;
-                m_mnemocics.append (token_cstr);
-            }
-        }
-        // FIXME!!!
-        // Workaround for llvm::tB's operands not properly parsed by ARMAsmParser.
-        if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("b") == 0) 
-        {
-            const char *inst_str;
-            const char *pos = NULL;
-            comment.Clear();
-            if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) 
-            {
-                uint64_t operand_value = PC + atoi(++pos);
-                // Put the address value into the operands.
-                comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
-                AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
-            }
-        }
-        // Yet more workaround for "bl #..." and "blx #...".
-        if ((m_arch_type == llvm::Triple::arm || m_arch_type == llvm::Triple::thumb) &&
-            (m_opcode_name.compare("bl") == 0 || m_opcode_name.compare("blx") == 0)) 
-        {
-            const char *inst_str;
-            const char *pos = NULL;
-            comment.Clear();
-            if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL) 
-            {
-                if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("blx") == 0)
-                {
-                    // A8.6.23 BLX (immediate)
-                    // Target Address = Align(PC,4) + offset value
-                    PC = AlignPC(PC);
-                }
-                uint64_t operand_value = PC + atoi(++pos);
-                // Put the address value into the comment.
-                comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
-                // And the original token string into the operands.
-//                llvm::StringRef Str(pos - 1);
-//                RStrip(Str, '\n');
-//                operands.PutCString(Str.str().c_str());
-                AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
-            }
-        }
-        // END of workaround.
-
-        m_comment.swap (comment.GetString());
-    }
-}
-
-bool
-InstructionLLVM::DoesBranch() const
-{
-    return EDInstIsBranch(m_inst);
-}
-
-size_t
-InstructionLLVM::Decode (const Disassembler &disassembler, 
-                         const lldb_private::DataExtractor &data,
-                         uint32_t data_offset)
-{
-    if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
-    {
-        const int byte_size = EDInstByteSize(m_inst);
-        uint32_t offset = data_offset;
-        // Make a copy of the opcode in m_opcode
-        switch (disassembler.GetArchitecture().GetMachine())
-        {
-        case llvm::Triple::x86:
-        case llvm::Triple::x86_64:
-            m_opcode.SetOpcodeBytes (data.PeekData (data_offset, byte_size), byte_size);
-            break;
-
-        case llvm::Triple::arm:
-        case llvm::Triple::thumb:
-            switch (byte_size)
-            {
-            case 2: 
-                m_opcode.SetOpcode16 (data.GetU16 (&offset)); 
-                break;
-
-            case 4:
-                {
-                if (GetAddressClass() ==  eAddressClassCodeAlternateISA)
-                {
-                    // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves.
-                    uint32_t orig_bytes = data.GetU32 (&offset);
-                    uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1);
-                    uint16_t lower_bits = orig_bytes & ((1u << 16) - 1);
-                    uint32_t swapped = (lower_bits << 16) | upper_bits;
-                    m_opcode.SetOpcode32 (swapped);
-                }
-                else
-                    m_opcode.SetOpcode32 (data.GetU32 (&offset));
-                }
-                break;
-
-            default:
-                assert (!"Invalid ARM opcode size");
-                break;
-            }
-            break;
-
-        default:
-            assert (!"This shouldn't happen since we control the architecture we allow DisassemblerLLVM to be created for");
-            break;
-        }
-        return byte_size;
-    }
-    else
-        return 0;
-}
-
-static inline EDAssemblySyntax_t
-SyntaxForArchSpec (const ArchSpec &arch)
-{
-    switch (arch.GetMachine ())
-    {
-    case llvm::Triple::x86:
-    case llvm::Triple::x86_64:
-        return kEDAssemblySyntaxX86ATT;
-    case llvm::Triple::arm:
-    case llvm::Triple::thumb:
-        return kEDAssemblySyntaxARMUAL;
-    default:
-        break;
-    }
-    return (EDAssemblySyntax_t)0;   // default
-}
-
-Disassembler *
-DisassemblerLLVM::CreateInstance(const ArchSpec &arch)
-{
-    std::auto_ptr<DisassemblerLLVM> disasm_ap (new DisassemblerLLVM(arch));
- 
-    if (disasm_ap.get() && disasm_ap->IsValid())
-        return disasm_ap.release();
-
-    return NULL;
-}
-
-DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) :
-    Disassembler (arch),
-    m_disassembler (NULL),
-    m_disassembler_thumb (NULL) // For ARM only
-{
-    // Initialize the LLVM objects needed to use the disassembler.
-    static struct InitializeLLVM {
-        InitializeLLVM() {
-            llvm::InitializeAllTargetInfos();
-            llvm::InitializeAllTargetMCs();
-            llvm::InitializeAllAsmParsers();
-            llvm::InitializeAllDisassemblers();
-        }
-    } InitializeLLVM;
-
-    const std::string &arch_triple = arch.GetTriple().str();
-    if (!arch_triple.empty())
-    {
-        if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch)))
-            m_disassembler = NULL;
-        llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch();
-		// Don't have the lldb::Triple::thumb architecture here. If someone specifies
-		// "thumb" as the architecture, we want a thumb only disassembler. But if any
-		// architecture starting with "arm" if specified, we want to auto detect the
-		// arm/thumb code automatically using the AddressClass from section offset 
-		// addresses.
-        if (llvm_arch == llvm::Triple::arm)
-        {
-            ArchSpec thumb_arch(arch);
-            thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
-            std::string thumb_triple(thumb_arch.GetTriple().getTriple());
-            if (EDGetDisassembler(&m_disassembler_thumb, thumb_triple.c_str(), kEDAssemblySyntaxARMUAL))
-                m_disassembler_thumb = NULL;
-        }
-    }
-}
-
-DisassemblerLLVM::~DisassemblerLLVM()
-{
-}
-
-size_t
-DisassemblerLLVM::DecodeInstructions
-(
-    const Address &base_addr,
-    const DataExtractor& data,
-    uint32_t data_offset,
-    uint32_t num_instructions,
-    bool append
-)
-{
-    if (m_disassembler == NULL)
-        return 0;
-
-    size_t total_inst_byte_size = 0;
-
-    if (!append)
-        m_instruction_list.Clear();
-
-    while (data.ValidOffset(data_offset) && num_instructions)
-    {
-        Address inst_addr (base_addr);
-        inst_addr.Slide(data_offset);
-
-        bool use_thumb = false;
-        // If we have a thumb disassembler, then we have an ARM architecture
-        // so we need to check what the instruction address class is to make
-        // sure we shouldn't be disassembling as thumb...
-        AddressClass inst_address_class = eAddressClassInvalid;
-        if (m_disassembler_thumb)
-        {
-            inst_address_class = inst_addr.GetAddressClass ();
-            if (inst_address_class == eAddressClassCodeAlternateISA)
-                use_thumb = true;
-        }
-        
-        InstructionSP inst_sp (new InstructionLLVM (inst_addr, 
-                                                    inst_address_class,
-                                                    use_thumb ? m_disassembler_thumb : m_disassembler,
-                                                    use_thumb ? llvm::Triple::thumb : m_arch.GetMachine()));
-
-        size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset);
-
-        if (inst_byte_size == 0)
-            break;
-
-        m_instruction_list.Append (inst_sp);
-
-        total_inst_byte_size += inst_byte_size;
-        data_offset += inst_byte_size;
-        num_instructions--;
-    }
-
-    return total_inst_byte_size;
-}
-
-void
-DisassemblerLLVM::Initialize()
-{
-    PluginManager::RegisterPlugin (GetPluginNameStatic(),
-                                   GetPluginDescriptionStatic(),
-                                   CreateInstance);
-}
-
-void
-DisassemblerLLVM::Terminate()
-{
-    PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-const char *
-DisassemblerLLVM::GetPluginNameStatic()
-{
-    return "llvm-edis";
-}
-
-const char *
-DisassemblerLLVM::GetPluginDescriptionStatic()
-{
-    return "Disassembler that uses the LLVM enhanced disassembler to disassemble i386, x86_64 and ARM.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-const char *
-DisassemblerLLVM::GetPluginName()
-{
-    return "DisassemblerLLVM";
-}
-
-const char *
-DisassemblerLLVM::GetShortPluginName()
-{
-    return GetPluginNameStatic();
-}
-
-uint32_t
-DisassemblerLLVM::GetPluginVersion()
-{
-    return 1;
-}
-

Removed: lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h (removed)
@@ -1,105 +0,0 @@
-//===-- DisassemblerLLVM.h --------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_DisassemblerLLVM_h_
-#define liblldb_DisassemblerLLVM_h_
-
-
-#include "llvm-c/EnhancedDisassembly.h"
-
-#include "lldb/Core/Disassembler.h"
-#include "lldb/Host/Mutex.h"
-
-class InstructionLLVM : public lldb_private::Instruction
-{
-public:
-    InstructionLLVM (const lldb_private::Address &addr,
-                     lldb::AddressClass addr_class,
-                     EDDisassemblerRef disassembler,
-                     llvm::Triple::ArchType arch_type);
-    
-    virtual
-    ~InstructionLLVM();
-    
-    virtual bool
-    DoesBranch () const;
-    
-    virtual size_t
-    Decode (const lldb_private::Disassembler &disassembler,
-            const lldb_private::DataExtractor &data,
-            uint32_t data_offset);
-    
-    virtual void
-    CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext* exe_ctx);
-    
-protected:
-    EDDisassemblerRef m_disassembler;
-    EDInstRef m_inst;
-    llvm::Triple::ArchType m_arch_type;
-};
-
-
-class DisassemblerLLVM : public lldb_private::Disassembler
-{
-public:
-    //------------------------------------------------------------------
-    // Static Functions
-    //------------------------------------------------------------------
-    static void
-    Initialize();
-
-    static void
-    Terminate();
-
-    static const char *
-    GetPluginNameStatic();
-
-    static const char *
-    GetPluginDescriptionStatic();
-
-    static lldb_private::Disassembler *
-    CreateInstance(const lldb_private::ArchSpec &arch);
-
-
-    DisassemblerLLVM(const lldb_private::ArchSpec &arch);
-
-    virtual
-    ~DisassemblerLLVM();
-
-    size_t
-    DecodeInstructions (const lldb_private::Address &base_addr,
-                        const lldb_private::DataExtractor& data,
-                        uint32_t data_offset,
-                        uint32_t num_instructions,
-                        bool append);
-    
-    //------------------------------------------------------------------
-    // PluginInterface protocol
-    //------------------------------------------------------------------
-    virtual const char *
-    GetPluginName();
-
-    virtual const char *
-    GetShortPluginName();
-
-    virtual uint32_t
-    GetPluginVersion();
-
-protected:
-    bool
-    IsValid() const
-    {
-        return m_disassembler != NULL;
-    }
-
-    EDDisassemblerRef m_disassembler;
-    EDDisassemblerRef m_disassembler_thumb;
-};
-
-#endif  // liblldb_DisassemblerLLVM_h_

Modified: lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Thu Jun  6 19:06:43 2013
@@ -10,10 +10,26 @@
 #include "DisassemblerLLVMC.h"
 
 #include "llvm-c/Disassembler.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCRelocationInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/ADT/SmallString.h"
+
 
 #include "lldb/Core/Address.h"
 #include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -33,11 +49,11 @@ public:
     InstructionLLVMC (DisassemblerLLVMC &disasm,
                       const lldb_private::Address &address, 
                       AddressClass addr_class) :
-        Instruction(address, addr_class),
-        m_is_valid(false),
-        m_disasm(disasm),
-        m_disasm_sp(disasm.shared_from_this()),
-        m_does_branch(eLazyBoolCalculate)
+        Instruction (address, addr_class),
+        m_disasm_sp (disasm.shared_from_this()),
+        m_does_branch (eLazyBoolCalculate),
+        m_is_valid (false),
+        m_using_file_addr (false)
     {
     }
     
@@ -46,33 +62,71 @@ public:
     {
     }
     
-    static void
-    PadToWidth (lldb_private::StreamString &ss,
-                int new_width)
+    virtual bool
+    DoesBranch ()
     {
-        int old_width = ss.GetSize();
-        
-        if (old_width < new_width)
+        if (m_does_branch == eLazyBoolCalculate)
         {
-            ss.Printf("%*s", new_width - old_width, "");
+            GetDisassemblerLLVMC().Lock(this, NULL);
+            DataExtractor data;
+            if (m_opcode.GetData(data))
+            {
+                bool is_alternate_isa;
+                lldb::addr_t pc = m_address.GetFileAddress();
+
+                DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+                const uint8_t *opcode_data = data.GetDataStart();
+                const size_t opcode_data_len = data.GetByteSize();
+                llvm::MCInst inst;
+                const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+                                                                   opcode_data_len,
+                                                                   pc,
+                                                                   inst);
+                // Be conservative, if we didn't understand the instruction, say it might branch...
+                if (inst_size == 0)
+                    m_does_branch = eLazyBoolYes;
+                else
+                {
+                    const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+                    if (can_branch)
+                        m_does_branch = eLazyBoolYes;
+                    else
+                        m_does_branch = eLazyBoolNo;
+                }
+            }
+            GetDisassemblerLLVMC().Unlock();
         }
+        return m_does_branch == eLazyBoolYes;
     }
-        
-    virtual bool
-    DoesBranch () const
+    
+    DisassemblerLLVMC::LLVMCDisassembler *
+    GetDisasmToUse (bool &is_alternate_isa)
     {
-        return m_does_branch == eLazyBoolYes;
+        is_alternate_isa = false;
+        DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+        if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
+        {
+            const AddressClass address_class = GetAddressClass ();
+        
+            if (address_class == eAddressClassCodeAlternateISA)
+            {
+                is_alternate_isa = true;
+                return llvm_disasm.m_alternate_disasm_ap.get();
+            }
+        }
+        return llvm_disasm.m_disasm_ap.get();
     }
     
     virtual size_t
     Decode (const lldb_private::Disassembler &disassembler,
             const lldb_private::DataExtractor &data,
-            uint32_t data_offset)
+            lldb::offset_t data_offset)
     {
         // All we have to do is read the opcode which can be easy for some
         // architetures
         bool got_op = false;
-        const ArchSpec &arch = m_disasm.GetArchitecture();
+        DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+        const ArchSpec &arch = llvm_disasm.GetArchitecture();
         
         const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
         const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
@@ -112,23 +166,13 @@ public:
         }
         if (!got_op)
         {
-            ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context;
-            
-            bool is_altnernate_isa = false;
-            if (m_disasm.m_alternate_disasm_context)
-            {
-                const AddressClass address_class = GetAddressClass ();
+            bool is_alternate_isa = false;
+            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
             
-                if (address_class == eAddressClassCodeAlternateISA)
-                {
-                    disasm_context = m_disasm.m_alternate_disasm_context;
-                    is_altnernate_isa = true;
-                }
-            }
             const llvm::Triple::ArchType machine = arch.GetMachine();
             if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
             {
-                if (machine == llvm::Triple::thumb || is_altnernate_isa)
+                if (machine == llvm::Triple::thumb || is_alternate_isa)
                 {
                     uint32_t thumb_opcode = data.GetU16(&data_offset);
                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
@@ -154,20 +198,17 @@ public:
             {
                 // The opcode isn't evenly sized, so we need to actually use the llvm
                 // disassembler to parse it and get the size.
-                char out_string[512];
-                m_disasm.Lock(this, NULL);
                 uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
-                const size_t opcode_data_len = data.GetByteSize() - data_offset;
+                const size_t opcode_data_len = data.BytesLeft(data_offset);
                 const addr_t pc = m_address.GetFileAddress();
-                const size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
-                                                                  opcode_data,
+                llvm::MCInst inst;
+                
+                llvm_disasm.Lock(this, NULL);
+                const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
                                                                   opcode_data_len,
-                                                                  pc, // PC value
-                                                                  out_string,
-                                                                  sizeof(out_string));
-                // The address lookup function could have caused us to fill in our comment
-                m_comment.clear();
-                m_disasm.Unlock();
+                                                                  pc,
+                                                                  inst);
+                llvm_disasm.Unlock();
                 if (inst_size == 0)
                     m_opcode.Clear();
                 else
@@ -202,43 +243,57 @@ public:
         {
             char out_string[512];
             
-            ::LLVMDisasmContextRef disasm_context;
+            DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+
+            DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
             
             if (address_class == eAddressClassCodeAlternateISA)
-                disasm_context = m_disasm.m_alternate_disasm_context;
+                mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
             else
-                disasm_context = m_disasm.m_disasm_context;
+                mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
             
-            lldb::addr_t pc = LLDB_INVALID_ADDRESS;
+            lldb::addr_t pc = m_address.GetFileAddress();
+            m_using_file_addr = true;
             
-            if (exe_ctx)
+            const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
+            if (!data_from_file)
             {
-                Target *target = exe_ctx->GetTargetPtr();
-                if (target)
-                    pc = m_address.GetLoadAddress(target);
+                if (exe_ctx)
+                {
+                    Target *target = exe_ctx->GetTargetPtr();
+                    if (target)
+                    {
+                        const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+                        if (load_addr != LLDB_INVALID_ADDRESS)
+                        {
+                            pc = load_addr;
+                            m_using_file_addr = false;
+                        }
+                    }
+                }
             }
             
-            if (pc == LLDB_INVALID_ADDRESS)
-                pc = m_address.GetFileAddress();
+            llvm_disasm.Lock(this, exe_ctx);
             
-            m_disasm.Lock(this, exe_ctx);
-            uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
+            const uint8_t *opcode_data = data.GetDataStart();
             const size_t opcode_data_len = data.GetByteSize();
-            size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
-                                                        opcode_data,
-                                                        opcode_data_len,
-                                                        pc,
-                                                        out_string,
-                                                        sizeof(out_string));
+            llvm::MCInst inst;
+            size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+                                                         opcode_data_len,
+                                                         pc,
+                                                         inst);
+                
+            if (inst_size > 0)
+                mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
             
-            m_disasm.Unlock();
+            llvm_disasm.Unlock();
             
             if (inst_size == 0)
             {
                 m_comment.assign ("unknown opcode");
                 inst_size = m_opcode.GetByteSize();
                 StreamString mnemonic_strm;
-                uint32_t offset = 0;
+                lldb::offset_t offset = 0;
                 switch (inst_size)
                 {
                     case 1:
@@ -270,7 +325,7 @@ public:
                             const uint64_t uval64 = data.GetU64(&offset);
                             m_opcode.SetOpcode64(uval64);
                             m_opcode_name.assign (".quad");
-                            mnemonic_strm.Printf("0x%16.16llx", uval64);
+                            mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
                         }
                         break;
                     default:
@@ -289,17 +344,19 @@ public:
                         }
                         break;
                 }
-                m_mnemocics.swap(mnemonic_strm.GetString());
+                m_mnemonics.swap(mnemonic_strm.GetString());
                 return;
             }
             else
             {
                 if (m_does_branch == eLazyBoolCalculate)
                 {
-                    if (StringRepresentsBranch (out_string, strlen(out_string)))
+                    const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+                    if (can_branch)
                         m_does_branch = eLazyBoolYes;
                     else
                         m_does_branch = eLazyBoolNo;
+
                 }
             }
             
@@ -316,110 +373,39 @@ public:
                 if (matches[1].rm_so != -1)
                     m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
                 if (matches[2].rm_so != -1)
-                    m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
+                    m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
             }
         }
     }
     
     bool
-    IsValid ()
+    IsValid () const
     {
         return m_is_valid;
     }
     
+    bool
+    UsingFileAddress() const
+    {
+        return m_using_file_addr;
+    }
     size_t
-    GetByteSize ()
+    GetByteSize () const
     {
         return m_opcode.GetByteSize();
     }
-protected:
     
-    bool StringRepresentsBranch (const char *data, size_t size)
+    DisassemblerLLVMC &
+    GetDisassemblerLLVMC ()
     {
-        const char *cursor = data;
-
-        bool inWhitespace = true;
-
-        while (inWhitespace && cursor < data + size)
-        {
-            switch (*cursor)
-            {
-            default:
-                inWhitespace = false;
-                break;
-            case ' ':
-                break;
-            case '\t':
-                break;
-            }
-            
-            if (inWhitespace)
-                ++cursor;
-        }
-        
-        if (cursor >= data + size)
-            return false;
-        
-        llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
-        
-        switch (arch)
-        {
-        default:
-            return false;
-        case llvm::Triple::x86:
-        case llvm::Triple::x86_64:
-            switch (cursor[0])
-            {
-            default:
-                return false;
-            case 'j':
-                return true;
-            case 'c':
-                if (cursor[1] == 'a' &&
-                    cursor[2] == 'l' &&
-                    cursor[3] == 'l')
-                    return true;
-                else
-                    return false;
-            }
-        case llvm::Triple::arm:
-        case llvm::Triple::thumb:
-            switch (cursor[0])
-            {
-            default:
-                return false;
-            case 'b':
-                {
-                    switch (cursor[1])
-                    {
-                    default:
-                        return true;
-                    case 'f':
-                    case 'i':
-                    case 'k':
-                        return false;
-                    }
-                }
-            case 'c':
-                {
-                    switch (cursor[1])
-                    {
-                    default:
-                        return false;
-                    case 'b':
-                        return true;
-                    }
-                }
-            }
-        }
-        
-        return false;
+        return *(DisassemblerLLVMC *)m_disasm_sp.get();
     }
+protected:
     
-    bool                    m_is_valid;
-    DisassemblerLLVMC      &m_disasm;
     DisassemblerSP          m_disasm_sp; // for ownership
     LazyBool                m_does_branch;
+    bool                    m_is_valid;
+    bool                    m_using_file_addr;
     
     static bool             s_regex_compiled;
     static ::regex_t        s_regex;
@@ -428,64 +414,249 @@ protected:
 bool InstructionLLVMC::s_regex_compiled = false;
 ::regex_t InstructionLLVMC::s_regex;
 
-Disassembler *
-DisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
+    m_is_valid(true)
+{
+    std::string Error;
+    const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
+    if (!curr_target)
+    {
+        m_is_valid = false;
+        return;
+    }
+    
+    m_instr_info_ap.reset(curr_target->createMCInstrInfo());
+    m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
+    
+    std::string features_str;
+
+    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
+                                                                features_str));
+    
+    m_asm_info_ap.reset(curr_target->createMCAsmInfo(*curr_target->createMCRegInfo(triple), triple));
+
+    if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
+    {
+        m_is_valid = false;
+        return;
+    }
+    
+    m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
+    
+    m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
+    if (m_disasm_ap.get() && m_context_ap.get())
+    {
+        llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
+        if (!RelInfo)
+        {
+            m_is_valid = false;
+            return;
+        }
+        m_disasm_ap->setupForSymbolicDisassembly(NULL,
+                                                 DisassemblerLLVMC::SymbolLookupCallback,
+                                                 (void *) &owner,
+                                                 m_context_ap.get(),
+                                                 RelInfo);
+        
+        unsigned asm_printer_variant;
+        if (flavor == ~0U)
+            asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
+        else
+        {
+            asm_printer_variant = flavor;
+        }
+        
+        m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
+                                                                  *m_asm_info_ap.get(),
+                                                                  *m_instr_info_ap.get(),
+                                                                  *m_reg_info_ap.get(),
+                                                                  *m_subtarget_info_ap.get()));
+        if (m_instr_printer_ap.get() == NULL)
+        {
+            m_disasm_ap.reset();
+            m_is_valid = false;
+        }
+    }
+    else
+        m_is_valid = false;
+}
+
+DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler()
+{
+}
+
+namespace {
+    // This is the memory object we use in GetInstruction.
+    class LLDBDisasmMemoryObject : public llvm::MemoryObject {
+      const uint8_t *m_bytes;
+      uint64_t m_size;
+      uint64_t m_base_PC;
+    public:
+      LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
+                         m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
+     
+      uint64_t getBase() const { return m_base_PC; }
+      uint64_t getExtent() const { return m_size; }
+
+      int readByte(uint64_t addr, uint8_t *byte) const {
+        if (addr - m_base_PC >= m_size)
+          return -1;
+        *byte = m_bytes[addr - m_base_PC];
+        return 0;
+      }
+    };
+} // End Anonymous Namespace
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
+                                                 size_t opcode_data_len,
+                                                 lldb::addr_t pc,
+                                                 llvm::MCInst &mc_inst)
+{
+    LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
+    llvm::MCDisassembler::DecodeStatus status;
+
+    uint64_t new_inst_size;
+    status = m_disasm_ap->getInstruction(mc_inst,
+                                         new_inst_size,
+                                         memory_object,
+                                         pc,
+                                         llvm::nulls(),
+                                         llvm::nulls());
+    if (status == llvm::MCDisassembler::Success)
+        return new_inst_size;
+    else
+        return 0;
+}
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
+                                                   char *dst,
+                                                   size_t dst_len)
 {
-    std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
+    llvm::StringRef unused_annotations;
+    llvm::SmallString<64> inst_string;
+    llvm::raw_svector_ostream inst_stream(inst_string);
+    m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
+    inst_stream.flush();
+    const size_t output_size = std::min(dst_len - 1, inst_string.size());
+    std::memcpy(dst, inst_string.data(), output_size);
+    dst[output_size] = '\0';
     
-    if (disasm_ap.get() && disasm_ap->IsValid())
-        return disasm_ap.release();
+    return output_size;
+}
+
+bool
+DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
+{
+    return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+}
+
+bool
+DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
+{
+    llvm::Triple triple = arch.GetTriple();
+    if (flavor == NULL || strcmp (flavor, "default") == 0)
+        return true;
     
+    if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
+    {
+        if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
+            return true;
+        else
+            return false;
+    }
+    else
+        return false;
+}
+    
+
+Disassembler *
+DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
+{
+    if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
+    {
+        std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
+    
+        if (disasm_ap.get() && disasm_ap->IsValid())
+            return disasm_ap.release();
+    }
     return NULL;
 }
 
-DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
-    Disassembler(arch),
+DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
+    Disassembler(arch, flavor_string),
     m_exe_ctx (NULL),
     m_inst (NULL),
-    m_disasm_context (NULL),
-    m_alternate_disasm_context (NULL)
+    m_data_from_file (false)
 {
-    m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(), 
-                                          (void*)this, 
-                                          /*TagType=*/1,
-                                          NULL,
-                                          DisassemblerLLVMC::SymbolLookupCallback);
+    if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
+    {
+        m_flavor.assign("default");
+    }
+    
+    const char *triple = arch.GetTriple().getTriple().c_str();
+    unsigned flavor = ~0U;
+    
+    // So far the only supported flavor is "intel" on x86.  The base class will set this
+    // correctly coming in.
+    if (arch.GetTriple().getArch() == llvm::Triple::x86
+        || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+    {
+        if (m_flavor == "intel")
+        {
+            flavor = 1;
+        }
+        else if (m_flavor == "att")
+        {
+            flavor = 0;
+        }
+    }
+    
+    m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
+    if (!m_disasm_ap->IsValid())
+    {
+        // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
+        // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
+        m_disasm_ap.reset();
+    }
     
     if (arch.GetTriple().getArch() == llvm::Triple::arm)
     {
         ArchSpec thumb_arch(arch);
-        thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
+        std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str());
+        // Replace "arm" with "thumb" so we get all thumb variants correct
+        if (thumb_arch_name.size() > 3)
+        {
+            thumb_arch_name.erase(0,3);
+            thumb_arch_name.insert(0, "thumb");
+        }
+        else
+        {
+            thumb_arch_name = "thumbv7";
+        }
+        thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
         std::string thumb_triple(thumb_arch.GetTriple().getTriple());
-
-        m_alternate_disasm_context = ::LLVMCreateDisasm(thumb_triple.c_str(),
-                                                        (void*)this, 
-                                                        /*TagType=*/1,
-                                                        NULL,
-                                                        DisassemblerLLVMC::SymbolLookupCallback);
+        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
+        if (!m_alternate_disasm_ap->IsValid())
+        {
+            m_disasm_ap.reset();
+            m_alternate_disasm_ap.reset();
+        }
     }
 }
 
 DisassemblerLLVMC::~DisassemblerLLVMC()
 {
-    if (m_disasm_context)
-    {
-        ::LLVMDisasmDispose(m_disasm_context);
-        m_disasm_context = NULL;
-    }
-    if (m_alternate_disasm_context)
-    {
-        ::LLVMDisasmDispose(m_alternate_disasm_context);
-        m_alternate_disasm_context = NULL;
-    }
 }
 
 size_t
 DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
                                        const DataExtractor& data,
-                                       uint32_t data_offset,
-                                       uint32_t num_instructions,
-                                       bool append)
+                                       lldb::offset_t data_offset,
+                                       size_t num_instructions,
+                                       bool append,
+                                       bool data_from_file)
 {
     if (!append)
         m_instruction_list.Clear();
@@ -493,6 +664,7 @@ DisassemblerLLVMC::DecodeInstructions (c
     if (!IsValid())
         return 0;
     
+    m_data_from_file = data_from_file;
     uint32_t data_cursor = data_offset;
     const size_t data_byte_size = data.GetByteSize();
     uint32_t instructions_parsed = 0;
@@ -503,7 +675,7 @@ DisassemblerLLVMC::DecodeInstructions (c
         
         AddressClass address_class = eAddressClassCode;
         
-        if (m_alternate_disasm_context)
+        if (m_alternate_disasm_ap.get() != NULL)
             address_class = inst_addr.GetAddressClass ();
         
         InstructionSP inst_sp(new InstructionLLVMC(*this,
@@ -531,7 +703,7 @@ void
 DisassemblerLLVMC::Initialize()
 {
     PluginManager::RegisterPlugin (GetPluginNameStatic(),
-                                   GetPluginDescriptionStatic(),
+                                   "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.",
                                    CreateInstance);
     
     llvm::InitializeAllTargetInfos();
@@ -547,16 +719,11 @@ DisassemblerLLVMC::Terminate()
 }
 
 
-const char *
+ConstString
 DisassemblerLLVMC::GetPluginNameStatic()
 {
-    return "llvm-mc";
-}
-
-const char *
-DisassemblerLLVMC::GetPluginDescriptionStatic()
-{
-    return "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.";
+    static ConstString g_name("llvm-mc");
+    return g_name;
 }
 
 int DisassemblerLLVMC::OpInfoCallback (void *disassembler,
@@ -612,36 +779,33 @@ const char *DisassemblerLLVMC::SymbolLoo
         if (m_exe_ctx && m_inst)
         {        
             //std::string remove_this_prior_to_checkin;
-            Address reference_address;
-            
             Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
-            
-            if (target && !target->GetSectionLoadList().IsEmpty())
-                target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
-            else
+            Address value_so_addr;
+            if (m_inst->UsingFileAddress())
             {
                 ModuleSP module_sp(m_inst->GetAddress().GetModule());
                 if (module_sp)
-                    module_sp->ResolveFileAddress(value, reference_address);
+                    module_sp->ResolveFileAddress(value, value_so_addr);
             }
-                
-            if (reference_address.IsValid() && reference_address.GetSection())
+            else if (target && !target->GetSectionLoadList().IsEmpty())
+            {
+                target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
+            }
+            
+            if (value_so_addr.IsValid() && value_so_addr.GetSection())
             {
                 StreamString ss;
                 
-                reference_address.Dump (&ss, 
-                                        target, 
-                                        Address::DumpStyleResolvedDescriptionNoModule, 
-                                        Address::DumpStyleSectionNameOffset);
+                value_so_addr.Dump (&ss,
+                                    target,
+                                    Address::DumpStyleResolvedDescriptionNoModule,
+                                    Address::DumpStyleSectionNameOffset);
                 
                 if (!ss.GetString().empty())
                 {
-                    //remove_this_prior_to_checkin = ss.GetString();
-                    //if (*type_ptr)
                     m_inst->AppendComment(ss.GetString());
                 }
             }
-            //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16llx, type=%llu, pc=0x%16.16llx, name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
         }
     }
 
@@ -653,15 +817,9 @@ const char *DisassemblerLLVMC::SymbolLoo
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+ConstString
 DisassemblerLLVMC::GetPluginName()
 {
-    return "DisassemblerLLVMC";
-}
-
-const char *
-DisassemblerLLVMC::GetShortPluginName()
-{
     return GetPluginNameStatic();
 }
 

Modified: lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h Thu Jun  6 19:06:43 2013
@@ -10,9 +10,23 @@
 #ifndef liblldb_DisassemblerLLVMC_h_
 #define liblldb_DisassemblerLLVMC_h_
 
+#include <string>
 
 #include "llvm-c/Disassembler.h"
 
+// Opaque references to C++ Objects in LLVM's MC.
+namespace llvm
+{
+    class MCContext;
+    class MCInst;
+    class MCInstrInfo;
+    class MCRegisterInfo;
+    class MCDisassembler;
+    class MCInstPrinter;
+    class MCAsmInfo;
+    class MCSubtargetInfo;
+}
+
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/PluginManager.h"
@@ -22,6 +36,34 @@ class InstructionLLVMC;
 
 class DisassemblerLLVMC : public lldb_private::Disassembler
 {
+    // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), and there's a bit of goo to set up and own
+    // in the MC disassembler world, I added this class to manage the actual disassemblers.
+    class LLVMCDisassembler
+    {
+    public:
+        LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner);
+        
+        ~LLVMCDisassembler();
+        
+        uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
+        uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
+        bool     CanBranch (llvm::MCInst &mc_inst);
+        bool     IsValid()
+        {
+            return m_is_valid;
+        }
+        
+    private:
+        bool                                    m_is_valid;
+        std::unique_ptr<llvm::MCContext>         m_context_ap;
+        std::unique_ptr<llvm::MCAsmInfo>         m_asm_info_ap;
+        std::unique_ptr<llvm::MCSubtargetInfo>   m_subtarget_info_ap;
+        std::unique_ptr<llvm::MCInstrInfo>       m_instr_info_ap;
+        std::unique_ptr<llvm::MCRegisterInfo>    m_reg_info_ap;
+        std::unique_ptr<llvm::MCInstPrinter>     m_instr_printer_ap;
+        std::unique_ptr<llvm::MCDisassembler>    m_disasm_ap;
+    };
+
 public:
     //------------------------------------------------------------------
     // Static Functions
@@ -32,47 +74,44 @@ public:
     static void
     Terminate();
     
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic();
     
-    static const char *
-    GetPluginDescriptionStatic();
-    
     static lldb_private::Disassembler *
-    CreateInstance(const lldb_private::ArchSpec &arch);
-    
-    
-    DisassemblerLLVMC(const lldb_private::ArchSpec &arch);
+    CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
+        
+    DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
     
     virtual
     ~DisassemblerLLVMC();
     
-    size_t
+    virtual size_t
     DecodeInstructions (const lldb_private::Address &base_addr,
                         const lldb_private::DataExtractor& data,
-                        uint32_t data_offset,
-                        uint32_t num_instructions,
-                        bool append);
+                        lldb::offset_t data_offset,
+                        size_t num_instructions,
+                        bool append,
+                        bool data_from_file);
     
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
     
-    virtual const char *
-    GetShortPluginName();
-    
     virtual uint32_t
     GetPluginVersion();
     
 protected:
     friend class InstructionLLVMC;
     
+    virtual bool
+    FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
+    
     bool
     IsValid()
     {
-        return (m_disasm_context != NULL);
+        return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
     }
     
     int OpInfo(uint64_t PC,
@@ -117,8 +156,10 @@ protected:
     const lldb_private::ExecutionContext *m_exe_ctx;
     InstructionLLVMC *m_inst;
     lldb_private::Mutex m_mutex;
-    ::LLVMDisasmContextRef m_disasm_context;
-    ::LLVMDisasmContextRef m_alternate_disasm_context;
+    bool m_data_from_file;
+    
+    std::unique_ptr<LLVMCDisassembler> m_disasm_ap;
+    std::unique_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
 };
 
 #endif  // liblldb_DisassemblerLLVM_h_

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp Thu Jun  6 19:06:43 2013
@@ -7,21 +7,26 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
+
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
 #include "lldb/Core/DataBuffer.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
+#include "lldb/Host/Symbols.h"
 #include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlanRunToAddress.h"
-#include "lldb/Target/StackFrame.h"
+#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
 
 #include "DynamicLoaderDarwinKernel.h"
 
@@ -36,10 +41,91 @@
 using namespace lldb;
 using namespace lldb_private;
 
-/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
-/// I am putting it here so I can invoke it in the Trampoline code here, but
-/// it should be moved to the ObjC Runtime support when it is set up.
+// Progressively greater amounts of scanning we will allow
+// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
+// so a setting is needed that can completely disable the KASLR scans.
+
+enum KASLRScanType
+{
+    eKASLRScanNone = 0,         // No reading into the inferior at all
+    eKASLRScanLowgloAddresses,  // Check one word of memory for a possible kernel addr, then see if a kernel is there
+    eKASLRScanNearPC,           // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
+    eKASLRScanExhaustiveScan    // Scan through the entire possible kernel address range looking for a kernel
+};
+
+OptionEnumValueElement
+g_kaslr_kernel_scan_enum_values[] =
+{
+    { eKASLRScanNone,            "none",            "Do not read memory looking for a Darwin kernel when attaching." },
+    { eKASLRScanLowgloAddresses, "basic",           "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
+    { eKASLRScanNearPC,          "fast-scan",       "Scan near the pc value on attach to find the Darwin kernel's load address."},
+    { eKASLRScanExhaustiveScan,  "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
+    { 0, NULL, NULL }
+};
+
+static PropertyDefinition
+g_properties[] =
+{
+    { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
+    { "scan-type",   OptionValue::eTypeEnum,    true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
+    {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
+};
+
+enum {
+    ePropertyLoadKexts,
+    ePropertyScanType
+};
+
+class DynamicLoaderDarwinKernelProperties : public Properties
+{
+public:
+    
+    static ConstString &
+    GetSettingName ()
+    {
+        static ConstString g_setting_name("darwin-kernel");
+        return g_setting_name;
+    }
+
+    DynamicLoaderDarwinKernelProperties() :
+        Properties ()
+    {
+        m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
+        m_collection_sp->Initialize(g_properties);
+    }
+
+    virtual
+    ~DynamicLoaderDarwinKernelProperties()
+    {
+    }
+
+    bool
+    GetLoadKexts() const
+    {
+        const uint32_t idx = ePropertyLoadKexts;
+        return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+    }
+
+    KASLRScanType
+    GetScanType() const
+    {
+        const uint32_t idx = ePropertyScanType;
+        return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+    }
+
 
+};
+
+typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties> DynamicLoaderDarwinKernelPropertiesSP;
+
+static const DynamicLoaderDarwinKernelPropertiesSP &
+GetGlobalProperties()
+{
+    static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
+    if (!g_settings_sp)
+        g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ());
+    return g_settings_sp;
+}
 
 //----------------------------------------------------------------------
 // Create an instance of this class. This function is filled into
@@ -49,57 +135,339 @@ using namespace lldb_private;
 DynamicLoader *
 DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
 {
-    bool create = force;
-    if (!create)
+    if (!force)
     {
+        // If the user provided an executable binary and it is not a kernel,
+        // this plugin should not create an instance.
         Module* exe_module = process->GetTarget().GetExecutableModulePointer();
         if (exe_module)
         {
             ObjectFile *object_file = exe_module->GetObjectFile();
             if (object_file)
             {
-                create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
+                if (object_file->GetStrata() != ObjectFile::eStrataKernel)
+                {
+                    return NULL;
+                }
             }
         }
-        
-        if (create)
+
+        // If the target's architecture does not look like an Apple environment,
+        // this plugin should not create an instance.
+        const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
+        switch (triple_ref.getOS())
         {
-            const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
-            switch (triple_ref.getOS())
-            {
-                case llvm::Triple::Darwin:
-                case llvm::Triple::MacOSX:
-                case llvm::Triple::IOS:
-                    create = triple_ref.getVendor() == llvm::Triple::Apple;
-                    break;
-                default:
-                    create = false;
-                    break;
-            }
+            case llvm::Triple::Darwin:
+            case llvm::Triple::MacOSX:
+            case llvm::Triple::IOS:
+                if (triple_ref.getVendor() != llvm::Triple::Apple)
+                {
+                   return NULL;
+                }
+                break;
+            // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
+            case llvm::Triple::UnknownOS:
+                break;
+            default:
+                return NULL;
+                break;
         }
     }
-    
-    if (create)
+
+    // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.  
+    // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
+
+    addr_t kernel_load_address = SearchForDarwinKernel (process);
+    if (kernel_load_address != LLDB_INVALID_ADDRESS)
     {
         process->SetCanJIT(false);
-        return new DynamicLoaderDarwinKernel (process);
+        return new DynamicLoaderDarwinKernel (process, kernel_load_address);
     }
     return NULL;
 }
 
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
+{
+    addr_t kernel_load_address = process->GetImageInfoAddress();
+    if (kernel_load_address == LLDB_INVALID_ADDRESS)
+    {
+        kernel_load_address = SearchForKernelAtSameLoadAddr (process);
+        if (kernel_load_address == LLDB_INVALID_ADDRESS)
+        {
+            kernel_load_address = SearchForKernelWithDebugHints (process);
+            if (kernel_load_address == LLDB_INVALID_ADDRESS)
+            {
+                kernel_load_address = SearchForKernelNearPC (process);
+                if (kernel_load_address == LLDB_INVALID_ADDRESS)
+                {
+                    kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
+                }
+            }
+        }
+    }
+    return kernel_load_address;
+}
+
+//----------------------------------------------------------------------
+// Check if the kernel binary is loaded in memory without a slide.
+// First verify that the ExecutableModule is a kernel before we proceed.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
+{
+    Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+    if (exe_module == NULL)
+        return LLDB_INVALID_ADDRESS;
+
+    ObjectFile *exe_objfile = exe_module->GetObjectFile();
+    if (exe_objfile == NULL)
+        return LLDB_INVALID_ADDRESS;
+
+    if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
+        return LLDB_INVALID_ADDRESS;
+
+    if (!exe_objfile->GetHeaderAddress().IsValid())
+        return LLDB_INVALID_ADDRESS;
+
+    if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
+        return exe_objfile->GetHeaderAddress().GetFileAddress();
+
+    return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the debug flag is included in the boot-args nvram setting, the kernel's load address
+// will be noted in the lowglo page at a fixed address
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
+{
+    if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
+        return LLDB_INVALID_ADDRESS;
+
+    Error read_err;
+    addr_t addr = LLDB_INVALID_ADDRESS;
+    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+    {
+        addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
+    }
+    else
+    {
+        addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
+    }
+
+    if (addr == 0)
+        addr = LLDB_INVALID_ADDRESS;
+
+    if (addr != LLDB_INVALID_ADDRESS)
+    {
+        if (CheckForKernelImageAtAddress (addr, process).IsValid())
+            return addr;
+    }
+
+    return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the kernel is currently executing when lldb attaches, and we don't have
+// a better way of finding the kernel's load address, try searching backwards
+// from the current pc value looking for the kernel's Mach header in memory.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
+{
+    if (GetGlobalProperties()->GetScanType() == eKASLRScanNone 
+        || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
+    {
+        return LLDB_INVALID_ADDRESS;
+    }
+
+    ThreadSP thread = process->GetThreadList().GetSelectedThread ();
+    if (thread.get() == NULL)
+        return LLDB_INVALID_ADDRESS;
+    addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
+
+    if (pc == LLDB_INVALID_ADDRESS)
+        return LLDB_INVALID_ADDRESS;
+
+    addr_t kernel_range_low;
+    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+    {
+        kernel_range_low = 1ULL << 63;
+    }
+    else
+    {
+        kernel_range_low = 1ULL << 31;
+    }
+
+    // Outside the normal kernel address range, this is probably userland code running right now
+    if (pc < kernel_range_low)
+        return LLDB_INVALID_ADDRESS;
+
+    // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus 
+    // an offset of one page (0x1000) or two, depending on the device.
+
+    // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
+    addr_t addr = pc & ~0xfffff;
+
+    int i = 0;
+    while (i < 32 && pc >= kernel_range_low)
+    {
+        if (CheckForKernelImageAtAddress (addr, process).IsValid())
+            return addr;
+        if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+            return addr + 0x1000;
+        if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+            return addr + 0x2000;
+        i++;
+        addr -= 0x100000;
+    }
+
+    return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Scan through the valid address range for a kernel binary.
+// This is uselessly slow in 64-bit environments so we don't even try it.
+// This scan is not enabled by default even for 32-bit targets.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
+{
+    if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
+    {
+        return LLDB_INVALID_ADDRESS;
+    }
+
+    addr_t kernel_range_low, kernel_range_high;
+    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+    {
+        kernel_range_low = 1ULL << 63;
+        kernel_range_high = UINT64_MAX;
+    }
+    else
+    {
+        kernel_range_low = 1ULL << 31;
+        kernel_range_high = UINT32_MAX;
+    }
+
+    // Stepping through memory at one-megabyte resolution looking for a kernel
+    // rarely works (fast enough) with a 64-bit address space -- for now, let's
+    // not even bother.  We may be attaching to something which *isn't* a kernel
+    // and we don't want to spin for minutes on-end looking for a kernel.
+    if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+        return LLDB_INVALID_ADDRESS;
+
+    addr_t addr = kernel_range_low;
+
+    while (addr >= kernel_range_low && addr < kernel_range_high)
+    {
+        if (CheckForKernelImageAtAddress (addr, process).IsValid())
+            return addr;
+        if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+            return addr + 0x1000;
+        if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+            return addr + 0x2000;
+        addr += 0x100000;
+    }
+    return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Given an address in memory, look to see if there is a kernel image at that
+// address.  
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
+//----------------------------------------------------------------------
+lldb_private::UUID
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
+{
+    if (addr == LLDB_INVALID_ADDRESS)
+        return UUID();
+
+    // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
+    // (the first field of the mach_header/mach_header_64 struct).
+
+    Error read_error;
+    uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
+    if (result != llvm::MachO::HeaderMagic64
+        && result != llvm::MachO::HeaderMagic32
+        && result != llvm::MachO::HeaderMagic32Swapped 
+        && result != llvm::MachO::HeaderMagic64Swapped)
+    {
+        return UUID();
+    }
+
+    // Read the mach header and see whether it looks like a kernel
+    llvm::MachO::mach_header header;
+    if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
+        return UUID();
+
+    if (header.magic == llvm::MachO::HeaderMagic32Swapped ||
+        header.magic == llvm::MachO::HeaderMagic64Swapped)
+    {
+        header.magic        = llvm::ByteSwap_32(header.magic);
+        header.cputype      = llvm::ByteSwap_32(header.cputype);
+        header.cpusubtype   = llvm::ByteSwap_32(header.cpusubtype);
+        header.filetype     = llvm::ByteSwap_32(header.filetype);
+        header.ncmds        = llvm::ByteSwap_32(header.ncmds);
+        header.sizeofcmds   = llvm::ByteSwap_32(header.sizeofcmds);
+        header.flags        = llvm::ByteSwap_32(header.flags);
+    }
+
+    // A kernel is an executable which does not have the dynamic link object flag set.
+    if (header.filetype == llvm::MachO::HeaderFileTypeExecutable
+        && (header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
+    {
+        // Create a full module to get the UUID
+        ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
+        if (!memory_module_sp.get())
+            return UUID();
+
+        ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+        if (exe_objfile == NULL)
+            return UUID();
+
+        if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+        {
+            ArchSpec kernel_arch (eArchTypeMachO, header.cputype, header.cpusubtype);
+            if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
+            {
+                process->GetTarget().SetArchitecture (kernel_arch);
+            }
+            return memory_module_sp->GetUUID();
+        }
+    }
+
+    return UUID();
+}
+
 //----------------------------------------------------------------------
 // Constructor
 //----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
     DynamicLoader(process),
+    m_kernel_load_address (kernel_addr),
     m_kernel(),
     m_kext_summary_header_ptr_addr (),
     m_kext_summary_header_addr (),
     m_kext_summary_header (),
-    m_kext_summaries(),
+    m_known_kexts (),
     m_mutex(Mutex::eMutexTypeRecursive),
     m_break_id (LLDB_INVALID_BREAK_ID)
 {
+    PlatformSP platform_sp(Platform::FindPlugin (process, PlatformDarwinKernel::GetPluginNameStatic ()));
+    // Only select the darwin-kernel Platform if we've been asked to load kexts.
+    // It can take some time to scan over all of the kext info.plists and that
+    // shouldn't be done if kext loading is explicitly disabled.
+    if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
+    {
+        process->GetTarget().SetPlatform (platform_sp);
+    }
 }
 
 //----------------------------------------------------------------------
@@ -156,152 +524,480 @@ DynamicLoaderDarwinKernel::Clear (bool c
 
     if (clear_process)
         m_process = NULL;
-    m_kernel.Clear(false);
+    m_kernel.Clear();
+    m_known_kexts.clear();
     m_kext_summary_header_ptr_addr.Clear();
     m_kext_summary_header_addr.Clear();
-    m_kext_summaries.clear();
     m_break_id = LLDB_INVALID_BREAK_ID;
 }
 
 
 bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
 {
     if (IsLoaded())
         return true;
 
-    if (module_sp)
+    if (m_module_sp)
     {
         bool changed = false;
-        if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
-            load_process_stop_id = process->GetStopID();
+        if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
+            m_load_process_stop_id = process->GetStopID();
     }
     return false;
 }
 
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
+{
+    m_module_sp = module_sp;
+    if (module_sp.get() && module_sp->GetObjectFile())
+    {
+        if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+            && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+        {
+            m_kernel_image = true;
+        }
+        else
+        {
+            m_kernel_image = false;
+        }
+    }
+}
+
+ModuleSP
+DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
+{
+    return m_module_sp;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
+{ 
+    m_load_address = load_addr;
+}
+
+addr_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
+{ 
+    return m_load_address;
+}
+
+uint64_t 
+DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
+{
+    return m_size;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
+{
+    m_size = size;
+}
+
+uint32_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
+{
+    return m_load_process_stop_id;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
+{
+    m_load_process_stop_id = stop_id;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
+{
+    if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
+    {
+        if (m_uuid == rhs.GetUUID())
+        {
+            return true;
+        }
+        return false;
+    }
+
+    if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
+        return true;
+
+    return false;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
+{
+    m_name = name;
+}
+
+std::string
+DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
+{
+    return m_name;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
+{
+    m_uuid = uuid;
+}
+
+UUID
+DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
+{
+    return m_uuid;
+}
+
+// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
+// Module at that address.  Require that the MemoryModule have a matching UUID and detect
+// if this MemoryModule is a kernel or a kext.
+//
+// Returns true if m_memory_module_sp is now set to a valid Module.  
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
+{
+    if (m_memory_module_sp.get() != NULL)
+        return true;
+    if (m_load_address == LLDB_INVALID_ADDRESS)
+        return false;
+
+    FileSpec file_spec;
+    file_spec.SetFile (m_name.c_str(), false);
+
+    ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
+
+    if (memory_module_sp.get() == NULL)
+        return false;
+
+    bool is_kernel = false;
+    if (memory_module_sp->GetObjectFile())
+    {
+        if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+            && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+        {
+            is_kernel = true;
+        }
+        else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
+        {
+            is_kernel = false;
+        }
+    }
+
+    // If this is a kext, and the kernel specified what UUID we should find at this 
+    // load address, require that the memory module have a matching UUID or something 
+    // has gone wrong and we should discard it.
+    if (m_uuid.IsValid())
+    {
+        if (m_uuid != memory_module_sp->GetUUID())
+        {
+            return false;
+        }
+    }
+
+    // If the in-memory Module has a UUID, let's use that.
+    if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
+    {
+        m_uuid = memory_module_sp->GetUUID();
+    }
+
+    m_memory_module_sp = memory_module_sp;
+    m_kernel_image = is_kernel;
+    if (is_kernel)
+    {
+        if (memory_module_sp->GetArchitecture().IsValid())
+        {
+            process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+        }
+        if (m_uuid.IsValid())
+        {
+            Module* exe_module = process->GetTarget().GetExecutableModulePointer();
+            if (exe_module && exe_module->GetUUID().IsValid())
+            {
+                if (m_uuid != exe_module->GetUUID())
+                {
+                    Stream *s = &process->GetTarget().GetDebugger().GetOutputStream();
+                    if (s)
+                    {
+                        s->Printf ("warning: Host-side kernel file has Mach-O UUID of %s but remote kernel has a UUID of %s -- a mismatched kernel file will result in a poor debugger experience.\n", 
+                                   exe_module->GetUUID().GetAsString().c_str(),
+                                   m_uuid.GetAsString().c_str());
+                        s->Flush ();
+                    }
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
+{
+    return m_kernel_image == true;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel) 
+{
+    m_kernel_image = is_kernel;
+}
+
 bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
 {
     if (IsLoaded())
         return true;
 
-    bool uuid_is_valid = uuid.IsValid();
 
     Target &target = process->GetTarget();
-    ModuleSP memory_module_sp;
-    // Use the memory module as the module if we have one...
-    if (address != LLDB_INVALID_ADDRESS)
-    {
-        FileSpec file_spec;
-        if (module_sp)
-            file_spec = module_sp->GetFileSpec();
-        else
-            file_spec.SetFile (name, false);
-        
-        memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
-        if (memory_module_sp && !uuid_is_valid)
+
+    // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
+    // have the correct segment load addresses.
+    if (!ReadMemoryModule (process))
+    {
+        return false;
+    }
+
+    bool uuid_is_valid = m_uuid.IsValid();
+
+    if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
+    {
+        Stream *s = &target.GetDebugger().GetOutputStream();
+        if (s)
         {
-            uuid = memory_module_sp->GetUUID();
-            uuid_is_valid = uuid.IsValid();
+            s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
+            s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
         }
     }
 
-    if (!module_sp)
+    if (!m_module_sp)
     {
-        if (uuid_is_valid)
+        // See if the kext has already been loaded into the target, probably by the user doing target modules add.
+        const ModuleList &target_images = target.GetImages();
+        m_module_sp = target_images.FindModule(m_uuid);
+
+        // Search for the kext on the local filesystem via the UUID
+        if (!m_module_sp && uuid_is_valid)
         {
-            ModuleList &target_images = target.GetImages();
-            module_sp = target_images.FindModule(uuid);
-            
-            if (!module_sp)
+            ModuleSpec module_spec;
+            module_spec.GetUUID() = m_uuid;
+            module_spec.GetArchitecture() = target.GetArchitecture();
+
+            // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
+            // This will force a clal to 
+            if (IsKernel())
+            {
+                if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
+                {
+                    if (module_spec.GetFileSpec().Exists())
+                    {
+                        m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
+                        if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
+                        {
+                            ModuleList loaded_module_list;
+                            loaded_module_list.Append (m_module_sp);
+                            target.ModulesDidLoad (loaded_module_list);
+                        }
+                    }
+                }
+            }
+
+            // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set 
+            // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
+            // to find it.
+            PlatformSP platform_sp (target.GetPlatform());
+            if (platform_sp)
+            {
+                ConstString platform_name (platform_sp->GetPluginName());
+                static ConstString g_platform_name (PlatformDarwinKernel::GetPluginNameStatic());
+                if (platform_name == g_platform_name)
+                {
+                    ModuleSpec kext_bundle_module_spec(module_spec);
+                    FileSpec kext_filespec(m_name.c_str(), false);
+                    kext_bundle_module_spec.GetFileSpec() = kext_filespec;
+                    platform_sp->GetSharedModule (kext_bundle_module_spec, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
+                }
+            }
+
+            // Ask the Target to find this file on the local system, if possible.
+            // This will search in the list of currently-loaded files, look in the 
+            // standard search paths on the system, and on a Mac it will try calling
+            // the DebugSymbols framework with the UUID to find the binary via its
+            // search methods.
+            if (!m_module_sp)
+            {
+                m_module_sp = target.GetSharedModule (module_spec);
+            }
+
+            if (IsKernel() && !m_module_sp)
+            {
+                Stream *s = &target.GetDebugger().GetOutputStream();
+                if (s)
+                {
+                    s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
+                }
+            }
+        }
+
+        // If we managed to find a module, append it to the target's list of images.
+        // If we also have a memory module, require that they have matching UUIDs
+        if (m_module_sp)
+        {
+            bool uuid_match_ok = true;
+            if (m_memory_module_sp)
             {
-                ModuleSpec module_spec;
-                module_spec.GetUUID() = uuid;
-                module_sp = target.GetSharedModule (module_spec);
+                if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
+                {
+                    uuid_match_ok = false;
+                }
+            }
+            if (uuid_match_ok)
+            {
+                target.GetImages().AppendIfNeeded(m_module_sp);
+                if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
+                {
+                    target.SetExecutableModule (m_module_sp, false);
+                }
             }
         }
     }
     
+    if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
+    {
+        Stream *s = &target.GetDebugger().GetOutputStream();
+        if (s)
+        {
+            s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n", 
+                       m_name.c_str(), m_uuid.GetAsString().c_str());
+        }
+    }
+
+    static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
 
-    if (memory_module_sp)
+    if (m_memory_module_sp && m_module_sp)
     {
-        // Someone already supplied a file, make sure it is the right one.
-        if (module_sp)
+        if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
         {
-            if (module_sp->GetUUID() == memory_module_sp->GetUUID())
+            ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+            ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
+            
+            if (memory_object_file && ondisk_object_file)
             {
-                ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
-                ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
-                if (memory_object_file && ondisk_object_file)
+                // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
+                const bool ignore_linkedit = !IsKernel ();
+                
+                SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
+                SectionList *memory_section_list = memory_object_file->GetSectionList ();
+                if (memory_section_list && ondisk_section_list)
                 {
-                    SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
-                    SectionList *memory_section_list = memory_object_file->GetSectionList ();
-                    if (memory_section_list && ondisk_section_list)
+                    const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
+                    // There may be CTF sections in the memory image so we can't
+                    // always just compare the number of sections (which are actually
+                    // segments in mach-o parlance)
+                    uint32_t sect_idx = 0;
+                    
+                    // Use the memory_module's addresses for each section to set the 
+                    // file module's load address as appropriate.  We don't want to use
+                    // a single slide value for the entire kext - different segments may
+                    // be slid different amounts by the kext loader.
+
+                    uint32_t num_sections_loaded = 0;
+                    for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
                     {
-                        const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
-                        // There may be CTF sections in the memory image so we can't
-                        // always just compare the number of sections (which are actually
-                        // segments in mach-o parlance)
-                        uint32_t sect_idx = 0;
-                        
-                        
-                        // We now iterate through all sections in the file module 
-                        // and look to see if the memory module has a load address
-                        // for that section.
-                        uint32_t num_sections_loaded = 0;
-                        for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
+                        SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
+                        if (ondisk_section_sp)
                         {
-                            SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
-                            if (ondisk_section_sp)
+                            // Don't ever load __LINKEDIT as it may or may not be actually
+                            // mapped into memory and there is no current way to tell.
+                            // I filed rdar://problem/12851706 to track being able to tell
+                            // if the __LINKEDIT is actually mapped, but until then, we need
+                            // to not load the __LINKEDIT
+                            if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
+                                continue;
+
+                            const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
+                            if (memory_section)
                             {
-                                const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
-                                if (memory_section)
-                                {
-                                    target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
-                                    ++num_sections_loaded;
-                                }
+                                target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
+                                ++num_sections_loaded;
                             }
                         }
-                        if (num_sections_loaded > 0)
-                            load_process_stop_id = process->GetStopID();
-                        else
-                            module_sp.reset(); // No sections were loaded
                     }
+                    if (num_sections_loaded > 0)
+                        m_load_process_stop_id = process->GetStopID();
                     else
-                        module_sp.reset(); // One or both section lists
+                        m_module_sp.reset(); // No sections were loaded
                 }
                 else
-                    module_sp.reset(); // One or both object files missing
+                    m_module_sp.reset(); // One or both section lists
             }
             else
-                module_sp.reset(); // UUID mismatch
-        }
-        
-        // Use the memory module as the module if we didn't like the file
-        // module we either found or were supplied with
-        if (!module_sp)
-        {
-            module_sp = memory_module_sp;
-            // Load the memory image in the target as all adresses are already correct
-            bool changed = false;
-            target.GetImages().Append (memory_module_sp);
-            if (module_sp->SetLoadAddress (target, 0, changed))
-                load_process_stop_id = process->GetStopID();
+                m_module_sp.reset(); // One or both object files missing
         }
+        else
+            m_module_sp.reset(); // UUID mismatch
     }
+
     bool is_loaded = IsLoaded();
     
-    if (so_address.IsValid())
+    if (is_loaded && m_module_sp && IsKernel())
     {
-        if (is_loaded)
-            so_address.SetLoadAddress (address, &target);
-        else
-            target.GetImages().ResolveFileAddress (address, so_address);
-
+        Stream *s = &target.GetDebugger().GetOutputStream();
+        if (s)
+        {
+            ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+            if (kernel_object_file)
+            {
+                addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
+                if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
+                {
+                    s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
+                }
+            }
+            {
+                s->Printf ("Loaded kernel file %s\n",
+                           m_module_sp->GetFileSpec().GetPath().c_str());
+            }
+            s->Flush ();
+        }
     }
     return is_loaded;
 }
 
+uint32_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
+{
+    if (m_memory_module_sp)
+        return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
+    if (m_module_sp)
+        return m_module_sp->GetArchitecture().GetAddressByteSize();
+    return 0;
+}
+
+lldb::ByteOrder
+DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
+{
+    if (m_memory_module_sp)
+        return m_memory_module_sp->GetArchitecture().GetByteOrder();
+    if (m_module_sp)
+        return m_module_sp->GetArchitecture().GetByteOrder();
+    return lldb::endian::InlHostByteOrder();
+}
+
+lldb_private::ArchSpec
+DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
+{
+    if (m_memory_module_sp)
+        return m_memory_module_sp->GetArchitecture();
+    if (m_module_sp)
+        return m_module_sp->GetArchitecture();
+    return lldb_private::ArchSpec ();
+}
+
+
 //----------------------------------------------------------------------
 // Load the kernel module and initialize the "m_kernel" member. Return
 // true _only_ if the kernel is loaded the first time through (subsequent
@@ -313,24 +1009,52 @@ DynamicLoaderDarwinKernel::LoadKernelMod
 {
     if (!m_kext_summary_header_ptr_addr.IsValid())
     {
-        m_kernel.Clear(false);
-        m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
-        strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name));
-        if (m_kernel.address == LLDB_INVALID_ADDRESS)
+        m_kernel.Clear();
+        m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
+        m_kernel.SetIsKernel(true);
+
+        ConstString kernel_name("mach_kernel");
+        if (m_kernel.GetModule().get()
+            && m_kernel.GetModule()->GetObjectFile()
+            && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
+        {
+            kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
+        }
+        m_kernel.SetName (kernel_name.AsCString());
+
+        if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
         {
-            m_kernel.address = m_process->GetImageInfoAddress ();
-            if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
+            m_kernel.SetLoadAddress(m_kernel_load_address);
+            if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
             {
                 // We didn't get a hint from the process, so we will
                 // try the kernel at the address that it exists at in
                 // the file if we have one
-                ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
+                ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
                 if (kernel_object_file)
-                    m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress();
+                {
+                    addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
+                    addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
+                    if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
+                    {
+                        m_kernel.SetLoadAddress (load_address);
+                        if (load_address != file_address)
+                        {
+                            // Don't accidentally relocate the kernel to the File address -- 
+                            // the Load address has already been set to its actual in-memory address.  
+                            // Mark it as IsLoaded.
+                            m_kernel.SetProcessStopId (m_process->GetStopID());
+                        }
+                    }
+                    else
+                    {
+                        m_kernel.SetLoadAddress(file_address);
+                    }
+                }
             }
         }
         
-        if (m_kernel.address != LLDB_INVALID_ADDRESS)
+        if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
         {
             if (!m_kernel.LoadImageUsingMemoryModule (m_process))
             {
@@ -338,10 +1062,10 @@ DynamicLoaderDarwinKernel::LoadKernelMod
             }
         }
 
-        if (m_kernel.IsLoaded())
+        if (m_kernel.IsLoaded() && m_kernel.GetModule())
         {
             static ConstString kext_summary_symbol ("gLoadedKextSummaries");
-            const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
+            const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
             if (symbol)
             {
                 m_kext_summary_header_ptr_addr = symbol->GetAddress();
@@ -351,7 +1075,7 @@ DynamicLoaderDarwinKernel::LoadKernelMod
         }
         else
         {
-            m_kernel.Clear(false);
+            m_kernel.Clear();
         }
     }
 }
@@ -376,14 +1100,14 @@ DynamicLoaderDarwinKernel::BreakpointHit
                                           user_id_t break_id, 
                                           user_id_t break_loc_id)
 {    
-    LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
         log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
 
     ReadAllKextSummaries ();
     
     if (log)
-        PutToLog(log.get());
+        PutToLog(log);
 
     return GetStopWhenImagesChange();
 }
@@ -396,7 +1120,6 @@ DynamicLoaderDarwinKernel::ReadKextSumma
 
     // the all image infos is already valid for this process stop ID
 
-    m_kext_summaries.clear();
     if (m_kext_summary_header_ptr_addr.IsValid())
     {
         const uint32_t addr_size = m_kernel.GetAddressByteSize ();
@@ -420,7 +1143,7 @@ DynamicLoaderDarwinKernel::ReadKextSumma
                 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
                 if (bytes_read == count)
                 {
-                    uint32_t offset = 0;
+                    lldb::offset_t offset = 0;
                     m_kext_summary_header.version = data.GetU32(&offset);
                     if (m_kext_summary_header.version >= 2)
                     {
@@ -441,96 +1164,194 @@ DynamicLoaderDarwinKernel::ReadKextSumma
     return false;
 }
 
+// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
+// and we need to figure out what kexts have been added or removed.
+// Read the kext summaries from the inferior kernel memory, compare them against the
+// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
+// inferior.
 
 bool
-DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 
-                                               uint32_t count)
+DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
 {
-    OSKextLoadedKextSummary::collection kext_summaries;
-    LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    KextImageInfo::collection kext_summaries;
+    Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
-        log->Printf ("Adding %d modules.\n", count);
+        log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
         
     Mutex::Locker locker(m_mutex);
 
     if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
         return false;
 
-    Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
-    for (uint32_t i = 0; i < count; i++)
+    // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no 
+    // kext loading, don't print any messages about kexts & don't try to read them.
+    const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
+
+    // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
+    // we just found out about from ReadKextSummaries are marked as "add".
+    std::vector<bool> to_be_removed(m_known_kexts.size(), true);
+    std::vector<bool> to_be_added(count, true);
+
+    int number_of_new_kexts_being_added = 0;
+    int number_of_old_kexts_being_removed = m_known_kexts.size();
+
+    const uint32_t new_kexts_size = kext_summaries.size();
+    const uint32_t old_kexts_size = m_known_kexts.size();
+
+    // The m_known_kexts vector may have entries that have been Cleared,
+    // or are a kernel.  
+    for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
     {
-        if (s)
+        bool ignore = false;
+        KextImageInfo &image_info = m_known_kexts[old_kext];
+        if (image_info.IsKernel())
         {
-            const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes();
-            if (u)
-            {
-                s->Printf("Loading kext: %2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X 0x%16.16llx \"%s\"...",
-                          u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
-                          u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
-                          kext_summaries[i].address, kext_summaries[i].name);
-            }   
-            else
-            {
-                s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name);
-            }
+            ignore = true;
+        }
+        else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
+        {
+            ignore = true;
         }
-        
-        if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
-            kext_summaries[i].LoadImageAtFileAddress (m_process);
 
-        if (s)
+        if (ignore)
+        {
+            number_of_old_kexts_being_removed--;
+            to_be_removed[old_kext] = false;
+        }
+    }
+
+    // Scan over the list of kexts we just read from the kernel, note those that
+    // need to be added and those already loaded.
+    for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
+    {
+        bool add_this_one = true;
+        for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
         {
-            if (kext_summaries[i].module_sp)
+            if (m_known_kexts[old_kext] == kext_summaries[new_kext])
             {
-                if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory())
-                    s->Printf("\n  found kext: %s/%s\n", 
-                              kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
-                              kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
-                else
-                    s->Printf("\n  found kext: %s\n", 
-                              kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
+                // We already have this kext, don't re-load it.
+                to_be_added[new_kext] = false;
+                // This kext is still present, do not remove it.
+                to_be_removed[old_kext] = false;
+
+                number_of_old_kexts_being_removed--;
+                add_this_one = false;
+                break;
             }
-            else
-                s->Printf (" failed to locate/load.\n");
         }
-            
-        if (log)
-            kext_summaries[i].PutToLog (log.get());
+        if (add_this_one)
+        {
+            number_of_new_kexts_being_added++;
+        }
     }
-    bool return_value = AddModulesUsingImageInfos (kext_summaries);
-    return return_value;
-}
 
-// Adds the modules in image_infos to m_kext_summaries.  
-// NB don't call this passing in m_kext_summaries.
+    if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
+        return true;
 
-bool
-DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
-{
-    // Now add these images to the main list.
-    ModuleList loaded_module_list;
-    
-    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+    Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
+    if (s && load_kexts)
     {
-        OSKextLoadedKextSummary &image_info = image_infos[idx];
-        m_kext_summaries.push_back(image_info);
-        
-        if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
-            loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
+        if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
+        {
+            s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+        }
+        else if (number_of_new_kexts_being_added > 0)
+        {
+            s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
+        }
+        else if (number_of_old_kexts_being_removed > 0)
+        {
+            s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
+        }
     }
-    
-    if (loaded_module_list.GetSize() > 0)
+
+    if (log)
+    {
+        if (load_kexts)
+        {
+            log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+        }
+        else
+        {
+            log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+        }
+    }
+
+
+    if (number_of_new_kexts_being_added > 0)
     {
+        ModuleList loaded_module_list;
+
+        const uint32_t num_of_new_kexts = kext_summaries.size();
+        for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
+        {
+            if (to_be_added[new_kext] == true)
+            {
+                KextImageInfo &image_info = kext_summaries[new_kext];
+                if (load_kexts)
+                {
+                    if (!image_info.LoadImageUsingMemoryModule (m_process))
+                    {
+                        image_info.LoadImageAtFileAddress (m_process);
+                    }
+                }
+
+                m_known_kexts.push_back(image_info);
+
+                if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
+                    loaded_module_list.AppendIfNeeded (image_info.GetModule());
+
+                if (s && load_kexts)
+                    s->Printf (".");
+
+                if (log)
+                    kext_summaries[new_kext].PutToLog (log);
+            }
+        }
         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
     }
+
+    if (number_of_old_kexts_being_removed > 0)
+    {
+        ModuleList loaded_module_list;
+        const uint32_t num_of_old_kexts = m_known_kexts.size();
+        for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
+        {
+            ModuleList unloaded_module_list;
+            if (to_be_removed[old_kext])
+            {
+                KextImageInfo &image_info = m_known_kexts[old_kext];
+                // You can't unload the kernel.
+                if (!image_info.IsKernel())
+                {
+                    if (image_info.GetModule())
+                    {
+                        unloaded_module_list.AppendIfNeeded (image_info.GetModule());
+                    }
+                    if (s)
+                        s->Printf (".");
+                    image_info.Clear();
+                    // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
+                    // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
+                }
+            }
+            m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+        }
+    }
+
+    if (s && load_kexts)
+    {
+        s->Printf (" done.\n");
+        s->Flush ();
+    }
+
     return true;
 }
 
-
 uint32_t
 DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
                                               uint32_t image_infos_count, 
-                                              OSKextLoadedKextSummary::collection &image_infos)
+                                              KextImageInfo::collection &image_infos)
 {
     const ByteOrder endian = m_kernel.GetByteOrder();
     const uint32_t addr_size = m_kernel.GetAddressByteSize();
@@ -540,10 +1361,6 @@ DynamicLoaderDarwinKernel::ReadKextSumma
     DataBufferHeap data(count, 0);
     Error error;
     
-    Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
-
-    if (s)
-        s->Printf ("Reading %u kext summaries...\n", image_infos_count);
     const bool prefer_file_cache = false;
     const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 
                                                                  prefer_file_cache,
@@ -559,35 +1376,15 @@ DynamicLoaderDarwinKernel::ReadKextSumma
              i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 
              ++i, kext_summary_offset += m_kext_summary_header.entry_size)
         {
-            uint32_t offset = kext_summary_offset;
+            lldb::offset_t offset = kext_summary_offset;
             const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
             if (name_data == NULL)
                 break;
-            memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
-            image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
-            image_infos[i].address          = extractor.GetU64(&offset);
-            if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
-                m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
-            image_infos[i].size             = extractor.GetU64(&offset);
-            image_infos[i].version          = extractor.GetU64(&offset);
-            image_infos[i].load_tag         = extractor.GetU32(&offset);
-            image_infos[i].flags            = extractor.GetU32(&offset);
-            if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
-            {
-                image_infos[i].reference_list = extractor.GetU64(&offset);
-            }
-            else
-            {
-                image_infos[i].reference_list = 0;
-            }
-//            printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n", 
-//                    i,
-//                    KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME,  (char *)name_data, 
-//                    image_infos[i].address, 
-//                    image_infos[i].size,
-//                    image_infos[i].version,
-//                    image_infos[i].load_tag,
-//                    image_infos[i].flags);
+            image_infos[i].SetName ((const char *) name_data);
+            UUID uuid (extractor.GetData (&offset, 16), 16);
+            image_infos[i].SetUUID (uuid);
+            image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
+            image_infos[i].SetSize (extractor.GetU64(&offset));
         }
         if (i < image_infos.size())
             image_infos.resize(i);
@@ -602,8 +1399,6 @@ DynamicLoaderDarwinKernel::ReadKextSumma
 bool
 DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
 {
-    LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-    
     Mutex::Locker locker(m_mutex);
     
     if (ReadKextSummaryHeader ())
@@ -614,7 +1409,7 @@ DynamicLoaderDarwinKernel::ReadAllKextSu
             summary_addr.Slide(m_kext_summary_header.GetSize());
             if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
             {
-                m_kext_summaries.clear();
+                m_known_kexts.clear();
             }
             return true;
         }
@@ -626,13 +1421,13 @@ DynamicLoaderDarwinKernel::ReadAllKextSu
 // Dump an image info structure to the file handle provided.
 //----------------------------------------------------------------------
 void
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
+DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
 {
     if (log == NULL)
         return;
-    const uint8_t *u = (uint8_t *)uuid.GetBytes();
+    const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
 
-    if (address == LLDB_INVALID_ADDRESS)
+    if (m_load_address == LLDB_INVALID_ADDRESS)
     {
         if (u)
         {
@@ -641,26 +1436,25 @@ DynamicLoaderDarwinKernel::OSKextLoadedK
                         u[ 4], u[ 5], u[ 6], u[ 7],
                         u[ 8], u[ 9], u[10], u[11],
                         u[12], u[13], u[14], u[15],
-                        name);
+                        m_name.c_str());
         }
         else
-            log->Printf("\tname=\"%s\" (UNLOADED)", name);
+            log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
     }
     else
     {
         if (u)
         {
-            log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
-                        address, size, version, load_tag, flags, reference_list,
+            log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
+                        m_load_address, m_size, 
                         u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
                         u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
-                        name);
+                        m_name.c_str());
         }
         else
         {
-            log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"",
-                        address, address+size, version, load_tag, flags, reference_list,
-                        name);
+            log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
+                        m_load_address, m_load_address+m_size, m_name.c_str());
         }
     }
 }
@@ -676,19 +1470,19 @@ DynamicLoaderDarwinKernel::PutToLog(Log
         return;
 
     Mutex::Locker locker(m_mutex);
-    log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
+    log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
                 m_kext_summary_header_addr.GetFileAddress(),
                 m_kext_summary_header.version,
                 m_kext_summary_header.entry_size,
                 m_kext_summary_header.entry_count);
 
     size_t i;
-    const size_t count = m_kext_summaries.size();
+    const size_t count = m_known_kexts.size();
     if (count > 0)
     {
         log->PutCString("Loaded:");
         for (i = 0; i<count; i++)
-            m_kext_summaries[i].PutToLog(log);
+            m_known_kexts[i].PutToLog(log);
     }
 }
 
@@ -698,13 +1492,12 @@ DynamicLoaderDarwinKernel::PrivateInitia
     DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
     Clear(true);
     m_process = process;
-    m_process->GetTarget().GetSectionLoadList().Clear();
 }
 
 void
 DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
 {
-    if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
+    if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
     {
         DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
 
@@ -712,7 +1505,7 @@ DynamicLoaderDarwinKernel::SetNotificati
         const bool internal_bp = true;
         const LazyBool skip_prologue = eLazyBoolNo;
         FileSpecList module_spec_list;
-        module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
+        module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
         Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
                                                                   NULL,
                                                                   "OSKextLoadedKextSummariesUpdated",
@@ -753,9 +1546,6 @@ DynamicLoaderDarwinKernel::PrivateProces
     case eStateCrashed:
     case eStateSuspended:
         break;
-
-    default:
-        break;
     }
 }
 
@@ -763,7 +1553,7 @@ ThreadPlanSP
 DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
 {
     ThreadPlanSP thread_plan_sp;
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
         log->Printf ("Could not find symbol for step through.");
     return thread_plan_sp;
@@ -782,7 +1572,8 @@ DynamicLoaderDarwinKernel::Initialize()
 {
     PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                    GetPluginDescriptionStatic(),
-                                   CreateInstance);
+                                   CreateInstance,
+                                   DebuggerInitialize);
 }
 
 void
@@ -791,11 +1582,24 @@ DynamicLoaderDarwinKernel::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+void
+DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
+{
+    if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
+    {
+        const bool is_global_setting = true;
+        PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
+                                                            GetGlobalProperties()->GetValueProperties(),
+                                                            ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
+                                                            is_global_setting);
+    }
+}
 
-const char *
+lldb_private::ConstString
 DynamicLoaderDarwinKernel::GetPluginNameStatic()
 {
-    return "dynamic-loader.macosx-kernel";
+    static ConstString g_name("darwin-kernel");
+    return g_name;
 }
 
 const char *
@@ -808,15 +1612,9 @@ DynamicLoaderDarwinKernel::GetPluginDesc
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 DynamicLoaderDarwinKernel::GetPluginName()
 {
-    return "DynamicLoaderDarwinKernel";
-}
-
-const char *
-DynamicLoaderDarwinKernel::GetShortPluginName()
-{
     return GetPluginNameStatic();
 }
 
@@ -826,3 +1624,25 @@ DynamicLoaderDarwinKernel::GetPluginVers
     return 1;
 }
 
+lldb::ByteOrder
+DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
+{
+    switch (magic)
+    {
+        case llvm::MachO::HeaderMagic32:
+        case llvm::MachO::HeaderMagic64:
+            return lldb::endian::InlHostByteOrder();
+            
+        case llvm::MachO::HeaderMagic32Swapped:
+        case llvm::MachO::HeaderMagic64Swapped:
+            if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
+                return lldb::eByteOrderLittle;
+            else
+                return lldb::eByteOrderBig;
+            
+        default:
+            break;
+    }
+    return lldb::eByteOrderInvalid;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h Thu Jun  6 19:06:43 2013
@@ -38,7 +38,7 @@ public:
     static void
     Terminate();
 
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic();
 
     static const char *
@@ -47,10 +47,14 @@ public:
     static lldb_private::DynamicLoader *
     CreateInstance (lldb_private::Process *process, bool force);
 
-    DynamicLoaderDarwinKernel (lldb_private::Process *process);
+    static void
+    DebuggerInitialize (lldb_private::Debugger &debugger);
+
+    DynamicLoaderDarwinKernel (lldb_private::Process *process, lldb::addr_t kernel_addr);
 
     virtual
     ~DynamicLoaderDarwinKernel ();
+
     //------------------------------------------------------------------
     /// Called after attaching a process.
     ///
@@ -73,12 +77,9 @@ public:
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
 
-    virtual const char *
-    GetShortPluginName();
-
     virtual uint32_t
     GetPluginVersion();
 
@@ -89,7 +90,7 @@ protected:
     void
     PrivateProcessStateChanged (lldb_private::Process *process,
                                 lldb::StateType state);
-    
+
     void
     UpdateIfNeeded();
 
@@ -109,8 +110,8 @@ protected:
                            lldb::user_id_t break_loc_id);
 
     bool
-    BreakpointHit (lldb_private::StoppointCallbackContext *context, 
-                   lldb::user_id_t break_id, 
+    BreakpointHit (lldb_private::StoppointCallbackContext *context,
+                   lldb::user_id_t break_id,
                    lldb::user_id_t break_loc_id);
     uint32_t
     GetAddrByteSize()
@@ -119,26 +120,8 @@ protected:
     }
 
     static lldb::ByteOrder
-    GetByteOrderFromMagic (uint32_t magic)
-    {
-        switch (magic)
-        {
-            case llvm::MachO::HeaderMagic32:
-            case llvm::MachO::HeaderMagic64:
-                return lldb::endian::InlHostByteOrder();
-
-            case llvm::MachO::HeaderMagic32Swapped:
-            case llvm::MachO::HeaderMagic64Swapped:
-                if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
-                    return lldb::eByteOrderLittle;
-                else
-                    return lldb::eByteOrderBig;
+    GetByteOrderFromMagic (uint32_t magic);
 
-            default:
-                break;
-        }
-        return lldb::eByteOrderInvalid;
-    }
     enum
     {
         KERNEL_MODULE_MAX_NAME = 64u,
@@ -148,58 +131,51 @@ protected:
         // 4 byte flags
         KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
     };
-    
-    struct OSKextLoadedKextSummary
+
+    // class KextImageInfo represents a single kext or kernel binary image.
+    // The class was designed to hold the information from the OSKextLoadedKextSummary
+    // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel maintains 
+    // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure, 
+    // which points to an array of OSKextLoadedKextSummary's).
+    //
+    // A KextImageInfos may have -
+    // 
+    // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
+    //    (read straight out of the kernel's list-of-kexts loaded)
+    // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory 
+    //    (very unlikely to have any symbolic information)
+    // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
+    //    or a dSYM
+    //
+    // For performance reasons, the developer may prefer that lldb not load the kexts out
+    // of memory at the start of a kernel session.  But we should build up / maintain a 
+    // list of kexts that the kernel has told us about so we can relocate a kext module
+    // later if the user explicitly adds it to the target.
+
+    class KextImageInfo
     {
-        char                     name[KERNEL_MODULE_MAX_NAME];
-        lldb::ModuleSP           module_sp;
-        uint32_t                 load_process_stop_id;
-        lldb_private::UUID       uuid;            // UUID for this dylib if it has one, else all zeros
-        lldb_private::Address    so_address;        // The section offset address for this kext in case it can be read from object files
-        uint64_t                 address;
-        uint64_t                 size;
-        uint64_t                 version;
-        uint32_t                 load_tag;
-        uint32_t                 flags;
-        uint64_t                 reference_list;
-
-        OSKextLoadedKextSummary() :
-            module_sp (),
-            load_process_stop_id (UINT32_MAX),
-            uuid (),
-            so_address (),
-            address (LLDB_INVALID_ADDRESS),
-            size (0),
-            version (0),
-            load_tag (0),
-            flags (0),
-            reference_list (0)
-        {
-            name[0] = '\0';
-        }
-        
-        bool
-        IsLoaded ()
-        {
-            return load_process_stop_id != UINT32_MAX;
-        }
+    public:
+        KextImageInfo () :
+            m_name (),
+            m_module_sp (),
+            m_memory_module_sp (),
+            m_load_process_stop_id (UINT32_MAX),
+            m_uuid (),
+            m_load_address (LLDB_INVALID_ADDRESS),
+            m_size (0),
+            m_kernel_image (false)
+        { }
 
         void
-        Clear (bool load_cmd_data_only)
+        Clear ()
         {
-            if (!load_cmd_data_only)
-            {
-                so_address.Clear();
-                address = LLDB_INVALID_ADDRESS;
-                size = 0;
-                version = 0;
-                load_tag = 0;
-                flags = 0;
-                reference_list = 0;
-                name[0] = '\0';
-            }
-            module_sp.reset();
-            load_process_stop_id = UINT32_MAX;
+            m_load_address = LLDB_INVALID_ADDRESS;
+            m_size = 0;
+            m_name.clear ();
+            m_uuid.Clear();
+            m_module_sp.reset();
+            m_memory_module_sp.reset();
+            m_load_process_stop_id = UINT32_MAX;
         }
 
         bool
@@ -207,57 +183,88 @@ protected:
 
         bool
         LoadImageUsingMemoryModule (lldb_private::Process *process);
-        
-//        bool
-//        operator == (const OSKextLoadedKextSummary& rhs) const
-//        {
-//            return  address == rhs.address
-//                    && size == rhs.size
-//            //&& module_sp.get() == rhs.module_sp.get()
-//                    && uuid == rhs.uuid
-//                    && version == rhs.version
-//                    && load_tag == rhs.load_tag
-//                    && flags == rhs.flags
-//                    && reference_list == rhs.reference_list
-//                    && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
-//        }
-//
+
         bool
-        UUIDValid() const
+        IsLoaded ()
         {
-            return uuid.IsValid();
+            return m_load_process_stop_id != UINT32_MAX;
         }
 
+        void
+        SetLoadAddress (lldb::addr_t load_addr);     // Address of the Mach-O header for this binary
+
+        lldb::addr_t 
+        GetLoadAddress () const;                     // Address of the Mach-O header for this binary
+
+        lldb_private::UUID
+        GetUUID () const;
+
+        void
+        SetUUID (const lldb_private::UUID &uuid);
+
+        void
+        SetName (const char *);
+
+        std::string
+        GetName () const;
+
+        void
+        SetModule (lldb::ModuleSP module);
+
+        lldb::ModuleSP
+        GetModule ();
+
+        // try to fill in m_memory_module_sp from memory based on the m_load_address
+        bool
+        ReadMemoryModule (lldb_private::Process *process); 
+
+        bool
+        IsKernel () const;            // true if this is the mach_kernel; false if this is a kext
+
+        void
+        SetIsKernel (bool is_kernel);
+
+        uint64_t 
+        GetSize () const;
+
+        void
+        SetSize (uint64_t size);
+
         uint32_t
-        GetAddressByteSize ()
-        {
-            if (module_sp)
-                return module_sp->GetArchitecture().GetAddressByteSize();
-            return 0;
-        }
+        GetProcessStopId () const;    // the stop-id when this binary was first noticed
+
+        void
+        SetProcessStopId (uint32_t stop_id);
+
+        bool
+        operator== (const KextImageInfo &rhs);
+
+        uint32_t
+        GetAddressByteSize ();        // as determined by Mach-O header
 
         lldb::ByteOrder
-        GetByteOrder()
-        {
-            if (module_sp)
-                return module_sp->GetArchitecture().GetByteOrder();
-            return lldb::endian::InlHostByteOrder();
-        }
+        GetByteOrder();               // as determined by Mach-O header
 
         lldb_private::ArchSpec
-        GetArchitecture () const
-        {
-            if (module_sp)
-                return module_sp->GetArchitecture();
-            return lldb_private::ArchSpec ();
-        }
+        GetArchitecture () const;     // as determined by Mach-O header
 
         void
         PutToLog (lldb_private::Log *log) const;
 
-        typedef std::vector<OSKextLoadedKextSummary> collection;
+        typedef std::vector<KextImageInfo> collection;
         typedef collection::iterator iterator;
         typedef collection::const_iterator const_iterator;
+
+    private:
+        std::string              m_name;
+        lldb::ModuleSP           m_module_sp;
+        lldb::ModuleSP           m_memory_module_sp;
+        uint32_t                 m_load_process_stop_id; // the stop-id when this module was added to the Target
+        lldb_private::UUID       m_uuid;                 // UUID for this dylib if it has one, else all zeros
+        lldb::addr_t             m_load_address;
+        uint64_t                 m_size;
+        bool                     m_kernel_image;         // true if this is the kernel, false if this is a kext
+
     };
 
     struct OSKextLoadedKextSummaryHeader
@@ -285,7 +292,7 @@ protected:
                 default: break;
             }
             // Version 2 and above has version, entry_size, entry_count, and reserved
-            return 16; 
+            return 16;
         }
 
         void
@@ -318,31 +325,48 @@ protected:
 
     bool
     ReadKextSummaryHeader ();
-    
+
     bool
-    ParseKextSummaries (const lldb_private::Address &kext_summary_addr, 
+    ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
                         uint32_t count);
-    
-    bool
-    AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
-    
+
     void
-    UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos, 
-                                          uint32_t infos_count, 
+    UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
+                                          uint32_t infos_count,
                                           bool update_executable);
 
     uint32_t
     ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
-                       uint32_t image_infos_count, 
-                       OSKextLoadedKextSummary::collection &image_infos);
+                       uint32_t image_infos_count,
+                       KextImageInfo::collection &image_infos);
+
+    static lldb::addr_t
+    SearchForDarwinKernel (lldb_private::Process *process);
     
-    OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
-    lldb_private::Address m_kext_summary_header_ptr_addr;
-    lldb_private::Address m_kext_summary_header_addr;
-    OSKextLoadedKextSummaryHeader m_kext_summary_header;
-    OSKextLoadedKextSummary::collection m_kext_summaries;
-    mutable lldb_private::Mutex m_mutex;
-    lldb::user_id_t m_break_id;
+    static lldb::addr_t
+    SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
+
+    static lldb::addr_t
+    SearchForKernelWithDebugHints (lldb_private::Process *process);
+
+    static lldb::addr_t
+    SearchForKernelNearPC (lldb_private::Process *process);
+
+    static lldb::addr_t
+    SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
+
+    static lldb_private::UUID
+    CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
+
+    lldb::addr_t  m_kernel_load_address;
+    KextImageInfo m_kernel;                 // Info about the current kernel image being used
+
+    lldb_private::Address          m_kext_summary_header_ptr_addr;
+    lldb_private::Address          m_kext_summary_header_addr;
+    OSKextLoadedKextSummaryHeader  m_kext_summary_header;
+    KextImageInfo::collection      m_known_kexts;
+    mutable lldb_private::Mutex    m_mutex;
+    lldb::user_id_t                m_break_id;
 
 private:
     DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Thu Jun  6 19:06:43 2013
@@ -15,8 +15,11 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
+#include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/RegisterContext.h"
@@ -35,6 +38,10 @@
 #define DEBUG_PRINTF(fmt, ...)
 #endif
 
+#ifndef __APPLE__
+#include "Utility/UuidCompatibility.h"
+#endif
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -136,7 +143,8 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMa
     m_break_id(LLDB_INVALID_BREAK_ID),
     m_dyld_image_infos(),
     m_dyld_image_infos_stop_id (UINT32_MAX),
-    m_mutex(Mutex::eMutexTypeRecursive)
+    m_mutex(Mutex::eMutexTypeRecursive),
+    m_process_image_addr_is_all_images_infos (false)
 {
 }
 
@@ -176,6 +184,54 @@ DynamicLoaderMacOSXDYLD::DidLaunch ()
     SetNotificationBreakpoint ();
 }
 
+bool
+DynamicLoaderMacOSXDYLD::ProcessDidExec ()
+{
+    if (m_process)
+    {
+        // If we are stopped after an exec, we will have only one thread...
+        if (m_process->GetThreadList().GetSize() == 1)
+        {
+            // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
+            // value differs from the Process' image info address. When a process
+            // execs itself it might cause a change if ASLR is enabled.
+            const addr_t shlib_addr = m_process->GetImageInfoAddress ();
+            if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr)
+            {
+                // The image info address from the process is the 'dyld_all_image_infos'
+                // address and it has changed.
+                return true;
+            }
+            
+            if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
+            {
+                // The image info address from the process is the mach_header
+                // address for dyld and it has changed.
+                return true;
+            }
+            
+            // ASLR might be disabled and dyld could have ended up in the same
+            // location. We should try and detect if we are stopped at '_dyld_start'
+            ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0));
+            if (thread_sp)
+            {
+                lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0));
+                if (frame_sp)
+                {
+                    const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+                    if (symbol)
+                    {
+                        if (symbol->GetName() == ConstString("_dyld_start"))
+                            return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+
 
 //----------------------------------------------------------------------
 // Clear out the state of this class.
@@ -186,7 +242,7 @@ DynamicLoaderMacOSXDYLD::Clear (bool cle
     Mutex::Locker locker(m_mutex);
 
     if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
-        m_process->ClearBreakpointSiteByID(m_break_id);
+        m_process->GetTarget().RemoveBreakpointByID (m_break_id);
 
     if (clear_process)
         m_process = NULL;
@@ -221,29 +277,33 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
         // mach header for dyld, or it might point to the 
         // dyld_all_image_infos struct
         const addr_t shlib_addr = m_process->GetImageInfoAddress ();
-
-        ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
-        uint8_t buf[4];
-        DataExtractor data (buf, sizeof(buf), byte_order, 4);
-        Error error;
-        if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+        if (shlib_addr != LLDB_INVALID_ADDRESS)
         {
-            uint32_t offset = 0;
-            uint32_t magic = data.GetU32 (&offset);
-            switch (magic)
-            {
-            case llvm::MachO::HeaderMagic32:
-            case llvm::MachO::HeaderMagic64:
-            case llvm::MachO::HeaderMagic32Swapped:
-            case llvm::MachO::HeaderMagic64Swapped:
-                return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
-                
-            default:
-                break;
+            ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
+            uint8_t buf[4];
+            DataExtractor data (buf, sizeof(buf), byte_order, 4);
+            Error error;
+            if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+            {
+                lldb::offset_t offset = 0;
+                uint32_t magic = data.GetU32 (&offset);
+                switch (magic)
+                {
+                case llvm::MachO::HeaderMagic32:
+                case llvm::MachO::HeaderMagic64:
+                case llvm::MachO::HeaderMagic32Swapped:
+                case llvm::MachO::HeaderMagic64Swapped:
+                    m_process_image_addr_is_all_images_infos = false;
+                    return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+                    
+                default:
+                    break;
+                }
             }
+            // Maybe it points to the all image infos?
+            m_dyld_all_image_infos_addr = shlib_addr;
+            m_process_image_addr_is_all_images_infos = true;
         }
-        // Maybe it points to the all image infos?
-        m_dyld_all_image_infos_addr = shlib_addr;
     }
 
     if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
@@ -280,11 +340,13 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
 }
 
 ModuleSP
-DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
+DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
 {
     if (did_create_ptr)
         *did_create_ptr = false;
-    ModuleList &target_images = m_process->GetTarget().GetImages();
+    
+    Target &target = m_process->GetTarget();
+    const ModuleList &target_images = target.GetImages();
     ModuleSpec module_spec (image_info.file_spec, image_info.GetArchitecture ());
     module_spec.GetUUID() = image_info.uuid;
     ModuleSP module_sp (target_images.FindFirstModule (module_spec));
@@ -301,16 +363,9 @@ DynamicLoaderMacOSXDYLD::FindTargetModul
     {
         if (can_create)
         {
-            module_sp = m_process->GetTarget().GetSharedModule (module_spec);
+            module_sp = target.GetSharedModule (module_spec);
             if (!module_sp || module_sp->GetObjectFile() == NULL)
-            {
-                const bool add_image_to_target = true;
-                const bool load_image_sections_in_target = false;
-                module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
-                                                             image_info.address,
-                                                             add_image_to_target,
-                                                             load_image_sections_in_target);
-            }
+                module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
 
             if (did_create_ptr)
                 *did_create_ptr = (bool) module_sp;
@@ -344,12 +399,14 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
                 }
             }
 
+            Target &target = m_process->GetTarget();
+
             if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
             {
                 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
                 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
                 if (symbol)
-                    m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
+                    m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&target);
             }
 
             // Update all image infos
@@ -360,9 +417,15 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
             // it again (since Target::SetExecutableModule() will clear the
             // images). So append the dyld module back to the list if it is
             /// unique!
-            if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
-                UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+            if (dyld_module_sp)
+            {
+                target.GetImages().AppendIfNeeded (dyld_module_sp);
 
+                // At this point we should have read in dyld's module, and so we should set breakpoints in it:
+                ModuleList modules;
+                modules.Append(dyld_module_sp);
+                target.ModulesDidLoad(modules);
+            }
             return true;
         }
     }
@@ -375,40 +438,6 @@ DynamicLoaderMacOSXDYLD::NeedToLocateDYL
     return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
 }
 
-bool
-DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
-{
-    bool changed = false;
-    if (module)
-    {
-        ObjectFile *image_object_file = module->GetObjectFile();
-        if (image_object_file)
-        {
-            SectionList *section_list = image_object_file->GetSectionList ();
-            if (section_list)
-            {
-                uint32_t num_sections = section_list->GetSize();
-                for (uint32_t i=0; i<num_sections; ++i)
-                {
-                    SectionSP section_sp (section_list->GetSectionAtIndex (i));
-                    if (section_sp)
-                    {
-                        const addr_t new_section_load_addr = section_sp->GetFileAddress ();
-                        const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
-                        if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
-                            old_section_load_addr != new_section_load_addr)
-                        {
-                            if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress ()))
-                                changed = true;
-                        }
-                    }
-                }
-            }
-        }
-    }
-    return changed;
-}
-
 //----------------------------------------------------------------------
 // Update the load addresses for all segments in MODULE using the
 // updated INFO that is passed in.
@@ -428,8 +457,8 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoad
                 std::vector<uint32_t> inaccessible_segment_indexes;
                 // We now know the slide amount, so go through all sections
                 // and update the load addresses with the correct values.
-                uint32_t num_segments = info.segments.size();
-                for (uint32_t i=0; i<num_segments; ++i)
+                const size_t num_segments = info.segments.size();
+                for (size_t i=0; i<num_segments; ++i)
                 {
                     // Only load a segment if it has protections. Things like
                     // __PAGEZERO don't have any protections, and they shouldn't
@@ -464,11 +493,10 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoad
                         else
                         {
                             Host::SystemLog (Host::eSystemLogWarning, 
-                                             "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
+                                             "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
                                              info.segments[i].name.AsCString("<invalid>"),
                                              (uint64_t)new_section_load_addr,
-                                             image_object_file->GetFileSpec().GetDirectory().AsCString(),
-                                             image_object_file->GetFileSpec().GetFilename().AsCString());
+                                             image_object_file->GetFileSpec().GetPath().c_str());
                         }
                     }
                 }
@@ -504,6 +532,14 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoad
             }
         }
     }
+    // We might have an in memory image that was loaded as soon as it was created
+    if (info.load_stop_id == m_process->GetStopID())
+        changed = true;
+    else if (changed)
+    {
+        // Update the stop ID when this library was updated
+        info.load_stop_id = m_process->GetStopID();
+    }
     return changed;
 }
 
@@ -523,8 +559,8 @@ DynamicLoaderMacOSXDYLD::UnloadImageLoad
             SectionList *section_list = image_object_file->GetSectionList ();
             if (section_list)
             {
-                uint32_t num_segments = info.segments.size();
-                for (uint32_t i=0; i<num_segments; ++i)
+                const size_t num_segments = info.segments.size();
+                for (size_t i=0; i<num_segments; ++i)
                 {
                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
                     if (section_sp)
@@ -536,10 +572,9 @@ DynamicLoaderMacOSXDYLD::UnloadImageLoad
                     else
                     {
                         Host::SystemLog (Host::eSystemLogWarning, 
-                                         "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
+                                         "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
                                          info.segments[i].name.AsCString("<invalid>"),
-                                         image_object_file->GetFileSpec().GetDirectory().AsCString(),
-                                         image_object_file->GetFileSpec().GetFilename().AsCString());
+                                         image_object_file->GetFileSpec().GetPath().c_str());
                     }
                 }
             }
@@ -653,7 +688,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
 
         uint8_t buf[256];
         DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
-        uint32_t offset = 0;
+        lldb::offset_t offset = 0;
 
         const size_t count_v2 =  sizeof (uint32_t) + // version
                                  sizeof (uint32_t) + // infoArrayCount
@@ -676,9 +711,11 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
                                  addr_size +         // errorClientOfDylibPath
                                  addr_size +         // errorTargetDylibPath
                                  addr_size;          // errorSymbol
-        assert (sizeof (buf) >= count_v11);
+        const size_t count_v13 = count_v11 +
+                                 addr_size +         // sharedCacheSlide
+                                 sizeof (uuid_t);    // sharedCacheUUID
+        assert (sizeof (buf) >= count_v13);
 
-        int count;
         Error error;
         if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
         {
@@ -705,10 +742,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
             return false;
         }
 
-        if (m_dyld_all_image_infos.version >= 11)
-            count = count_v11;
-        else
-            count = count_v2;
+        const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
 
         const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
         if (bytes_read == count)
@@ -759,7 +793,7 @@ bool
 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
 {
     DYLDImageInfo::collection image_infos;
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
         log->Printf ("Adding %d modules.\n", image_infos_count);
         
@@ -784,14 +818,16 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
 {
     // Now add these images to the main list.
     ModuleList loaded_module_list;
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Target &target = m_process->GetTarget();
+    ModuleList& target_images = target.GetImages();
     
     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
     {
         if (log)
         {
-            log->Printf ("Adding new image at address=0x%16.16llx.", image_infos[idx].address);
-            image_infos[idx].PutToLog (log.get());
+            log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
+            image_infos[idx].PutToLog (log);
         }
         
         m_dyld_image_infos.push_back(image_infos[idx]);
@@ -813,26 +849,31 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
                     Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
                     if (commpage_section)
                     {
-                        ModuleList& target_images = m_process->GetTarget().GetImages();
                         ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
                         module_spec.GetObjectName() = commpage_dbstr;
                         ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
                         if (!commpage_image_module_sp)
                         {
-                            module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
-                            commpage_image_module_sp  = m_process->GetTarget().GetSharedModule (module_spec);
+                            module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+                            commpage_image_module_sp  = target.GetSharedModule (module_spec);
                             if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
                             {
-                                const bool add_image_to_target = true;
-                                const bool load_image_sections_in_target = false;
                                 commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
-                                                                                            image_infos[idx].address,
-                                                                                            add_image_to_target,
-                                                                                            load_image_sections_in_target);
+                                                                                            image_infos[idx].address);
+                                // Always load a memory image right away in the target in case
+                                // we end up trying to read the symbol table from memory... The
+                                // __LINKEDIT will need to be mapped so we can figure out where
+                                // the symbol table bits are...
+                                bool changed = false;
+                                UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
+                                target.GetImages().Append(commpage_image_module_sp);
+                                if (changed)
+                                {
+                                    image_infos[idx].load_stop_id = m_process->GetStopID();
+                                    loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
+                                }
                             }
                         }
-                        if (commpage_image_module_sp)
-                            UpdateCommPageLoadAddress (commpage_image_module_sp.get());
                     }
                 }
             }
@@ -844,6 +885,7 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
             // shared libraries each time.
             if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
             {
+                target_images.AppendIfNeeded(image_module_sp);
                 loaded_module_list.AppendIfNeeded (image_module_sp);
             }
         }
@@ -880,7 +922,7 @@ bool
 DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
 {
     DYLDImageInfo::collection image_infos;
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     
     Mutex::Locker locker(m_mutex);
     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
@@ -902,8 +944,8 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
     {        
         if (log)
         {
-            log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
-            image_infos[idx].PutToLog (log.get());
+            log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
+            image_infos[idx].PutToLog (log);
         }
             
         // Remove this image_infos from the m_all_image_infos.  We do the comparision by address
@@ -936,7 +978,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
                     if (log)
                     {
                         log->Printf ("Could not find module for unloading info entry:");
-                        image_infos[idx].PutToLog(log.get());
+                        image_infos[idx].PutToLog(log);
                     }
                 }
                 
@@ -952,7 +994,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
             if (log)
             {
                 log->Printf ("Could not find image_info entry for unloading image:");
-                image_infos[idx].PutToLog(log.get());            
+                image_infos[idx].PutToLog(log);
             }
         }
     }
@@ -963,7 +1005,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
             log->PutCString("Unloaded:");
             unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
         }
-        m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+        m_process->GetTarget().GetImages().Remove (unloaded_module_list);
     }
     m_dyld_image_infos_stop_id = m_process->GetStopID();
     return true;
@@ -987,7 +1029,7 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos
                                                      error);
     if (bytes_read == count)
     {
-        uint32_t info_data_offset = 0;
+        lldb::offset_t info_data_offset = 0;
         DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
         for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
         {
@@ -1022,7 +1064,7 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos
 bool
 DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
 {
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     
     Mutex::Locker locker(m_mutex);
     if (m_process->GetStopID() == m_dyld_image_infos_stop_id
@@ -1046,7 +1088,7 @@ DynamicLoaderMacOSXDYLD::InitializeFromA
             if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr, 
                                                    m_dyld_all_image_infos.dylib_info_count))
             {
-                DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
+                DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
                 m_dyld_image_infos.clear();
             }
         }
@@ -1057,7 +1099,7 @@ DynamicLoaderMacOSXDYLD::InitializeFromA
         // to an equivalent version.  We don't want it to stay in the target's module list or it will confuse
         // us, so unload it here.
         Target &target = m_process->GetTarget();
-        ModuleList &target_modules = target.GetImages();
+        const ModuleList &target_modules = target.GetImages();
         ModuleList not_loaded_modules;
         Mutex::Locker modules_locker(target_modules.GetMutex());
         
@@ -1079,7 +1121,7 @@ DynamicLoaderMacOSXDYLD::InitializeFromA
         
         if (not_loaded_modules.GetSize() != 0)
         {
-            target.ModulesDidUnload(not_loaded_modules);
+            target.GetImages().Remove(not_loaded_modules);
         }
 
         return true;
@@ -1105,7 +1147,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader
                                                error);
     if (bytes_read == sizeof(llvm::MachO::mach_header))
     {
-        uint32_t offset = 0;
+        lldb::offset_t offset = 0;
         ::memset (header, 0, sizeof(llvm::MachO::mach_header));
 
         // Get the magic byte unswapped so we can figure out what we are dealing with
@@ -1167,7 +1209,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader
 uint32_t
 DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
 {
-    uint32_t offset = 0;
+    lldb::offset_t offset = 0;
     uint32_t cmd_idx;
     Segment segment;
     dylib_info.Clear (true);
@@ -1180,7 +1222,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadComman
         if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
         {
             llvm::MachO::load_command load_cmd;
-            uint32_t load_cmd_offset = offset;
+            lldb::offset_t load_cmd_offset = offset;
             load_cmd.cmd = data.GetU32 (&offset);
             load_cmd.cmdsize = data.GetU32 (&offset);
             switch (load_cmd.cmd)
@@ -1214,7 +1256,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadComman
             case llvm::MachO::LoadCommandDynamicLinkerIdent:
                 if (lc_id_dylinker)
                 {
-                    uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
+                    const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
                     const char *path = data.PeekCStr (name_offset);
                     lc_id_dylinker->SetFile (path, true);
                 }
@@ -1267,7 +1309,6 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
                                                                bool update_executable)
 {
     uint32_t exe_idx = UINT32_MAX;
-    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     // Read any UUID values that we can get
     for (uint32_t i = 0; i < infos_count; i++)
     {
@@ -1285,32 +1326,18 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
         }
     }
 
+    Target &target = m_process->GetTarget();
+
     if (exe_idx < image_infos.size())
     {
         const bool can_create = true;
         ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
 
-        if (!exe_module_sp)
-        {
-            ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
-            ModuleSpec module_spec (image_infos[exe_idx].file_spec, 
-                                    image_infos[exe_idx].GetArchitecture ());
-            module_spec.GetUUID() = image_infos[exe_idx].uuid;
-            exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
-            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
-            {
-                const bool add_image_to_target = true;
-                const bool load_image_sections_in_target = false;
-                exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
-                                                                 image_infos[exe_idx].address,
-                                                                 add_image_to_target,
-                                                                 load_image_sections_in_target);                
-            }
-        }
-        
         if (exe_module_sp)
         {
-            if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
+            UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
+
+            if (exe_module_sp.get() != target.GetExecutableModulePointer())
             {
                 // Don't load dependent images since we are in dyld where we will know
                 // and find out about all images that are loaded
@@ -1371,12 +1398,12 @@ DynamicLoaderMacOSXDYLD::Segment::PutToL
     if (log)
     {
         if (slide == 0)
-            log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)", 
+            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
                          name.AsCString(""), 
                          vmaddr + slide, 
                          vmaddr + slide + vmsize);
         else
-            log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx", 
+            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
                          name.AsCString(""), 
                          vmaddr + slide, 
                          vmaddr + slide + vmsize, 
@@ -1411,42 +1438,38 @@ DynamicLoaderMacOSXDYLD::DYLDImageInfo::
     {
         if (u)
         {
-            log->Printf("\t                           modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s' (UNLOADED)",
+            log->Printf("\t                           modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
                         mod_date,
                         u[ 0], u[ 1], u[ 2], u[ 3],
                         u[ 4], u[ 5], u[ 6], u[ 7],
                         u[ 8], u[ 9], u[10], u[11],
                         u[12], u[13], u[14], u[15],
-                        file_spec.GetDirectory().AsCString(),
-                        file_spec.GetFilename().AsCString());
+                        file_spec.GetPath().c_str());
         }
         else
-            log->Printf("\t                           modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
+            log->Printf("\t                           modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
                         mod_date,
-                        file_spec.GetDirectory().AsCString(),
-                        file_spec.GetFilename().AsCString());
+                        file_spec.GetPath().c_str());
     }
     else
     {
         if (u)
         {
-            log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s'",
+            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
                         address,
                         mod_date,
                         u[ 0], u[ 1], u[ 2], u[ 3],
                         u[ 4], u[ 5], u[ 6], u[ 7],
                         u[ 8], u[ 9], u[10], u[11],
                         u[12], u[13], u[14], u[15],
-                        file_spec.GetDirectory().AsCString(),
-                        file_spec.GetFilename().AsCString());
+                        file_spec.GetPath().c_str());
         }
         else
         {
-            log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
+            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
                         address,
                         mod_date,
-                        file_spec.GetDirectory().AsCString(),
-                        file_spec.GetFilename().AsCString());
+                        file_spec.GetPath().c_str());
 
         }
         for (uint32_t i=0; i<segments.size(); ++i)
@@ -1465,7 +1488,7 @@ DynamicLoaderMacOSXDYLD::PutToLog(Log *l
         return;
 
     Mutex::Locker locker(m_mutex);
-    log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
+    log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
                     m_dyld_all_image_infos.version,
                     m_dyld_all_image_infos.dylib_info_count,
                     (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
@@ -1507,6 +1530,7 @@ DynamicLoaderMacOSXDYLD::SetNotification
             {
                 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
                 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
+                dyld_break->SetBreakpointKind ("shared-library-event");
                 m_break_id = dyld_break->GetID();
             }
         }
@@ -1550,9 +1574,6 @@ DynamicLoaderMacOSXDYLD::PrivateProcessS
     case eStateCrashed:
     case eStateSuspended:
         break;
-
-    default:
-        break;
     }
 }
 
@@ -1571,7 +1592,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughT
     StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
     Symbol *current_symbol = current_context.symbol;
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
 
     if (current_symbol != NULL)
     {
@@ -1583,7 +1604,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughT
             {
                 SymbolContextList target_symbols;
                 TargetSP target_sp (thread.CalculateTarget());
-                ModuleList &images = target_sp->GetImages();
+                const ModuleList &images = target_sp->GetImages();
                 
                 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
 
@@ -1593,6 +1614,8 @@ DynamicLoaderMacOSXDYLD::GetStepThroughT
                 // For now, just turn this off.
                 
                 // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
+                // FIXME: Actually that isn't true, the N_SYMBOL_RESOLVER bit is only valid in .o files.  You can't use
+                // the symbol flags to tell whether something is a symbol resolver in a linked image.
                 bool orig_is_resolver = false;
                 
                 if (num_original_symbols > 0)
@@ -1737,10 +1760,11 @@ DynamicLoaderMacOSXDYLD::Terminate()
 }
 
 
-const char *
+lldb_private::ConstString
 DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
 {
-    return "dynamic-loader.macosx-dyld";
+    static ConstString g_name("macosx-dyld");
+    return g_name;
 }
 
 const char *
@@ -1753,15 +1777,9 @@ DynamicLoaderMacOSXDYLD::GetPluginDescri
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 DynamicLoaderMacOSXDYLD::GetPluginName()
 {
-    return "DynamicLoaderMacOSXDYLD";
-}
-
-const char *
-DynamicLoaderMacOSXDYLD::GetShortPluginName()
-{
     return GetPluginNameStatic();
 }
 
@@ -1771,3 +1789,50 @@ DynamicLoaderMacOSXDYLD::GetPluginVersio
     return 1;
 }
 
+uint32_t
+DynamicLoaderMacOSXDYLD::AddrByteSize()
+{
+    switch (m_dyld.header.magic)
+    {
+        case llvm::MachO::HeaderMagic32:
+        case llvm::MachO::HeaderMagic32Swapped:
+            return 4;
+            
+        case llvm::MachO::HeaderMagic64:
+        case llvm::MachO::HeaderMagic64Swapped:
+            return 8;
+            
+        default:
+            break;
+    }
+    return 0;
+}
+
+lldb::ByteOrder
+DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
+{
+    switch (magic)
+    {
+        case llvm::MachO::HeaderMagic32:
+        case llvm::MachO::HeaderMagic64:
+            return lldb::endian::InlHostByteOrder();
+            
+        case llvm::MachO::HeaderMagic32Swapped:
+        case llvm::MachO::HeaderMagic64Swapped:
+            if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
+                return lldb::eByteOrderLittle;
+            else
+                return lldb::eByteOrderBig;
+            
+        default:
+            break;
+    }
+    return lldb::eByteOrderInvalid;
+}
+
+lldb::ByteOrder
+DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
+{
+    return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
+}
+

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Thu Jun  6 19:06:43 2013
@@ -37,7 +37,7 @@ public:
     static void
     Terminate();
 
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic();
 
     static const char *
@@ -62,6 +62,9 @@ public:
     virtual void
     DidLaunch ();
 
+    virtual bool
+    ProcessDidExec ();
+
     virtual lldb::ThreadPlanSP
     GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
                                   bool stop_others);
@@ -77,12 +80,9 @@ public:
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
 
-    virtual const char *
-    GetShortPluginName();
-
     virtual uint32_t
     GetPluginVersion();
 
@@ -118,45 +118,10 @@ protected:
                          lldb::user_id_t break_loc_id);
 
     uint32_t
-    AddrByteSize()
-    {
-        switch (m_dyld.header.magic)
-        {
-            case llvm::MachO::HeaderMagic32:
-            case llvm::MachO::HeaderMagic32Swapped:
-                return 4;
-
-            case llvm::MachO::HeaderMagic64:
-            case llvm::MachO::HeaderMagic64Swapped:
-                return 8;
-
-            default:
-                break;
-        }
-        return 0;
-    }
+    AddrByteSize();
 
     static lldb::ByteOrder
-    GetByteOrderFromMagic (uint32_t magic)
-    {
-        switch (magic)
-        {
-            case llvm::MachO::HeaderMagic32:
-            case llvm::MachO::HeaderMagic64:
-                return lldb::endian::InlHostByteOrder();
-
-            case llvm::MachO::HeaderMagic32Swapped:
-            case llvm::MachO::HeaderMagic64Swapped:
-                if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
-                    return lldb::eByteOrderLittle;
-                else
-                    return lldb::eByteOrderBig;
-
-            default:
-                break;
-        }
-        return lldb::eByteOrderInvalid;
-    }
+    GetByteOrderFromMagic (uint32_t magic);
 
     bool
     ReadMachHeader (lldb::addr_t addr,
@@ -210,6 +175,7 @@ protected:
         lldb_private::UUID uuid;            // UUID for this dylib if it has one, else all zeros
         llvm::MachO::mach_header header;    // The mach header for this image
         std::vector<Segment> segments;      // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
+        uint32_t load_stop_id;              // The process stop ID that the sections for this image were loadeded
 
         DYLDImageInfo() :
             address(LLDB_INVALID_ADDRESS),
@@ -218,7 +184,8 @@ protected:
             file_spec(),
             uuid(),
             header(),
-            segments()
+            segments(),
+            load_stop_id(0)
         {
         }
 
@@ -235,6 +202,7 @@ protected:
             }
             uuid.Clear();
             segments.clear();
+            load_stop_id = 0;
         }
 
         bool
@@ -269,26 +237,7 @@ protected:
         }
 
         lldb::ByteOrder
-        GetByteOrder()
-        {
-            switch (header.magic)
-            {
-            case llvm::MachO::HeaderMagic32:        // MH_MAGIC
-            case llvm::MachO::HeaderMagic64:        // MH_MAGIC_64
-                return lldb::endian::InlHostByteOrder();
-
-            case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM
-            case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64
-                if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle)
-                    return lldb::eByteOrderBig;
-                else
-                    return lldb::eByteOrderLittle;
-            default:
-                assert (!"invalid header.magic value");
-                break;
-            }
-            return lldb::endian::InlHostByteOrder();
-        }
+        GetByteOrder();
 
         lldb_private::ArchSpec
         GetArchitecture () const
@@ -367,7 +316,7 @@ protected:
                             DYLDImageInfo& info);
 
     lldb::ModuleSP
-    FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info,
+    FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info,
                                       bool can_create,
                                       bool *did_create_ptr);
 
@@ -409,9 +358,6 @@ protected:
                                           bool update_executable);
 
     bool
-    UpdateCommPageLoadAddress (lldb_private::Module *module);
-
-    bool
     ReadImageInfos (lldb::addr_t image_infos_addr, 
                     uint32_t image_infos_count, 
                     DYLDImageInfo::collection &image_infos);
@@ -426,6 +372,7 @@ protected:
     uint32_t m_dyld_image_infos_stop_id;    // The process stop ID that "m_dyld_image_infos" is valid for
     mutable lldb_private::Mutex m_mutex;
     lldb_private::Process::Notifications m_notification_callbacks;
+    bool m_process_image_addr_is_all_images_infos;
 
 private:
     DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp Thu Jun  6 19:06:43 2013
@@ -26,21 +26,25 @@ using namespace lldb_private;
 
 static bool
 GetMaxU64(DataExtractor &data,
-          uint32_t *offset, uint64_t *value, unsigned int byte_size)
-{
-    uint32_t saved_offset = *offset;
-    *value = data.GetMaxU64(offset, byte_size);
-    return *offset != saved_offset;
+          lldb::offset_t *offset_ptr,
+          uint64_t *value,
+          unsigned int byte_size)
+{
+    lldb::offset_t saved_offset = *offset_ptr;
+    *value = data.GetMaxU64(offset_ptr, byte_size);
+    return *offset_ptr != saved_offset;
 }
 
 static bool
-ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry, 
-               uint32_t *offset, unsigned int byte_size)
+ParseAuxvEntry(DataExtractor &data,
+               AuxVector::Entry &entry,
+               lldb::offset_t *offset_ptr,
+               unsigned int byte_size)
 {
-    if (!GetMaxU64(data, offset, &entry.type, byte_size))
+    if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
         return false;
 
-    if (!GetMaxU64(data, offset, &entry.value, byte_size))
+    if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
         return false;
 
     return true;
@@ -57,7 +61,7 @@ void
 AuxVector::ParseAuxv(DataExtractor &data)
 {
     const unsigned int byte_size  = m_process->GetAddressByteSize();
-    uint32_t offset = 0;
+    lldb::offset_t offset = 0;
 
     for (;;) 
     {
@@ -80,7 +84,7 @@ AuxVector::AuxVector(Process *process)
     : m_process(process)
 {
     DataExtractor data;
-    LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
 
     data.SetData(GetAuxvData());
     data.SetByteOrder(m_process->GetByteOrder());
@@ -105,7 +109,7 @@ AuxVector::FindEntry(EntryType type) con
 }
 
 void
-AuxVector::DumpToLog(LogSP log) const
+AuxVector::DumpToLog(Log *log) const
 {
     if (!log)
         return;
@@ -113,7 +117,7 @@ AuxVector::DumpToLog(LogSP log) const
     log->PutCString("AuxVector: ");
     for (iterator I = begin(); I != end(); ++I)
     {
-        log->Printf("   %s [%llu]: %llx", GetEntryName(*I), I->type, I->value);
+        log->Printf("   %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value);
     }
 }
 
@@ -125,10 +129,6 @@ AuxVector::GetEntryName(EntryType type)
 #define ENTRY_NAME(_type) _type: name = #_type
     switch (type) 
     {
-    default:
-        name = "unkown";
-        break;
-
     case ENTRY_NAME(AT_NULL);   break;
     case ENTRY_NAME(AT_IGNORE); break;
     case ENTRY_NAME(AT_EXECFD); break;

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h Thu Jun  6 19:06:43 2013
@@ -81,7 +81,7 @@ public:
     GetEntryName(EntryType type);
 
     void
-    DumpToLog(lldb::LogSP log) const;
+    DumpToLog(lldb_private::Log *log) const;
 
 private:
     lldb_private::Process *m_process;

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp Thu Jun  6 19:06:43 2013
@@ -13,6 +13,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
@@ -58,7 +59,12 @@ DYLDRendezvous::DYLDRendezvous(Process *
       m_removed_soentries()
 {
     // Cache a copy of the executable path
-    m_process->GetTarget().GetExecutableModule().get()->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
+    if (m_process)
+    {
+        Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
+        if (exe_mod)
+            exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
+    }
 }
 
 bool
@@ -294,7 +300,7 @@ DYLDRendezvous::ReadSOEntryFromMemory(ll
 }
 
 void
-DYLDRendezvous::DumpToLog(LogSP log) const
+DYLDRendezvous::DumpToLog(Log *log) const
 {
     int state = GetState();
 
@@ -302,11 +308,11 @@ DYLDRendezvous::DumpToLog(LogSP log) con
         return;
 
     log->PutCString("DYLDRendezvous:");
-    log->Printf("   Address: %llx", GetRendezvousAddress());
-    log->Printf("   Version: %d",  GetVersion());
-    log->Printf("   Link   : %llx", GetLinkMapAddress());
-    log->Printf("   Break  : %llx", GetBreakAddress());
-    log->Printf("   LDBase : %llx", GetLDBase());
+    log->Printf("   Address: %" PRIx64, GetRendezvousAddress());
+    log->Printf("   Version: %" PRIu64, GetVersion());
+    log->Printf("   Link   : %" PRIx64, GetLinkMapAddress());
+    log->Printf("   Break  : %" PRIx64, GetBreakAddress());
+    log->Printf("   LDBase : %" PRIx64, GetLDBase());
     log->Printf("   State  : %s", 
                 (state == eConsistent) ? "consistent" :
                 (state == eAdd)        ? "add"        :
@@ -321,10 +327,10 @@ DYLDRendezvous::DumpToLog(LogSP log) con
     for (int i = 1; I != E; ++I, ++i) 
     {
         log->Printf("\n   SOEntry [%d] %s", i, I->path.c_str());
-        log->Printf("      Base : %llx", I->base_addr);
-        log->Printf("      Path : %llx", I->path_addr);
-        log->Printf("      Dyn  : %llx", I->dyn_addr);
-        log->Printf("      Next : %llx", I->next);
-        log->Printf("      Prev : %llx", I->prev);
+        log->Printf("      Base : %" PRIx64, I->base_addr);
+        log->Printf("      Path : %" PRIx64, I->path_addr);
+        log->Printf("      Dyn  : %" PRIx64, I->dyn_addr);
+        log->Printf("      Next : %" PRIx64, I->next);
+        log->Printf("      Prev : %" PRIx64, I->prev);
     }
 }

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h Thu Jun  6 19:06:43 2013
@@ -73,7 +73,7 @@ public:
     GetRendezvousAddress() const { return m_rendezvous_addr; }
 
     /// @returns the version of the rendezvous protocol being used.
-    int
+    uint64_t
     GetVersion() const { return m_current.version; }
 
     /// @returns address in the inferiors address space containing the linked
@@ -92,7 +92,7 @@ public:
     GetBreakAddress() const { return m_current.brk; }
 
     /// Returns the current state of the rendezvous structure.
-    int
+    uint64_t
     GetState() const { return m_current.state; }
 
     /// @returns the base address of the runtime linker in the inferiors address
@@ -111,7 +111,7 @@ public:
     ModulesDidUnload() const { return !m_removed_soentries.empty(); }
 
     void
-    DumpToLog(lldb::LogSP log) const;
+    DumpToLog(lldb_private::Log *log) const;
 
     /// @brief Constants describing the state of the rendezvous.
     ///

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Thu Jun  6 19:06:43 2013
@@ -12,6 +12,10 @@
 // Other libraries and framework includes
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
@@ -36,22 +40,17 @@ DynamicLoaderPOSIXDYLD::Terminate()
 {
 }
 
-const char *
+lldb_private::ConstString
 DynamicLoaderPOSIXDYLD::GetPluginName()
 {
-    return "DynamicLoaderPOSIXDYLD";
-}
-
-const char *
-DynamicLoaderPOSIXDYLD::GetShortPluginName()
-{
-    return "linux-dyld";
+    return GetPluginNameStatic();
 }
 
-const char *
+lldb_private::ConstString
 DynamicLoaderPOSIXDYLD::GetPluginNameStatic()
 {
-    return "dynamic-loader.linux-dyld";
+    static ConstString g_name("linux-dyld");
+    return g_name;
 }
 
 const char *
@@ -94,7 +93,7 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOS
       m_rendezvous(process),
       m_load_offset(LLDB_INVALID_ADDRESS),
       m_entry_point(LLDB_INVALID_ADDRESS),
-      m_auxv(NULL)
+      m_auxv()
 {
 }
 
@@ -110,7 +109,7 @@ DynamicLoaderPOSIXDYLD::DidAttach()
 
     m_auxv.reset(new AuxVector(m_process));
 
-    executable = m_process->GetTarget().GetExecutableModule();
+    executable = GetTargetExecutable();
     load_offset = ComputeLoadOffset();
 
     if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
@@ -131,7 +130,7 @@ DynamicLoaderPOSIXDYLD::DidLaunch()
 
     m_auxv.reset(new AuxVector(m_process));
 
-    executable = m_process->GetTarget().GetExecutableModule();
+    executable = GetTargetExecutable();
     load_offset = ComputeLoadOffset();
 
     if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
@@ -144,6 +143,46 @@ DynamicLoaderPOSIXDYLD::DidLaunch()
     }
 }
 
+ModuleSP
+DynamicLoaderPOSIXDYLD::GetTargetExecutable()
+{
+    Target &target = m_process->GetTarget();
+    ModuleSP executable = target.GetExecutableModule();
+
+    if (executable.get())
+    {
+        if (executable->GetFileSpec().Exists())
+        {
+            ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
+            ModuleSP module_sp (new Module (module_spec));
+
+            // Check if the executable has changed and set it to the target executable if they differ.
+            if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
+            {
+                if (module_sp->GetUUID() != executable->GetUUID())
+                    executable.reset();
+            }
+            else if (executable->FileHasChanged())
+            {
+                executable.reset();
+            }
+
+            if (!executable.get())
+            {
+                executable = target.GetSharedModule(module_spec);
+                if (executable.get() != target.GetExecutableModulePointer())
+                {
+                    // Don't load dependent images since we are in dyld where we will know
+                    // and find out about all images that are loaded
+                    const bool get_dependent_images = false;
+                    target.SetExecutableModule(executable, get_dependent_images);
+                }
+            }
+        }
+    }
+    return executable;
+}
+
 Error
 DynamicLoaderPOSIXDYLD::ExecutePluginCommand(Args &command, Stream *strm)
 {
@@ -198,6 +237,7 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
     
     entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
     entry_break->SetCallback(EntryBreakpointHit, this, true);
+    entry_break->SetBreakpointKind("shared-library-event");
 }
 
 // The runtime linker has run and initialized the rendezvous structure once the
@@ -229,6 +269,7 @@ DynamicLoaderPOSIXDYLD::SetRendezvousBre
     break_addr = m_rendezvous.GetBreakAddress();
     dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
     dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+    dyld_break->SetBreakpointKind ("shared-library-event");
 }
 
 bool
@@ -267,9 +308,8 @@ DynamicLoaderPOSIXDYLD::RefreshModules()
             FileSpec file(I->path.c_str(), true);
             ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
             if (module_sp.get())
-                new_modules.Append(module_sp);
+                loaded_modules.AppendIfNeeded(module_sp);
         }
-        m_process->GetTarget().ModulesDidLoad(new_modules);
     }
     
     if (m_rendezvous.ModulesDidUnload())
@@ -286,7 +326,7 @@ DynamicLoaderPOSIXDYLD::RefreshModules()
             if (module_sp.get())
                 old_modules.Append(module_sp);
         }
-        m_process->GetTarget().ModulesDidUnload(old_modules);
+        loaded_modules.Remove(old_modules);
     }
 }
 
@@ -308,7 +348,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTr
 
     SymbolContextList target_symbols;
     Target &target = thread.GetProcess()->GetTarget();
-    ModuleList &images = target.GetImages();
+    const ModuleList &images = target.GetImages();
 
     images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
     size_t num_targets = target_symbols.GetSize();

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h Thu Jun  6 19:06:43 2013
@@ -30,7 +30,7 @@ public:
     static void
     Terminate();
 
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic();
 
     static const char *
@@ -64,12 +64,9 @@ public:
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
 
-    virtual const char *
-    GetShortPluginName();
-
     virtual uint32_t
     GetPluginVersion();
 
@@ -93,7 +90,7 @@ protected:
     lldb::addr_t m_entry_point;
 
     /// Auxiliary vector of the inferior process.
-    std::auto_ptr<AuxVector> m_auxv;
+    std::unique_ptr<AuxVector> m_auxv;
 
     /// Enables a breakpoint on a function called by the runtime
     /// linker each time a module is loaded or unloaded.
@@ -158,6 +155,11 @@ protected:
     lldb::addr_t
     GetEntryPoint();
 
+    /// Checks to see if the target module has changed, updates the target
+    /// accordingly and returns the target executable module.
+    lldb::ModuleSP
+    GetTargetExecutable();
+
 private:
     DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
 };

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp Thu Jun  6 19:06:43 2013
@@ -9,6 +9,8 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Target.h"
 
 #include "DynamicLoaderStatic.h"
@@ -93,10 +95,13 @@ DynamicLoaderStatic::DidLaunch ()
 void
 DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
 {
-    ModuleList &module_list = m_process->GetTarget().GetImages();
+    const ModuleList &module_list = m_process->GetTarget().GetImages();
     
     ModuleList loaded_module_list;
 
+    // Disable JIT for static dynamic loader targets
+    m_process->SetCanJIT(false);
+
     Mutex::Locker mutex_locker(module_list.GetMutex());
     
     const size_t num_modules = module_list.GetSize();
@@ -141,8 +146,7 @@ DynamicLoaderStatic::LoadAllImagesAtFile
         }
     }
 
-    if (loaded_module_list.GetSize())
-        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+    m_process->GetTarget().ModulesDidLoad (loaded_module_list);
 }
 
 ThreadPlanSP
@@ -174,10 +178,11 @@ DynamicLoaderStatic::Terminate()
 }
 
 
-const char *
+lldb_private::ConstString
 DynamicLoaderStatic::GetPluginNameStatic()
 {
-    return "dynamic-loader.static";
+    static ConstString g_name("static");
+    return g_name;
 }
 
 const char *
@@ -190,15 +195,9 @@ DynamicLoaderStatic::GetPluginDescriptio
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 DynamicLoaderStatic::GetPluginName()
 {
-    return "DynamicLoaderStatic";
-}
-
-const char *
-DynamicLoaderStatic::GetShortPluginName()
-{
     return GetPluginNameStatic();
 }
 

Modified: lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h Thu Jun  6 19:06:43 2013
@@ -37,7 +37,7 @@ public:
     static void
     Terminate();
 
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic();
 
     static const char *
@@ -72,12 +72,9 @@ public:
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName();
 
-    virtual const char *
-    GetShortPluginName();
-
     virtual uint32_t
     GetPluginVersion();
 

Modified: lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Thu Jun  6 19:06:43 2013
@@ -16,6 +16,8 @@
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Interpreter/OptionValueArray.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
 #include "lldb/Symbol/UnwindPlan.h"
 
 #include "Plugins/Process/Utility/ARMDefines.h"
@@ -23,7 +25,7 @@
 #include "Utility/ARM_DWARF_Registers.h"
 
 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
-                                     // and CountTrailingZeros_32 function
+                                     // and countTrailingZeros function
 
 using namespace lldb;
 using namespace lldb_private;
@@ -45,7 +47,7 @@ using namespace lldb_private;
 static uint32_t
 CountITSize (uint32_t ITMask) {
     // First count the trailing zeros of the IT mask.
-    uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
+    uint32_t TZ = llvm::countTrailingZeros(ITMask);
     if (TZ > 3)
     {
         printf("Encoding error: IT Mask '0000'\n");
@@ -172,10 +174,11 @@ EmulateInstructionARM::Terminate ()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
-const char *
+ConstString
 EmulateInstructionARM::GetPluginNameStatic ()
 {
-    return "lldb.emulate-instruction.arm";
+    static ConstString g_name("arm");
+    return g_name;
 }
 
 const char *
@@ -191,14 +194,14 @@ EmulateInstructionARM::CreateInstance (c
     {
         if (arch.GetTriple().getArch() == llvm::Triple::arm)
         {
-            std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
             
             if (emulate_insn_ap.get())
                 return emulate_insn_ap.release();
         }
         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
         {
-            std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
+            std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
             
             if (emulate_insn_ap.get())
                 return emulate_insn_ap.release();
@@ -12779,7 +12782,7 @@ EmulateInstructionARM::GetThumbOpcodeFor
         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
-        { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
+        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"}, 
                   
         //----------------------------------------------------------------------
@@ -12999,7 +13002,6 @@ EmulateInstructionARM::CurrentCond (cons
 {
     switch (m_opcode_mode)
     {
-    default:
     case eModeInvalid:
         break;
 
@@ -13611,9 +13613,7 @@ EmulateInstructionARM::CreateFunctionEnt
     // All other registers are the same.
     
     unwind_plan.SetSourceName ("EmulateInstructionARM");
+    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
     return true;
 }
-
-
-
-                                           

Modified: lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulateInstructionARM.h Thu Jun  6 19:06:43 2013
@@ -11,8 +11,8 @@
 #define lldb_EmulateInstructionARM_h_
 
 #include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Interpreter/NamedOptionValue.h"
 #include "Plugins/Process/Utility/ARMDefines.h"
 
 namespace lldb_private {
@@ -68,7 +68,7 @@ public:
     static void
     Terminate ();
 
-    static const char *
+    static lldb_private::ConstString
     GetPluginNameStatic ();
     
     static const char *
@@ -90,22 +90,13 @@ public:
                 
             case eInstructionTypeAll:
                 return false;
-                
-            default:
-                break;
         }
         return false;
     }
 
-    virtual const char *
+    virtual lldb_private::ConstString
     GetPluginName()
     {
-        return "EmulateInstructionARM";
-    }
-
-    virtual const char *
-    GetShortPluginName()
-    {
         return GetPluginNameStatic();
     }
 

Modified: lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.cpp Thu Jun  6 19:06:43 2013
@@ -11,6 +11,8 @@
 
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/Scalar.h"
+#include "lldb/Interpreter/OptionValueArray.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/RegisterContext.h"
 

Modified: lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/Instruction/ARM/EmulationStateARM.h Thu Jun  6 19:06:43 2013
@@ -14,7 +14,6 @@
 
 #include "lldb/Core/EmulateInstruction.h"
 #include "lldb/Core/Opcode.h"
-#include "lldb/Interpreter/NamedOptionValue.h"
 
 class EmulationStateARM {
 public: 

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Thu Jun  6 19:06:43 2013
@@ -19,6 +19,8 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectMemory.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
@@ -30,9 +32,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static const char *pluginName = "ItaniumABILanguageRuntime";
-static const char *pluginDesc = "Itanium ABI for the C++ language";
-static const char *pluginShort = "language.itanium";
 static const char *vtable_demangled_prefix = "vtable for ";
 
 bool
@@ -57,6 +56,8 @@ ItaniumABILanguageRuntime::GetDynamicTyp
     // start of the value object which holds the dynamic type.
     //
     
+    class_type_or_name.Clear();
+    
     // Only a pointer or reference type can have a different dynamic and static type:
     if (CouldHaveDynamicValue (in_value))
     {
@@ -86,10 +87,10 @@ ItaniumABILanguageRuntime::GetDynamicTyp
             return false;
         }
         
-        uint32_t offset_ptr = 0;
-        lldb::addr_t vtable_address_point = data.GetAddress (&offset_ptr);
+        lldb::offset_t offset = 0;
+        lldb::addr_t vtable_address_point = data.GetAddress (&offset);
             
-        if (offset_ptr == 0)
+        if (offset == 0)
             return false;
         
         // Now find the symbol that contains this address:
@@ -107,9 +108,9 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                     const char *name = symbol->GetMangled().GetDemangledName().AsCString();
                     if (strstr(name, vtable_demangled_prefix) == name)
                     {
-                        LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+                        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
                         if (log)
-                            log->Printf ("0x%16.16llx: static-type = '%s' has vtable symbol '%s'\n",
+                            log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
                                          original_ptr,
                                          in_value.GetTypeName().GetCString(),
                                          name);
@@ -147,14 +148,14 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                         if (num_matches == 0)
                         {
                             if (log)
-                                log->Printf("0x%16.16llx: is not dynamic\n", original_ptr);
+                                log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
                             return false;
                         }
                         if (num_matches == 1)
                         {
                             type_sp = class_types.GetTypeAtIndex(0);
                             if (log)
-                                log->Printf ("0x%16.16llx: static-type = '%s' has dynamic type: uid={0x%llx}, type-name='%s'\n",
+                                log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 "}, type-name='%s'\n",
                                              original_ptr,
                                              in_value.GetTypeName().AsCString(),
                                              type_sp->GetID(),
@@ -173,7 +174,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                                     if (type_sp)
                                     {
                                         if (log)
-                                            log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types: uid={0x%llx}, type-name='%s'\n",
+                                            log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n",
                                                          original_ptr,
                                                          in_value.GetTypeName().AsCString(),
                                                          type_sp->GetID(),
@@ -190,7 +191,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                                     if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType()))
                                     {
                                         if (log)
-                                            log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%llx}, type-name='%s'\n",
+                                            log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
                                                          original_ptr,
                                                          in_value.GetTypeName().AsCString(),
                                                          type_sp->GetID(),
@@ -204,7 +205,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                             if (i == num_matches)
                             {
                                 if (log)
-                                    log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
+                                    log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
                                                  original_ptr,
                                                  in_value.GetTypeName().AsCString());
                                 return false;
@@ -251,8 +252,8 @@ ItaniumABILanguageRuntime::GetDynamicTyp
                                 return false;
                             }
                             
-                            offset_ptr = 0;
-                            int64_t offset_to_top = data.GetMaxS64(&offset_ptr, process->GetAddressByteSize());
+                            offset = 0;
+                            int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
                             
                             // So the dynamic type is a value that starts at offset_to_top
                             // above the original address.
@@ -269,7 +270,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
         }
     }
     
-    return false;
+    return class_type_or_name.IsEmpty() == false;
 }
 
 bool
@@ -302,8 +303,8 @@ ItaniumABILanguageRuntime::CreateInstanc
 void
 ItaniumABILanguageRuntime::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "Itanium ABI for the C++ language",
                                    CreateInstance);    
 }
 
@@ -313,19 +314,20 @@ ItaniumABILanguageRuntime::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+ItaniumABILanguageRuntime::GetPluginNameStatic()
+{
+    static ConstString g_name("itanium");
+    return g_name;
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 ItaniumABILanguageRuntime::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-ItaniumABILanguageRuntime::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t
@@ -334,10 +336,6 @@ ItaniumABILanguageRuntime::GetPluginVers
     return 1;
 }
 
-static const char *exception_names[] = { "__cxa_begin_catch", "__cxa_throw", "__cxa_rethrow", "__cxa_allocate_exception"};
-static const int num_throw_names = 3;
-static const int num_expression_throw_names = 1;
-
 BreakpointResolverSP
 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
 {
@@ -347,49 +345,70 @@ ItaniumABILanguageRuntime::CreateExcepti
 BreakpointResolverSP
 ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
 {
-    BreakpointResolverSP resolver_sp;
-    static const int total_expressions = sizeof (exception_names)/sizeof (char *);
-    
     // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
     // anything better with predicting unwinding the expression parser does.  So we have two forms of the exception
     // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
     // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
+    static const char *g_catch_name = "__cxa_begin_catch";
+    static const char *g_throw_name1 = "__cxa_throw";
+    static const char *g_throw_name2 = "__cxa_rethrow";
+    static const char *g_exception_throw_name = "__cxa_allocate_exception";
+    std::vector<const char *> exception_names;
+    exception_names.reserve(4);
+    if (catch_bp)
+        exception_names.push_back(g_catch_name);
+
+    if (throw_bp)
+    {
+        exception_names.push_back(g_throw_name1);
+        exception_names.push_back(g_throw_name2);
+    }
+
+    if (for_expressions)
+        exception_names.push_back(g_exception_throw_name);
     
-    uint32_t num_expressions;
-    if (catch_bp && throw_bp)
+    BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
+                                                                  exception_names.data(),
+                                                                  exception_names.size(),
+                                                                  eFunctionNameTypeBase,
+                                                                  eLazyBoolNo));
+
+    return resolver_sp;
+}
+
+
+
+lldb::SearchFilterSP
+ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
+{
+    Target &target = m_process->GetTarget();
+
+    if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
     {
-        if (for_expressions)
-            num_expressions = total_expressions;
-        else
-            num_expressions = total_expressions - num_expression_throw_names;
-            
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names,
-                                                       num_expressions,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+        // Limit the number of modules that are searched for these breakpoints for
+        // Apple binaries.
+        FileSpecList filter_modules;
+        filter_modules.Append(FileSpec("libc++abi.dylib", false));
+        filter_modules.Append(FileSpec("libSystem.B.dylib", false));
+        return target.GetSearchFilterForModuleList(&filter_modules);
     }
-    else if (throw_bp)
+    else
     {
-        if (for_expressions)
-            num_expressions = num_throw_names - num_expression_throw_names;
-        else
-            num_expressions = num_throw_names;
-            
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names + 1,
-                                                       num_expressions,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+        return LanguageRuntime::CreateExceptionSearchFilter();
     }
-    else if (catch_bp)
-        resolver_sp.reset (new BreakpointResolverName (bkpt,
-                                                       exception_names,
-                                                       total_expressions - num_throw_names,
-                                                       eFunctionNameTypeBase,
-                                                       eLazyBoolNo));
+}
 
-    return resolver_sp;
+lldb::BreakpointSP
+ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
+                                                      bool throw_bp,
+                                                      bool for_expressions,
+                                                      bool is_internal)
+{
+    Target &target = m_process->GetTarget();
+    FileSpecList filter_modules;
+    BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
+    SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
+    return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
 }
 
 void
@@ -406,17 +425,16 @@ ItaniumABILanguageRuntime::SetExceptionB
     // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
     // stop at exception allocation as well.
     
-    if (!m_cxx_exception_bp_sp)
+    if (m_cxx_exception_bp_sp)
     {
-        Target &target = m_process->GetTarget();
-        
-        BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
-        SearchFilterSP filter_sp = target.GetSearchFilterForModule(NULL);
-        
-        m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
+        m_cxx_exception_bp_sp->SetEnabled (true);
     }
     else
-        m_cxx_exception_bp_sp->SetEnabled (true);
+    {
+        m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
+        if (m_cxx_exception_bp_sp)
+            m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
+    }
     
 }
 
@@ -426,7 +444,7 @@ ItaniumABILanguageRuntime::ClearExceptio
     if (!m_process)
         return;
     
-    if (m_cxx_exception_bp_sp.get())
+    if (m_cxx_exception_bp_sp)
     {
         m_cxx_exception_bp_sp->SetEnabled (false);
     }    

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h Thu Jun  6 19:06:43 2013
@@ -52,15 +52,15 @@ namespace lldb_private {
         static lldb_private::LanguageRuntime *
         CreateInstance (Process *process, lldb::LanguageType language);
         
+        static lldb_private::ConstString
+        GetPluginNameStatic();
+
         //------------------------------------------------------------------
         // PluginInterface protocol
         //------------------------------------------------------------------
-        virtual const char *
+        virtual lldb_private::ConstString
         GetPluginName();
         
-        virtual const char *
-        GetShortPluginName();
-        
         virtual uint32_t
         GetPluginVersion();
         
@@ -72,14 +72,24 @@ namespace lldb_private {
         
         virtual bool
         ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
-        
-    protected:
+
         virtual lldb::BreakpointResolverSP
         CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
+        
+        virtual lldb::SearchFilterSP
+        CreateExceptionSearchFilter ();
 
-        virtual lldb::BreakpointResolverSP
+    protected:
+
+        lldb::BreakpointResolverSP
         CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions);
 
+        lldb::BreakpointSP
+        CreateExceptionBreakpoint(bool catch_bp,
+                                  bool throw_bp,
+                                  bool for_expressions,
+                                  bool is_internal);
+        
     private:
         ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
         

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Thu Jun  6 19:06:43 2013
@@ -38,6 +38,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+#define PO_FUNCTION_TIMEOUT_USEC 15*1000*1000
+
 bool
 AppleObjCRuntime::GetObjectDescription (Stream &str, ValueObject &valobj)
 {
@@ -134,17 +136,19 @@ AppleObjCRuntime::GetObjectDescription (
     lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
     func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
 
-    bool unwind_on_error = true;
-    bool try_all_threads = true;
-    bool stop_others = true;
+    const bool unwind_on_error = true;
+    const bool try_all_threads = true;
+    const bool stop_others = true;
+    const bool ignore_breakpoints = true;
     
     ExecutionResults results = func.ExecuteFunction (exe_ctx, 
                                                      &wrapper_struct_addr, 
                                                      error_stream, 
                                                      stop_others, 
-                                                     0 /* no timeout */,
+                                                     PO_FUNCTION_TIMEOUT_USEC /* 15 secs timeout */,
                                                      try_all_threads, 
-                                                     unwind_on_error, 
+                                                     unwind_on_error,
+                                                     ignore_breakpoints,
                                                      ret);
     if (results != eExecutionCompleted)
     {
@@ -168,12 +172,36 @@ AppleObjCRuntime::GetObjectDescription (
     return cstr_len > 0;
 }
 
+lldb::ModuleSP
+AppleObjCRuntime::GetObjCModule ()
+{
+    ModuleSP module_sp (m_objc_module_wp.lock());
+    if (module_sp)
+        return module_sp;
+
+    Process *process = GetProcess();
+    if (process)
+    {
+        const ModuleList& modules = process->GetTarget().GetImages();
+        for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
+        {
+            module_sp = modules.GetModuleAtIndex(idx);
+            if (AppleObjCRuntime::AppleIsModuleObjCLibrary(module_sp))
+            {
+                m_objc_module_wp = module_sp;
+                return module_sp;
+            }
+        }
+    }
+    return ModuleSP();
+}
+
 Address *
 AppleObjCRuntime::GetPrintForDebuggerAddr()
 {
     if (!m_PrintForDebugger_addr.get())
     {
-        ModuleList &modules = m_process->GetTarget().GetImages();
+        const ModuleList &modules = m_process->GetTarget().GetImages();
         
         SymbolContextList contexts;
         SymbolContext context;
@@ -211,15 +239,17 @@ AppleObjCRuntime::GetDynamicTypeAndAddre
 bool
 AppleObjCRuntime::AppleIsModuleObjCLibrary (const ModuleSP &module_sp)
 {
-    const FileSpec &module_file_spec = module_sp->GetFileSpec();
-    static ConstString ObjCName ("libobjc.A.dylib");
-    
-    if (module_file_spec)
+    if (module_sp)
     {
-        if (module_file_spec.GetFilename() == ObjCName)
-            return true;
+        const FileSpec &module_file_spec = module_sp->GetFileSpec();
+        static ConstString ObjCName ("libobjc.A.dylib");
+        
+        if (module_file_spec)
+        {
+            if (module_file_spec.GetFilename() == ObjCName)
+                return true;
+        }
     }
-    
     return false;
 }
 
@@ -263,7 +293,7 @@ AppleObjCRuntime::GetObjCVersion (Proces
         return eObjC_VersionUnknown;
         
     Target &target = process->GetTarget();
-    ModuleList &target_modules = target.GetImages();
+    const ModuleList &target_modules = target.GetImages();
     Mutex::Locker modules_locker(target_modules.GetMutex());
     
     size_t num_images = target_modules.GetSize();
@@ -305,11 +335,15 @@ AppleObjCRuntime::SetExceptionBreakpoint
     const bool is_internal = true;
     
     if (!m_objc_exception_bp_sp)
+    {
         m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint (m_process->GetTarget(),
                                                                             GetLanguageType(),
                                                                             catch_bp, 
                                                                             throw_bp, 
                                                                             is_internal);
+        if (m_objc_exception_bp_sp)
+            m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
+    }
     else
         m_objc_exception_bp_sp->SetEnabled(true);
 }
@@ -361,3 +395,21 @@ AppleObjCRuntime::CalculateHasNewLiteral
     else
         return false;
 }
+
+lldb::SearchFilterSP
+AppleObjCRuntime::CreateExceptionSearchFilter ()
+{
+    Target &target = m_process->GetTarget();
+    
+    if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
+    {
+        FileSpecList filter_modules;
+        filter_modules.Append(FileSpec("libobjc.A.dylib", false));
+        return target.GetSearchFilterForModuleList(&filter_modules);
+    }
+    else
+    {
+        return LanguageRuntime::CreateExceptionSearchFilter();
+    }
+}
+

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Thu Jun  6 19:06:43 2013
@@ -63,29 +63,10 @@ public:
     virtual lldb::ThreadPlanSP
     GetStepThroughTrampolinePlan (Thread &thread, bool stop_others);
     
-    virtual bool
-    IsValidISA(ObjCISA isa)
-    {
-        return false;
-    }
-    
-    virtual ObjCISA
-    GetISA(ValueObject& valobj)
-    {
-        return 0;
-    }
-    
-    virtual ConstString
-    GetActualTypeName(ObjCISA isa)
-    {
-        return ConstString(NULL);
-    }
-    
-    virtual ObjCISA
-    GetParentClass(ObjCISA isa)
-    {
-        return 0;
-    }
+    // Get the "libobjc.A.dylib" module from the current target if we can find
+    // it, also cache it once it is found to ensure quick lookups.
+    lldb::ModuleSP
+    GetObjCModule ();
     
     //------------------------------------------------------------------
     // Static Functions
@@ -115,20 +96,27 @@ public:
     
     virtual bool
     ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
+    
+    virtual lldb::SearchFilterSP
+    CreateExceptionSearchFilter ();
+    
 protected:
     Address *
     GetPrintForDebuggerAddr();
     
-    std::auto_ptr<Address>  m_PrintForDebugger_addr;
+    std::unique_ptr<Address>  m_PrintForDebugger_addr;
     bool m_read_objc_library;
-    std::auto_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
+    std::unique_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
     lldb::BreakpointSP m_objc_exception_bp_sp;
+    lldb::ModuleWP m_objc_module_wp;
 
-    AppleObjCRuntime(Process *process) : 
+    AppleObjCRuntime(Process *process) :
         lldb_private::ObjCLanguageRuntime(process),
         m_read_objc_library (false),
-        m_objc_trampoline_handler_ap(NULL)
-     { } // Call CreateInstance instead.
+        m_objc_trampoline_handler_ap ()
+     {
+         // Call CreateInstance instead.
+     }
 };
     
 } // namespace lldb_private

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Thu Jun  6 19:06:43 2013
@@ -9,6 +9,7 @@
 
 #include "AppleObjCRuntimeV1.h"
 #include "AppleObjCTrampolineHandler.h"
+#include "AppleObjCTypeVendor.h"
 
 #include "llvm/Support/MachO.h"
 #include "clang/AST/Type.h"
@@ -24,6 +25,7 @@
 #include "lldb/Expression/ClangFunction.h"
 #include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -35,17 +37,33 @@
 using namespace lldb;
 using namespace lldb_private;
 
-static const char *pluginName = "AppleObjCRuntimeV1";
-static const char *pluginDesc = "Apple Objective C Language Runtime - Version 1";
-static const char *pluginShort = "language.apple.objc.v1";
+AppleObjCRuntimeV1::AppleObjCRuntimeV1(Process *process) :
+    AppleObjCRuntime (process),
+    m_hash_signature (),
+    m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS)
+{
+}
 
+// for V1 runtime we just try to return a class name as that is the minimum level of support
+// required for the data formatters to work
 bool
-AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value, 
+AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value,
                                              lldb::DynamicValueType use_dynamic, 
                                              TypeAndOrName &class_type_or_name, 
                                              Address &address)
 {
-    return false;
+    class_type_or_name.Clear();
+    if (CouldHaveDynamicValue(in_value))
+    {
+        auto class_descriptor(GetClassDescriptor(in_value));
+        if (class_descriptor && class_descriptor->IsValid() && class_descriptor->GetClassName())
+        {
+            const addr_t object_ptr = in_value.GetPointerValue();
+            address.SetRawAddress(object_ptr);
+            class_type_or_name.SetName(class_descriptor->GetClassName());
+        }
+    }
+    return class_type_or_name.IsEmpty() == false;
 }
 
 //------------------------------------------------------------------
@@ -69,11 +87,12 @@ AppleObjCRuntimeV1::CreateInstance (Proc
         return NULL;
 }
 
+
 void
 AppleObjCRuntimeV1::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "Apple Objective C Language Runtime - Version 1",
                                    CreateInstance);    
 }
 
@@ -83,19 +102,20 @@ AppleObjCRuntimeV1::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+AppleObjCRuntimeV1::GetPluginNameStatic()
+{
+    static ConstString g_name("apple-objc-v1");
+    return g_name;
+}
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+ConstString
 AppleObjCRuntimeV1::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-AppleObjCRuntimeV1::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t
@@ -126,7 +146,7 @@ struct BufStruct {
 ClangUtilityFunction *
 AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
 {
-    std::auto_ptr<BufStruct> buf(new BufStruct);
+    std::unique_ptr<BufStruct> buf(new BufStruct);
     
     assert(snprintf(&buf->contents[0], sizeof(buf->contents),
                     "struct __objc_class                                                    \n"
@@ -152,3 +172,311 @@ AppleObjCRuntimeV1::CreateObjectChecker(
 
     return new ClangUtilityFunction(buf->contents, name);
 }
+
+// this code relies on the assumption that an Objective-C object always starts
+// with an ISA at offset 0.
+//ObjCLanguageRuntime::ObjCISA
+//AppleObjCRuntimeV1::GetISA(ValueObject& valobj)
+//{
+////    if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC)
+////        return 0;
+//    
+//    // if we get an invalid VO (which might still happen when playing around
+//    // with pointers returned by the expression parser, don't consider this
+//    // a valid ObjC object)
+//    if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
+//        return 0;
+//    
+//    addr_t isa_pointer = valobj.GetPointerValue();
+//    
+//    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+//    
+//    Process *process = exe_ctx.GetProcessPtr();
+//    if (process)
+//    {
+//        uint8_t pointer_size = process->GetAddressByteSize();
+//        
+//        Error error;
+//        return process->ReadUnsignedIntegerFromMemory (isa_pointer,
+//                                                       pointer_size,
+//                                                       0,
+//                                                       error);
+//    }
+//    return 0;
+//}
+
+AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer)
+{
+    Initialize (isa_pointer.GetValueAsUnsigned(0),
+                isa_pointer.GetProcessSP());
+}
+
+AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp)
+{
+    Initialize (isa, process_sp);
+}
+
+void
+AppleObjCRuntimeV1::ClassDescriptorV1::Initialize (ObjCISA isa, lldb::ProcessSP process_sp)
+{
+    if (!isa || !process_sp)
+    {
+        m_valid = false;
+        return;
+    }
+    
+    m_valid = true;
+    
+    Error error;
+    
+    m_isa = process_sp->ReadPointerFromMemory(isa, error);
+    
+    if (error.Fail())
+    {
+        m_valid = false;
+        return;
+    }
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    
+    if (!IsPointerValid(m_isa,ptr_size))
+    {
+        m_valid = false;
+        return;
+    }
+
+    m_parent_isa = process_sp->ReadPointerFromMemory(m_isa + ptr_size,error);
+    
+    if (error.Fail())
+    {
+        m_valid = false;
+        return;
+    }
+    
+    if (!IsPointerValid(m_parent_isa,ptr_size,true))
+    {
+        m_valid = false;
+        return;
+    }
+    
+    lldb::addr_t name_ptr = process_sp->ReadPointerFromMemory(m_isa + 2 * ptr_size,error);
+    
+    if (error.Fail())
+    {
+        m_valid = false;
+        return;
+    }
+    
+    lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
+    
+    size_t count = process_sp->ReadCStringFromMemory(name_ptr, (char*)buffer_sp->GetBytes(), 1024, error);
+    
+    if (error.Fail())
+    {
+        m_valid = false;
+        return;
+    }
+    
+    if (count)
+        m_name = ConstString((char*)buffer_sp->GetBytes());
+    else
+        m_name = ConstString();
+    
+    m_instance_size = process_sp->ReadUnsignedIntegerFromMemory(m_isa + 5 * ptr_size, ptr_size, 0, error);
+    
+    if (error.Fail())
+    {
+        m_valid = false;
+        return;
+    }
+    
+    m_process_wp = lldb::ProcessWP(process_sp);
+}
+
+AppleObjCRuntime::ClassDescriptorSP
+AppleObjCRuntimeV1::ClassDescriptorV1::GetSuperclass ()
+{
+    if (!m_valid)
+        return AppleObjCRuntime::ClassDescriptorSP();
+    ProcessSP process_sp = m_process_wp.lock();
+    if (!process_sp)
+        return AppleObjCRuntime::ClassDescriptorSP();
+    return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp));
+}
+
+bool
+AppleObjCRuntimeV1::ClassDescriptorV1::Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+                                                 std::function <bool (const char *, const char *)> const &instance_method_func,
+                                                 std::function <bool (const char *, const char *)> const &class_method_func,
+                                                 std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
+{
+    return false;
+}
+
+lldb::addr_t
+AppleObjCRuntimeV1::GetISAHashTablePointer ()
+{
+    if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
+    {
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (!objc_module_sp)
+            return LLDB_INVALID_ADDRESS;
+        
+        static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
+        
+        const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData);
+        if (symbol)
+        {
+            Process *process = GetProcess();
+            if (process)
+            {
+
+                lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+            
+                if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS)
+                {
+                    Error error;
+                    lldb::addr_t objc_debug_class_hash_ptr = process->ReadPointerFromMemory(objc_debug_class_hash_addr, error);
+                    if (objc_debug_class_hash_ptr != 0 &&
+                        objc_debug_class_hash_ptr != LLDB_INVALID_ADDRESS)
+                    {
+                        m_isa_hash_table_ptr = objc_debug_class_hash_ptr;
+                    }
+                }
+            }
+        }
+    }
+    return m_isa_hash_table_ptr;
+}
+
+void
+AppleObjCRuntimeV1::UpdateISAToDescriptorMapIfNeeded()
+{
+    // TODO: implement HashTableSignature...
+    Process *process = GetProcess();
+    
+    if (process)
+    {
+        // Update the process stop ID that indicates the last time we updated the
+        // map, wether it was successful or not.
+        m_isa_to_descriptor_stop_id = process->GetStopID();
+        
+        Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+        
+        ProcessSP process_sp = process->shared_from_this();
+        
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (!objc_module_sp)
+            return;
+        
+        uint32_t isa_count = 0;
+        
+        lldb::addr_t hash_table_ptr = GetISAHashTablePointer ();
+        if (hash_table_ptr != LLDB_INVALID_ADDRESS)
+        {
+            // Read the NXHashTable struct:
+            //
+            // typedef struct {
+            //     const NXHashTablePrototype *prototype;
+            //     unsigned   count;
+            //     unsigned   nbBuckets;
+            //     void       *buckets;
+            //     const void *info;
+            // } NXHashTable;
+
+            Error error;
+            DataBufferHeap buffer(1024, 0);
+            if (process->ReadMemory(hash_table_ptr, buffer.GetBytes(), 20, error) == 20)
+            {
+                const uint32_t addr_size = m_process->GetAddressByteSize();
+                const ByteOrder byte_order = m_process->GetByteOrder();
+                DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
+                lldb::offset_t offset = addr_size; // Skip prototype
+                const uint32_t count = data.GetU32(&offset);
+                const uint32_t num_buckets = data.GetU32(&offset);
+                const addr_t buckets_ptr = data.GetPointer(&offset);
+                if (m_hash_signature.NeedsUpdate (count, num_buckets, buckets_ptr))
+                {
+                    m_hash_signature.UpdateSignature (count, num_buckets, buckets_ptr);
+
+                    const uint32_t data_size = num_buckets * 2 * sizeof(uint32_t);
+                    buffer.SetByteSize(data_size);
+                    
+                    if (process->ReadMemory(buckets_ptr, buffer.GetBytes(), data_size, error) == data_size)
+                    {
+                        data.SetData(buffer.GetBytes(), buffer.GetByteSize(), byte_order);
+                        offset = 0;
+                        for (uint32_t bucket_idx = 0; bucket_idx < num_buckets; ++bucket_idx)
+                        {
+                            const uint32_t bucket_isa_count = data.GetU32 (&offset);
+                            const lldb::addr_t bucket_data = data.GetU32 (&offset);
+                            
+
+                            if (bucket_isa_count == 0)
+                                continue;
+                            
+                            isa_count += bucket_isa_count;
+
+                            ObjCISA isa;
+                            if (bucket_isa_count == 1)
+                            {
+                                // When we only have one entry in the bucket, the bucket data is the "isa"
+                                isa = bucket_data;
+                                if (isa)
+                                {
+                                    if (!ISAIsCached(isa))
+                                    {
+                                        ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
+                                        
+                                        if (log && log->GetVerbose())
+                                            log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
+                                        
+                                        AddClass (isa, descriptor_sp);
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                // When we have more than one entry in the bucket, the bucket data is a pointer
+                                // to an array of "isa" values
+                                addr_t isa_addr = bucket_data;
+                                for (uint32_t isa_idx = 0; isa_idx < bucket_isa_count; ++isa_idx, isa_addr += addr_size)
+                                {
+                                    isa = m_process->ReadPointerFromMemory(isa_addr, error);
+
+                                    if (isa && isa != LLDB_INVALID_ADDRESS)
+                                    {
+                                        if (!ISAIsCached(isa))
+                                        {
+                                            ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
+                                            
+                                            if (log && log->GetVerbose())
+                                                log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
+                                            
+                                            AddClass (isa, descriptor_sp);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }        
+    }
+    else
+    {
+        m_isa_to_descriptor_stop_id = UINT32_MAX;
+    }
+}
+
+TypeVendor *
+AppleObjCRuntimeV1::GetTypeVendor()
+{
+    if (!m_type_vendor_ap.get())
+        m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
+    
+    return m_type_vendor_ap.get();
+}

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Thu Jun  6 19:06:43 2013
@@ -24,6 +24,72 @@ class AppleObjCRuntimeV1 :
         public AppleObjCRuntime
 {
 public:
+    
+    class ClassDescriptorV1 : public ObjCLanguageRuntime::ClassDescriptor
+    {
+    public:
+        ClassDescriptorV1 (ValueObject &isa_pointer);
+        ClassDescriptorV1 (ObjCISA isa, lldb::ProcessSP process_sp);
+        
+        virtual ConstString
+        GetClassName ()
+        {
+            return m_name;
+        }
+        
+        virtual ClassDescriptorSP
+        GetSuperclass ();
+        
+        virtual bool
+        IsValid ()
+        {
+            return m_valid;
+        }
+        
+        // v1 does not support tagged pointers
+        virtual bool
+        GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+                              uint64_t* value_bits = NULL,
+                              uint64_t* payload = NULL)
+        {
+            return false;
+        }
+        
+        virtual uint64_t
+        GetInstanceSize ()
+        {
+            return m_instance_size;
+        }
+        
+        virtual ObjCISA
+        GetISA ()
+        {
+            return m_isa;
+        }
+        
+        virtual bool
+        Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+                  std::function <bool (const char *, const char *)> const &instance_method_func,
+                  std::function <bool (const char *, const char *)> const &class_method_func,
+                  std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func);
+        
+        virtual
+        ~ClassDescriptorV1 ()
+        {}
+        
+    protected:
+        void
+        Initialize (ObjCISA isa, lldb::ProcessSP process_sp);
+        
+    private:
+        ConstString m_name;
+        ObjCISA m_isa;
+        ObjCISA m_parent_isa;
+        bool m_valid;
+        lldb::ProcessWP m_process_wp;
+        uint64_t m_instance_size;
+    };
+    
     virtual ~AppleObjCRuntimeV1() { }
     
     // These are generic runtime functions:
@@ -48,15 +114,15 @@ public:
     static lldb_private::LanguageRuntime *
     CreateInstance (Process *process, lldb::LanguageType language);
     
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual ConstString
     GetPluginName();
     
-    virtual const char *
-    GetShortPluginName();
-    
     virtual uint32_t
     GetPluginVersion();
     
@@ -66,38 +132,62 @@ public:
         return eAppleObjC_V1;
     }
     
-    virtual bool
-    IsValidISA(ObjCISA isa)
-    {
-        return false;
-    }
-    
-    virtual ObjCISA
-    GetISA(ValueObject& valobj)
-    {
-        return 0;
-    }
+    virtual void
+    UpdateISAToDescriptorMapIfNeeded();
     
-    virtual ConstString
-    GetActualTypeName(ObjCISA isa)
-    {
-        return ConstString(NULL);
-    }
-    
-    virtual ObjCISA
-    GetParentClass(ObjCISA isa)
-    {
-        return 0;
-    }
+    virtual TypeVendor *
+    GetTypeVendor();
 
 protected:
     virtual lldb::BreakpointResolverSP
     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
-            
+    
+    
+    class HashTableSignature
+    {
+    public:
+        HashTableSignature () :
+            m_count (0),
+            m_num_buckets (0),
+            m_buckets_ptr (LLDB_INVALID_ADDRESS)
+        {
+        }
+        
+        bool
+        NeedsUpdate (uint32_t count,
+                     uint32_t num_buckets,
+                     lldb::addr_t buckets_ptr)
+        {
+            return m_count       != count       ||
+                   m_num_buckets != num_buckets ||
+                   m_buckets_ptr != buckets_ptr ;
+        }
+        
+        void
+        UpdateSignature (uint32_t count,
+                         uint32_t num_buckets,
+                         lldb::addr_t buckets_ptr)
+        {
+            m_count = count;
+            m_num_buckets = num_buckets;
+            m_buckets_ptr = buckets_ptr;
+        }
+
+    protected:
+        uint32_t m_count;
+        uint32_t m_num_buckets;
+        lldb::addr_t m_buckets_ptr;
+    };
+    
+
+    lldb::addr_t
+    GetISAHashTablePointer ();
+    
+    HashTableSignature m_hash_signature;
+    lldb::addr_t m_isa_hash_table_ptr;
+    std::unique_ptr<TypeVendor> m_type_vendor_ap;
 private:
-    AppleObjCRuntimeV1(Process *process) : 
-        lldb_private::AppleObjCRuntime (process)
-     { } // Call CreateInstance instead.
+    AppleObjCRuntimeV1(Process *process);
 };
     
 } // namespace lldb_private

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Jun  6 19:06:43 2013
@@ -7,17 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/lldb-python.h"
 
 #include <string>
 #include <vector>
-#include <memory>
 #include <stdint.h>
 
 #include "lldb/lldb-enumerations.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Symbol/ClangASTType.h"
 
-#include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
@@ -25,11 +24,17 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Scalar.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Expression/ClangFunction.h"
 #include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
@@ -37,212 +42,324 @@
 #include "lldb/Target/Thread.h"
 
 #include "AppleObjCRuntimeV2.h"
-#include "AppleObjCSymbolVendor.h"
+#include "AppleObjCTypeVendor.h"
 #include "AppleObjCTrampolineHandler.h"
 
 #include <vector>
 
 using namespace lldb;
 using namespace lldb_private;
-    
 
-static const char *pluginName = "AppleObjCRuntimeV2";
-static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2";
-static const char *pluginShort = "language.apple.objc.v2";
-
-
-const char *AppleObjCRuntimeV2::g_find_class_name_function_name = "__lldb_apple_objc_v2_find_class_name";
-const char *AppleObjCRuntimeV2::g_find_class_name_function_body = "                               \n\
-extern \"C\"                                                                                      \n\
-{                                                                                                 \n\
-    extern void *gdb_class_getClass (void *objc_class);                                           \n\
-    extern void *class_getName(void *objc_class);                                                 \n\
-    extern int printf(const char *format, ...);                                                   \n\
-    extern unsigned char class_isMetaClass (void *objc_class);                                    \n\
-}                                                                                                 \n\
-                                                                                                  \n\
-struct __lldb_objc_object {                                                                       \n\
-    void *isa;                                                                                    \n\
-};                                                                                                \n\
-                                                                                                  \n\
-extern \"C\" void *__lldb_apple_objc_v2_find_class_name (                                         \n\
-                                                          __lldb_objc_object *object_ptr,         \n\
-                                                          int debug)                              \n\
-{                                                                                                 \n\
-    void *name = 0;                                                                               \n\
-    if (debug)                                                                                    \n\
-        printf (\"\\n*** Called in v2_find_class_name with object: 0x%p\\n\", object_ptr);        \n\
-    // Call gdb_class_getClass so we can tell if the class is good.                               \n\
-    void *objc_class = gdb_class_getClass (object_ptr->isa);                                      \n\
-    if (objc_class)                                                                               \n\
-    {                                                                                             \n\
-        void *actual_class = (void *) [(id) object_ptr class];                                    \n\
-        if (actual_class != 0)                                                                    \n\
-        {                                                                                         \n\
-            if (class_isMetaClass(actual_class) == 1)                                             \n\
-            {                                                                                     \n\
-                if (debug)                                                                        \n\
-                    printf (\"\\n*** Found metaclass.\\n\");                                      \n\
-            }                                                                                     \n\
-            else                                                                                  \n\
-            {                                                                                     \n\
-                name = class_getName((void *) actual_class);                                      \n\
-            }                                                                                     \n\
-        }                                                                                         \n\
-        if (debug)                                                                                \n\
-            printf (\"\\n*** Found name: %s\\n\", name ? name : \"<NOT FOUND>\");                 \n\
-    }                                                                                             \n\
-    else if (debug)                                                                               \n\
-        printf (\"\\n*** gdb_class_getClass returned NULL\\n\");                                  \n\
-    return name;                                                                                  \n\
-}                                                                                                 \n\
-";
+// 2 second timeout when running utility functions
+#define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
 
-AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, 
-                                        const ModuleSP &objc_module_sp) : 
-    AppleObjCRuntime (process),
-    m_get_class_name_args(LLDB_INVALID_ADDRESS),
-    m_get_class_name_args_mutex(Mutex::eMutexTypeNormal),
-    m_isa_to_name_cache(),
-    m_isa_to_parent_cache()
+static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_dynamic_class_info_body = R"(
+
+extern "C"
 {
-    static const ConstString g_gdb_object_getClass("gdb_object_getClass");
-    m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+    size_t strlen(const char *);
+    char *strncpy (char * s1, const char * s2, size_t n);
+    int printf(const char * format, ...);
 }
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+typedef struct _NXMapTable {
+    void *prototype;
+    unsigned num_classes;
+    unsigned num_buckets_minus_one;
+    void *buckets;
+} NXMapTable;
 
-bool
-AppleObjCRuntimeV2::RunFunctionToFindClassName(addr_t object_addr, Thread *thread, char *name_dst, size_t max_name_len)
+#define NX_MAPNOTAKEY   ((void *)(-1))
+
+typedef struct BucketInfo
 {
-    // Since we are going to run code we have to make sure only one thread at a time gets to try this.
-    Mutex::Locker (m_get_class_name_args_mutex);
-    
-    StreamString errors;
-    
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));  // FIXME - a more appropriate log channel?
-    
-    int32_t debug;
-    if (log && log->GetVerbose())
-        debug = 1;
-    else
-        debug = 0;
+    const char *name_ptr;
+    Class isa;
+} BucketInfo;
 
-    ValueList dispatch_values;
-    
-    Value void_ptr_value;
-    ClangASTContext *clang_ast_context = m_process->GetTarget().GetScratchClangASTContext();
-    
-    clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
-    void_ptr_value.SetValueType (Value::eValueTypeScalar);
-    void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
-    void_ptr_value.GetScalar() = object_addr;
-        
-    dispatch_values.PushValue (void_ptr_value);
-    
-    Value int_value;
-    clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
-    int_value.SetValueType (Value::eValueTypeScalar);
-    int_value.SetContext (Value::eContextTypeClangType, clang_int_type);
-    int_value.GetScalar() = debug;
-    
-    dispatch_values.PushValue (int_value);
-    
-    ExecutionContext exe_ctx;
-    thread->CalculateExecutionContext(exe_ctx);
-    
-    Address find_class_name_address;
-    
-    if (!m_get_class_name_code.get())
+struct ClassInfo
+{
+    Class isa;
+    uint32_t hash;
+} __attribute__((__packed__));
+
+uint32_t
+__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
+                                             void *class_infos_ptr,
+                                             uint32_t class_infos_byte_size)
+{
+    DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
+    DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+    DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
+    const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;
+    if (grc)
     {
-        m_get_class_name_code.reset (new ClangUtilityFunction (g_find_class_name_function_body,
-                                                               g_find_class_name_function_name));
-                                                               
-        if (!m_get_class_name_code->Install(errors, exe_ctx))
+        const unsigned num_classes = grc->num_classes;
+        if (class_infos_ptr)
         {
-            if (log)
-                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
-            m_get_class_name_code.reset();
-            return false;
+            const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+            ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+            BucketInfo *buckets = (BucketInfo *)grc->buckets;
+            
+            uint32_t idx = 0;
+            for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
+            {
+                if (buckets[i].name_ptr != NX_MAPNOTAKEY)
+                {
+                    if (idx < max_class_infos)
+                    {
+                        const char *s = buckets[i].name_ptr;
+                        uint32_t h = 5381;
+                        for (unsigned char c = *s; c; c = *++s)
+                            h = ((h << 5) + h) + c;
+                        class_infos[idx].hash = h;
+                        class_infos[idx].isa = buckets[i].isa;
+                    }
+                    ++idx;
+                }
+            }
+            if (idx < max_class_infos)
+            {
+                class_infos[idx].isa = NULL;
+                class_infos[idx].hash = 0;
+            }
         }
-        find_class_name_address.Clear();
-        find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
+        return num_classes;
     }
-    else
+    return 0;
+}
+
+)";
+
+static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_shared_cache_class_info_body = R"(
+
+extern "C"
+{
+    const char *class_getName(void *objc_class);
+    size_t strlen(const char *);
+    char *strncpy (char * s1, const char * s2, size_t n);
+    int printf(const char * format, ...);
+}
+
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+
+struct objc_classheader_t {
+    int32_t clsOffset;
+    int32_t hiOffset;
+};
+
+struct objc_clsopt_t {
+    uint32_t capacity;
+    uint32_t occupied;
+    uint32_t shift;
+    uint32_t mask;
+    uint32_t zero;
+    uint32_t unused;
+    uint64_t salt;
+    uint32_t scramble[256];
+    uint8_t tab[0]; // tab[mask+1]
+    //  uint8_t checkbytes[capacity];
+    //  int32_t offset[capacity];
+    //  objc_classheader_t clsOffsets[capacity];
+    //  uint32_t duplicateCount;
+    //  objc_classheader_t duplicateOffsets[duplicateCount];
+};
+
+struct objc_opt_t {
+    uint32_t version;
+    int32_t selopt_offset;
+    int32_t headeropt_offset;
+    int32_t clsopt_offset;
+};
+
+struct ClassInfo
+{
+    Class isa;
+    uint32_t hash;
+}  __attribute__((__packed__));
+
+uint32_t
+__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
+                                                  void *class_infos_ptr,
+                                                  uint32_t class_infos_byte_size)
+{
+    uint32_t idx = 0;
+    DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
+    DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+    DEBUG_PRINTF ("class_infos_byte_size = %u (%zu class infos)\n", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));
+    if (objc_opt_ro_ptr)
     {
-        find_class_name_address.Clear();
-        find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
+        const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
+        DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt->version);
+        DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt->selopt_offset);
+        DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
+        DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
+        if (objc_opt->version == 12)
+        {
+            const objc_clsopt_t* clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
+            const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+            ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+            int32_t zeroOffset = 16;
+            const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
+            const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
+            const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);
+            DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
+            DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
+            DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+            for (uint32_t i=0; i<clsopt->capacity; ++i)
+            {
+                const int32_t clsOffset = classOffsets[i].clsOffset;
+                if (clsOffset & 1)
+                    continue; // duplicate
+                else if (clsOffset == zeroOffset)
+                    continue; // zero offset
+                
+                if (class_infos && idx < max_class_infos)
+                {
+                    class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
+                    const char *name = class_getName (class_infos[idx].isa);
+                    DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+                    // Hash the class name so we don't have to read it
+                    const char *s = name;
+                    uint32_t h = 5381;
+                    for (unsigned char c = *s; c; c = *++s)
+                        h = ((h << 5) + h) + c;
+                    class_infos[idx].hash = h;
+                }
+                ++idx;
+            }
+            
+            const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
+            const uint32_t duplicate_count = *duplicate_count_ptr;
+            const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
+            DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
+            DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
+            for (uint32_t i=0; i<duplicate_count; ++i)
+            {
+                const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
+                if (clsOffset & 1)
+                    continue; // duplicate
+                else if (clsOffset == zeroOffset)
+                    continue; // zero offset
+                
+                if (class_infos && idx < max_class_infos)
+                {
+                    class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
+                    const char *name = class_getName (class_infos[idx].isa);
+                    DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+                    // Hash the class name so we don't have to read it
+                    const char *s = name;
+                    uint32_t h = 5381;
+                    for (unsigned char c = *s; c; c = *++s)
+                        h = ((h << 5) + h) + c;
+                    class_infos[idx].hash = h;
+                }
+                ++idx;
+            }
+        }
+        DEBUG_PRINTF ("%u class_infos\n", idx);
+        DEBUG_PRINTF ("done\n");
     }
+    return idx;
+}
 
-    // Next make the runner function for our implementation utility function.
-    if (!m_get_class_name_function.get())
+
+)";
+
+static uint64_t
+ExtractRuntimeGlobalSymbol (Process* process,
+                            ConstString name,
+                            const ModuleSP &module_sp,
+                            Error& error,
+                            bool read_value = true,
+                            uint8_t byte_size = 0,
+                            uint64_t default_value = LLDB_INVALID_ADDRESS,
+                            SymbolType sym_type = lldb::eSymbolTypeData)
+{
+    if (!process)
     {
-         m_get_class_name_function.reset(new ClangFunction (*m_process,
-                                                  clang_ast_context, 
-                                                  clang_void_ptr_type, 
-                                                  find_class_name_address, 
-                                                  dispatch_values));
-        
-        errors.Clear();        
-        unsigned num_errors = m_get_class_name_function->CompileFunction(errors);
-        if (num_errors)
+        error.SetErrorString("no process");
+        return default_value;
+    }
+    if (!module_sp)
+    {
+        error.SetErrorString("no module");
+        return default_value;
+    }
+    if (!byte_size)
+        byte_size = process->GetAddressByteSize();
+    const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
+    if (symbol)
+    {
+        lldb::addr_t symbol_load_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+        if (symbol_load_addr != LLDB_INVALID_ADDRESS)
         {
-            if (log)
-                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
-            return false;
+            if (read_value)
+                return process->ReadUnsignedIntegerFromMemory(symbol_load_addr, byte_size, default_value, error);
+            else
+                return symbol_load_addr;
         }
-        
-        errors.Clear();
-        if (!m_get_class_name_function->WriteFunctionWrapper(exe_ctx, errors))
+        else
         {
-            if (log)
-                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
-            return false;
+            error.SetErrorString("symbol address invalid");
+            return default_value;
         }
     }
-
-    if (m_get_class_name_code.get() == NULL || m_get_class_name_function.get() == NULL)
-        return false;
-
-    // Finally, write down the arguments, and call the function.  Note that we will re-use the same space in the target
-    // for the args.  We're locking this to ensure that only one thread at a time gets to call this function, so we don't
-    // have to worry about overwriting the arguments.
-    
-    if (!m_get_class_name_function->WriteFunctionArguments (exe_ctx, m_get_class_name_args, find_class_name_address, dispatch_values, errors))
-        return false;
-    
-    bool stop_others = true;
-    bool try_all_threads = true;
-    bool unwind_on_error = true;
-    
-    ExecutionResults results = m_get_class_name_function->ExecuteFunction (exe_ctx, 
-                                                     &m_get_class_name_args, 
-                                                     errors, 
-                                                     stop_others, 
-                                                     100000, 
-                                                     try_all_threads, 
-                                                     unwind_on_error, 
-                                                     void_ptr_value);
-                                                     
-    if (results != eExecutionCompleted)
+    else
     {
-        if (log)
-            log->Printf("Error evaluating our find class name function: %d.\n", results);
-        return false;
+        error.SetErrorString("no symbol");
+        return default_value;
     }
-    
-    addr_t result_ptr = void_ptr_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
-    Error error;
-    size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len, error);
-    
-    // If we exhausted our buffer before finding a NULL we're probably off in the weeds somewhere...
-    if (error.Fail() || chars_read == max_name_len)
-        return false;
-    else
-        return true;
-       
+
+}
+
+AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
+                                        const ModuleSP &objc_module_sp) :
+    AppleObjCRuntime (process),
+    m_get_class_info_function(),
+    m_get_class_info_code(),
+    m_get_class_info_args (LLDB_INVALID_ADDRESS),
+    m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
+    m_get_shared_cache_class_info_function(),
+    m_get_shared_cache_class_info_code(),
+    m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
+    m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
+    m_type_vendor_ap (),
+    m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
+    m_hash_signature (),
+    m_has_object_getClass (false),
+    m_loaded_objc_opt (false),
+    m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)),
+    m_tagged_pointer_vendor_ap(TaggedPointerVendor::CreateInstance(*this,objc_module_sp))
+{
+    static const ConstString g_gdb_object_getClass("gdb_object_getClass");
+    m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+}
+
+AppleObjCRuntimeV2::~AppleObjCRuntimeV2()
+{
 }
 
 bool
-AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value, 
+AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
                                               DynamicValueType use_dynamic, 
                                               TypeAndOrName &class_type_or_name, 
                                               Address &address)
@@ -250,159 +367,36 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAdd
     // The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
     assert (in_value.GetProcessSP().get() == m_process);
     assert (m_process != NULL);
+    
+    class_type_or_name.Clear();
 
     // Make sure we can have a dynamic value before starting...
     if (CouldHaveDynamicValue (in_value))
     {
         // First job, pull out the address at 0 offset from the object  That will be the ISA pointer.
-        Error error;
-        const addr_t object_ptr = in_value.GetPointerValue();
-        const addr_t isa_addr = m_process->ReadPointerFromMemory (object_ptr, error);
-
-        if (error.Fail())
-            return false;
-
-        address.SetRawAddress(object_ptr);
-
-        // First check the cache...
-        SymbolContext sc;
-        class_type_or_name = LookupInClassNameCache (isa_addr);
-        
-        if (!class_type_or_name.IsEmpty())
+        ClassDescriptorSP objc_class_sp (GetNonKVOClassDescriptor (in_value));
+        if (objc_class_sp)
         {
-            if (class_type_or_name.GetTypeSP())
-                return true;
-            else
-                return false;
-        }
-
-        // We don't have the object cached, so make sure the class
-        // address is readable, otherwise this is not a good object:
-        m_process->ReadPointerFromMemory (isa_addr, error);
-        
-        if (error.Fail())
-            return false;
+            const addr_t object_ptr = in_value.GetPointerValue();
+            address.SetRawAddress(object_ptr);
 
-        const char *class_name = NULL;
-        Address isa_address;
-        Target &target = m_process->GetTarget();
-        target.GetSectionLoadList().ResolveLoadAddress (isa_addr, isa_address);
-        
-        if (isa_address.IsValid())
-        {
-            // If the ISA pointer points to one of the sections in the binary, then see if we can
-            // get the class name from the symbols.
-        
-            SectionSP section_sp (isa_address.GetSection());
-
-            if (section_sp)
-            {
-                // If this points to a section that we know about, then this is
-                // some static class or nothing.  See if it is in the right section 
-                // and if its name is the right form.
-                ConstString section_name = section_sp->GetName();
-                static ConstString g_objc_class_section_name ("__objc_data");
-                if (section_name == g_objc_class_section_name)
-                {
-                    isa_address.CalculateSymbolContext(&sc);
-                    if (sc.symbol)
-                    {
-                        if (sc.symbol->GetType() == eSymbolTypeObjCClass)
-                            class_name = sc.symbol->GetName().GetCString();
-                        else if (sc.symbol->GetType() == eSymbolTypeObjCMetaClass)
-                        {
-                            // FIXME: Meta-classes can't have dynamic types...
-                            return false;
-                        }
-                    }
-                }
-            }
-        }
-        
-        char class_buffer[1024];
-        if (class_name == NULL && use_dynamic == eDynamicCanRunTarget)
-        {
-            // If the class address didn't point into the binary, or
-            // it points into the right section but there wasn't a symbol
-            // there, try to look it up by calling the class method in the target.
-            
-            ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
-            
-            Thread *thread_to_use = exe_ctx.GetThreadPtr();
-            
-            if (thread_to_use == NULL)
-                thread_to_use = m_process->GetThreadList().GetSelectedThread().get();
-                
-            if (thread_to_use == NULL)
-                return false;
-                
-            if (!RunFunctionToFindClassName (object_ptr, thread_to_use, class_buffer, 1024))
-                return false;
-                
-             class_name = class_buffer;   
-            
-        }
-        
-        if (class_name && class_name[0])
-        {
-            class_type_or_name.SetName (class_name);
-            
-            TypeList class_types;
-            SymbolContext sc;
-            const bool exact_match = true;
-            uint32_t num_matches = target.GetImages().FindTypes (sc,
-                                                                 class_type_or_name.GetName(),
-                                                                 exact_match,
-                                                                 UINT32_MAX,
-                                                                 class_types);
-            if (num_matches == 1)
-            {
-                class_type_or_name.SetTypeSP (class_types.GetTypeAtIndex(0));
-                return true;
-            }
+            ConstString class_name (objc_class_sp->GetClassName());
+            class_type_or_name.SetName(class_name);
+            TypeSP type_sp (objc_class_sp->GetType());
+            if (type_sp)
+                class_type_or_name.SetTypeSP (type_sp);
             else
             {
-                for (size_t i  = 0; i < num_matches; i++)
+                type_sp = LookupInCompleteClassCache (class_name);
+                if (type_sp)
                 {
-                    TypeSP this_type(class_types.GetTypeAtIndex(i));
-                    if (this_type)
-                    {
-                        // Only consider "real" ObjC classes.  For now this means avoiding
-                        // the Type objects that are made up from the OBJC_CLASS_$_<NAME> symbols.
-                        // we don't want to use them since they are empty and useless.
-                        if (this_type->IsRealObjCClass())
-                        {
-                            // There can only be one type with a given name,
-                            // so we've just found duplicate definitions, and this
-                            // one will do as well as any other.
-                            // We don't consider something to have a dynamic type if
-                            // it is the same as the static type.  So compare against
-                            // the value we were handed:
-                            
-                            clang::ASTContext *in_ast_ctx = in_value.GetClangAST ();
-                            clang::ASTContext *this_ast_ctx = this_type->GetClangAST ();
-                            if (in_ast_ctx != this_ast_ctx
-                                || !ClangASTContext::AreTypesSame (in_ast_ctx, 
-                                                                   in_value.GetClangType(),
-                                                                   this_type->GetClangFullType()))
-                            {
-                                class_type_or_name.SetTypeSP (this_type);
-                            }
-                            break;
-                        }
-                    }
+                    objc_class_sp->SetType (type_sp);
+                    class_type_or_name.SetTypeSP (type_sp);
                 }
             }
-            
-            AddToClassNameCache (isa_addr, class_type_or_name);
-            if (class_type_or_name.GetTypeSP())
-                return true;
-            else
-                return false;
         }
-    }
-    
-    return false;
+    }    
+    return class_type_or_name.IsEmpty() == false;
 }
 
 //------------------------------------------------------------------
@@ -429,8 +423,8 @@ AppleObjCRuntimeV2::CreateInstance (Proc
 void
 AppleObjCRuntimeV2::Initialize()
 {
-    PluginManager::RegisterPlugin (pluginName,
-                                   pluginDesc,
+    PluginManager::RegisterPlugin (GetPluginNameStatic(),
+                                   "Apple Objective C Language Runtime - Version 2",
                                    CreateInstance);    
 }
 
@@ -440,19 +434,21 @@ AppleObjCRuntimeV2::Terminate()
     PluginManager::UnregisterPlugin (CreateInstance);
 }
 
+lldb_private::ConstString
+AppleObjCRuntimeV2::GetPluginNameStatic()
+{
+    static ConstString g_name("apple-objc-v2");
+    return g_name;
+}
+
+
 //------------------------------------------------------------------
 // PluginInterface protocol
 //------------------------------------------------------------------
-const char *
+lldb_private::ConstString
 AppleObjCRuntimeV2::GetPluginName()
 {
-    return pluginName;
-}
-
-const char *
-AppleObjCRuntimeV2::GetShortPluginName()
-{
-    return pluginShort;
+    return GetPluginNameStatic();
 }
 
 uint32_t
@@ -574,207 +570,2083 @@ AppleObjCRuntimeV2::GetByteOffsetForIvar
     return ivar_offset;
 }
 
-// tagged pointers are marked by having their least-significant bit
-// set. this makes them "invalid" as pointers because they violate
-// the alignment requirements. of course, this detection algorithm
-// is not accurate (it might become better by incorporating further
-// knowledge about the internals of tagged pointers)
+
+// tagged pointers are special not-a-real-pointer values that contain both type and value information
+// this routine attempts to check with as little computational effort as possible whether something
+// could possibly be a tagged pointer - false positives are possible but false negatives shouldn't
 bool
 AppleObjCRuntimeV2::IsTaggedPointer(addr_t ptr)
 {
-    return (ptr & 0x01);
+    if (!m_tagged_pointer_vendor_ap)
+        return false;
+    return m_tagged_pointer_vendor_ap->IsPossibleTaggedPointer(ptr);
 }
 
-
-// this code relies on the assumption that an Objective-C object always starts
-// with an ISA at offset 0. an ISA is effectively a pointer to an instance of
-// struct class_t in the ObjCv2 runtime
-ObjCLanguageRuntime::ObjCISA
-AppleObjCRuntimeV2::GetISA(ValueObject& valobj)
+class RemoteNXMapTable
 {
-    if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != eLanguageTypeObjC)
-        return 0;
-    
-    // if we get an invalid VO (which might still happen when playing around
-    // with pointers returned by the expression parser, don't consider this
-    // a valid ObjC object)
-    if (valobj.GetValue().GetContextType() == Value::eContextTypeInvalid)
-        return 0;
+public:
     
-    addr_t isa_pointer = valobj.GetPointerValue();
+    RemoteNXMapTable () :
+        m_count (0),
+        m_num_buckets_minus_one (0),
+        m_buckets_ptr (LLDB_INVALID_ADDRESS),
+        m_process (NULL),
+        m_end_iterator (*this, -1),
+        m_load_addr (LLDB_INVALID_ADDRESS),
+        m_map_pair_size (0),
+        m_invalid_key (0)
+    {
+    }
     
-    // tagged pointer
-    if (IsTaggedPointer(isa_pointer))
-        return g_objc_Tagged_ISA;
-
-    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
-
-    Process *process = exe_ctx.GetProcessPtr();
-    if (process)
+    void
+    Dump ()
     {
-        uint8_t pointer_size = process->GetAddressByteSize();
+        printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
+        printf ("RemoteNXMapTable.m_count = %u\n", m_count);
+        printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
+        printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
+    }
     
-        Error error;
-        return process->ReadUnsignedIntegerFromMemory (isa_pointer,
-                                                       pointer_size,
-                                                       0,
-                                                       error);
+    bool
+    ParseHeader (Process* process, lldb::addr_t load_addr)
+    {
+        m_process = process;
+        m_load_addr = load_addr;
+        m_map_pair_size = m_process->GetAddressByteSize() * 2;
+        m_invalid_key = m_process->GetAddressByteSize() == 8 ? UINT64_MAX : UINT32_MAX;
+        Error err;
+        
+        // This currently holds true for all platforms we support, but we might
+        // need to change this to use get the actualy byte size of "unsigned"
+        // from the target AST...
+        const uint32_t unsigned_byte_size = sizeof(uint32_t);
+        // Skip the prototype as we don't need it (const struct +NXMapTablePrototype *prototype)
+        
+        bool success = true;
+        if (load_addr == LLDB_INVALID_ADDRESS)
+            success = false;
+        else
+        {
+            lldb::addr_t cursor = load_addr + m_process->GetAddressByteSize();
+                    
+            // unsigned count;
+            m_count = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
+            if (m_count)
+            {
+                cursor += unsigned_byte_size;
+            
+                // unsigned nbBucketsMinusOne;
+                m_num_buckets_minus_one = m_process->ReadUnsignedIntegerFromMemory(cursor, unsigned_byte_size, 0, err);
+                cursor += unsigned_byte_size;
+            
+                // void *buckets;
+                m_buckets_ptr = m_process->ReadPointerFromMemory(cursor, err);
+                
+                success = m_count > 0 && m_buckets_ptr != LLDB_INVALID_ADDRESS;
+            }
+        }
+        
+        if (!success)
+        {
+            m_count = 0;
+            m_num_buckets_minus_one = 0;
+            m_buckets_ptr = LLDB_INVALID_ADDRESS;
+        }
+        return success;
     }
-    return 0;
-}
+    
+    // const_iterator mimics NXMapState and its code comes from NXInitMapState and NXNextMapState.
+    typedef std::pair<ConstString, ObjCLanguageRuntime::ObjCISA> element;
 
-// TODO: should we have a transparent_kvo parameter here to say if we 
-// want to replace the KVO swizzled class with the actual user-level type?
-ConstString
-AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
-{
-    static const ConstString g_unknown ("unknown");
+    friend class const_iterator;
+    class const_iterator
+    {
+    public:
+        const_iterator (RemoteNXMapTable &parent, int index) : m_parent(parent), m_index(index)
+        {
+            AdvanceToValidIndex();
+        }
+        
+        const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
+        {
+            // AdvanceToValidIndex() has been called by rhs already.
+        }
+        
+        const_iterator &operator=(const const_iterator &rhs)
+        {
+            // AdvanceToValidIndex() has been called by rhs already.
+            assert (&m_parent == &rhs.m_parent);
+            m_index = rhs.m_index;
+            return *this;
+        }
+        
+        bool operator==(const const_iterator &rhs) const
+        {
+            if (&m_parent != &rhs.m_parent)
+                return false;
+            if (m_index != rhs.m_index)
+                return false;
+            
+            return true;
+        }
+        
+        bool operator!=(const const_iterator &rhs) const
+        {
+            return !(operator==(rhs));
+        }
+        
+        const_iterator &operator++()
+        {
+            AdvanceToValidIndex();
+            return *this;
+        }
+        
+        const element operator*() const
+        {
+            if (m_index == -1)
+            {
+                // TODO find a way to make this an error, but not an assert
+                return element();
+            }
+         
+            lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+            size_t map_pair_size = m_parent.m_map_pair_size;
+            lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
+            
+            Error err;
+            
+            lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
+            if (!err.Success())
+                return element();
+            lldb::addr_t value = m_parent.m_process->ReadPointerFromMemory(pair_ptr + m_parent.m_process->GetAddressByteSize(), err);
+            if (!err.Success())
+                return element();
+            
+            std::string key_string;
+            
+            m_parent.m_process->ReadCStringFromMemory(key, key_string, err);
+            if (!err.Success())
+                return element();
+            
+            return element(ConstString(key_string.c_str()), (ObjCLanguageRuntime::ObjCISA)value);
+        }
+    private:
+        void AdvanceToValidIndex ()
+        {
+            if (m_index == -1)
+                return;
+            
+            const lldb::addr_t pairs_ptr = m_parent.m_buckets_ptr;
+            const size_t map_pair_size = m_parent.m_map_pair_size;
+            const lldb::addr_t invalid_key = m_parent.m_invalid_key;
+            Error err;
 
-    if (!IsValidISA(isa))
-        return ConstString();
-     
-    if (isa == g_objc_Tagged_ISA)
+            while (m_index--)
+            {
+                lldb::addr_t pair_ptr = pairs_ptr + (m_index * map_pair_size);
+                lldb::addr_t key = m_parent.m_process->ReadPointerFromMemory(pair_ptr, err);
+                
+                if (!err.Success())
+                {
+                    m_index = -1;
+                    return;
+                }
+                
+                if (key != invalid_key)
+                    return;
+            }
+        }
+        RemoteNXMapTable   &m_parent;
+        int                 m_index;
+    };
+    
+    const_iterator begin ()
     {
-        static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
-        return g_objc_tagged_isa_name;
+        return const_iterator(*this, m_num_buckets_minus_one + 1);
     }
     
-    ISAToNameIterator found = m_isa_to_name_cache.find(isa);
-    ISAToNameIterator end = m_isa_to_name_cache.end();
-    
-    if (found != end)
-        return found->second;
+    const_iterator end ()
+    {
+        return m_end_iterator;
+    }
     
-    uint8_t pointer_size = m_process->GetAddressByteSize();
-    Error error;
+    uint32_t
+    GetCount () const
+    {
+        return m_count;
+    }
     
-    /*
-     struct class_t *isa;
-     struct class_t *superclass;
-     Cache cache;
-     IMP *vtable;
--->     class_rw_t data;
-     */
-    
-    addr_t rw_pointer = isa + (4 * pointer_size);
-    //printf("rw_pointer: %llx\n", rw_pointer);
-    uint64_t data_pointer =  m_process->ReadUnsignedIntegerFromMemory(rw_pointer,
-                                                                      pointer_size,
-                                                                      0,
-                                                                      error);
-    if (error.Fail())
+    uint32_t
+    GetBucketCount () const
     {
-        return g_unknown;
-
+        return m_num_buckets_minus_one;
     }
     
-    /*
-     uint32_t flags;
-     uint32_t version;
-     
--->     const class_ro_t *ro;
-     */
-    data_pointer += 8;
-    //printf("data_pointer: %llx\n", data_pointer);
-    uint64_t ro_pointer = m_process->ReadUnsignedIntegerFromMemory(data_pointer,
-                                                                   pointer_size,
-                                                                   0,
-                                                                   error);
-    if (error.Fail())
-        return g_unknown;
+    lldb::addr_t
+    GetBucketDataPointer () const
+    {
+        return m_buckets_ptr;
+    }
     
-    /*
-     uint32_t flags;
-     uint32_t instanceStart;
-     uint32_t instanceSize;
-     #ifdef __LP64__
-     uint32_t reserved;
-     #endif
-     
-     const uint8_t * ivarLayout;
-     
--->     const char * name;
-     */
-    ro_pointer += 12;
-    if (pointer_size == 8)
-        ro_pointer += 4;
-    ro_pointer += pointer_size;
-    //printf("ro_pointer: %llx\n", ro_pointer);
-    uint64_t name_pointer = m_process->ReadUnsignedIntegerFromMemory(ro_pointer,
-                                                                     pointer_size,
-                                                                     0,
-                                                                     error);
-    if (error.Fail())
-        return g_unknown;
+    lldb::addr_t
+    GetTableLoadAddress() const
+    {
+        return m_load_addr;
+    }
+
+private:
+    // contents of _NXMapTable struct
+    uint32_t m_count;
+    uint32_t m_num_buckets_minus_one;
+    lldb::addr_t m_buckets_ptr;
+    lldb_private::Process *m_process;
+    const_iterator m_end_iterator;
+    lldb::addr_t m_load_addr;
+    size_t m_map_pair_size;
+    lldb::addr_t m_invalid_key;
+};
+
+
+
+AppleObjCRuntimeV2::HashTableSignature::HashTableSignature() :
+    m_count (0),
+    m_num_buckets (0),
+    m_buckets_ptr (0)
+{
+}
+
+void
+AppleObjCRuntimeV2::HashTableSignature::UpdateSignature (const RemoteNXMapTable &hash_table)
+{
+    m_count = hash_table.GetCount();
+    m_num_buckets = hash_table.GetBucketCount();
+    m_buckets_ptr = hash_table.GetBucketDataPointer();
+}
+
+bool
+AppleObjCRuntimeV2::HashTableSignature::NeedsUpdate (Process *process, AppleObjCRuntimeV2 *runtime, RemoteNXMapTable &hash_table)
+{
+    if (!hash_table.ParseHeader(process, runtime->GetISAHashTablePointer ()))
+    {
+        return false; // Failed to parse the header, no need to update anything
+    }
+
+    // Check with out current signature and return true if the count,
+    // number of buckets or the hash table address changes.
+    if (m_count == hash_table.GetCount() &&
+        m_num_buckets == hash_table.GetBucketCount() &&
+        m_buckets_ptr == hash_table.GetBucketDataPointer())
+    {
+        // Hash table hasn't changed
+        return false;
+    }
+    // Hash table data has changed, we need to update
+    return true;
+}
+
+class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
+{
+public:
+    friend class lldb_private::AppleObjCRuntimeV2;
+    
+private:
+    // The constructor should only be invoked by the runtime as it builds its caches
+    // or populates them.  A ClassDescriptorV2 should only ever exist in a cache.
+    ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) :
+        m_runtime (runtime),
+        m_objc_class_ptr (isa),
+        m_name (name)
+    {
+    }
+
+public:
+    virtual ConstString
+    GetClassName ()
+    {
+        if (!m_name)
+        {
+            lldb_private::Process *process = m_runtime.GetProcess();
+
+            if (process)
+            {
+                std::unique_ptr<objc_class_t> objc_class;
+                std::unique_ptr<class_ro_t> class_ro;
+                std::unique_ptr<class_rw_t> class_rw;
+                
+                if (!Read_objc_class(process, objc_class))
+                    return m_name;
+                if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+                    return m_name;
+                
+                m_name = ConstString(class_ro->m_name.c_str());
+            }
+        }
+        return m_name;
+    }
+    
+    virtual ObjCLanguageRuntime::ClassDescriptorSP
+    GetSuperclass ()
+    {
+        lldb_private::Process *process = m_runtime.GetProcess();
+
+        if (!process)
+            return ObjCLanguageRuntime::ClassDescriptorSP();
+        
+        std::unique_ptr<objc_class_t> objc_class;
+
+        if (!Read_objc_class(process, objc_class))
+            return ObjCLanguageRuntime::ClassDescriptorSP();
+
+        return m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(objc_class->m_superclass);
+    }
+    
+    virtual bool
+    IsValid ()
+    {
+        return true;    // any Objective-C v2 runtime class descriptor we vend is valid
+    }
+    
+    // a custom descriptor is used for tagged pointers
+    virtual bool
+    GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+                          uint64_t* value_bits = NULL,
+                          uint64_t* payload = NULL)
+    {
+        return false;
+    }
+    
+    virtual uint64_t
+    GetInstanceSize ()
+    {
+        lldb_private::Process *process = m_runtime.GetProcess();
+        
+        if (process)
+        {
+            std::unique_ptr<objc_class_t> objc_class;
+            std::unique_ptr<class_ro_t> class_ro;
+            std::unique_ptr<class_rw_t> class_rw;
+            
+            if (!Read_objc_class(process, objc_class))
+                return 0;
+            if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+                return 0;
+            
+            return class_ro->m_instanceSize;
+        }
+        
+        return 0;
+    }
+    
+    virtual ObjCLanguageRuntime::ObjCISA
+    GetISA ()
+    {        
+        return m_objc_class_ptr;
+    }
+    
+    virtual bool
+    Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+              std::function <bool (const char *, const char *)> const &instance_method_func,
+              std::function <bool (const char *, const char *)> const &class_method_func,
+              std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
+    {
+        lldb_private::Process *process = m_runtime.GetProcess();
+
+        std::unique_ptr<objc_class_t> objc_class;
+        std::unique_ptr<class_ro_t> class_ro;
+        std::unique_ptr<class_rw_t> class_rw;
+        
+        if (!Read_objc_class(process, objc_class))
+            return 0;
+        if (!Read_class_row(process, *objc_class, class_ro, class_rw))
+            return 0;
+    
+        static ConstString NSObject_name("NSObject");
+        
+        if (m_name != NSObject_name && superclass_func)
+            superclass_func(objc_class->m_superclass);
+        
+        if (instance_method_func)
+        {
+            std::unique_ptr<method_list_t> base_method_list;
+            
+            base_method_list.reset(new method_list_t);
+            if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr))
+                return false;
+            
+            if (base_method_list->m_entsize != method_t::GetSize(process))
+                return false;
+            
+            std::unique_ptr<method_t> method;
+            method.reset(new method_t);
+            
+            for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
+            {
+                method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
+                
+                if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
+                    break;
+            }
+        }
+        
+        if (class_method_func)
+        {
+            ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa, NULL); // The metaclass is not in the cache
+            
+            // We don't care about the metaclass's superclass, or its class methods.  Its instance methods are
+            // our class methods.
+            
+            metaclass.Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
+                               class_method_func,
+                               std::function <bool (const char *, const char *)> (nullptr),
+                               std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> (nullptr));
+        }
+        
+        if (ivar_func)
+        {
+            ivar_list_t ivar_list;
+            if (!ivar_list.Read(process, class_ro->m_ivars_ptr))
+                return false;
+            
+            if (ivar_list.m_entsize != ivar_t::GetSize(process))
+                return false;
+            
+            ivar_t ivar;
+            
+            for (uint32_t i = 0, e = ivar_list.m_count; i < e; ++i)
+            {
+                ivar.Read(process, ivar_list.m_first_ptr + (i * ivar_list.m_entsize));
+                
+                if (ivar_func(ivar.m_name.c_str(), ivar.m_type.c_str(), ivar.m_offset_ptr, ivar.m_size))
+                    break;
+            }
+        }
+            
+        return true;
+    }
+    
+    virtual
+    ~ClassDescriptorV2 ()
+    {
+    }
+        
+private:
+    static const uint32_t RW_REALIZED = (1 << 31);
+    
+    struct objc_class_t {
+        ObjCLanguageRuntime::ObjCISA    m_isa;              // The class's metaclass.
+        ObjCLanguageRuntime::ObjCISA    m_superclass;
+        lldb::addr_t                    m_cache_ptr;
+        lldb::addr_t                    m_vtable_ptr;
+        lldb::addr_t                    m_data_ptr;
+        uint8_t                         m_flags;
+        
+        objc_class_t () :
+            m_isa (0),
+            m_superclass (0),
+            m_cache_ptr (0),
+            m_vtable_ptr (0),
+            m_data_ptr (0),
+            m_flags (0)
+        {
+        }
+        
+        void
+        Clear()
+        {
+            m_isa = 0;
+            m_superclass = 0;
+            m_cache_ptr = 0;
+            m_vtable_ptr = 0;
+            m_data_ptr = 0;
+            m_flags = 0;
+        }
+
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t ptr_size = process->GetAddressByteSize();
+            
+            size_t objc_class_size = ptr_size   // uintptr_t isa;
+            + ptr_size   // Class superclass;
+            + ptr_size   // void *cache;
+            + ptr_size   // IMP *vtable;
+            + ptr_size;  // uintptr_t data_NEVER_USE;
+            
+            DataBufferHeap objc_class_buf (objc_class_size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, objc_class_buf.GetBytes(), objc_class_size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_isa           = extractor.GetAddress_unchecked(&cursor);   // uintptr_t isa;
+            m_superclass    = extractor.GetAddress_unchecked(&cursor);   // Class superclass;
+            m_cache_ptr     = extractor.GetAddress_unchecked(&cursor);   // void *cache;
+            m_vtable_ptr    = extractor.GetAddress_unchecked(&cursor);   // IMP *vtable;
+            lldb::addr_t data_NEVER_USE = extractor.GetAddress_unchecked(&cursor);   // uintptr_t data_NEVER_USE;
+            
+            m_flags         = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3);
+            m_data_ptr      = data_NEVER_USE & ~(lldb::addr_t)3;
+            
+            return true;
+        }
+    };
+    
+    struct class_ro_t {
+        uint32_t                        m_flags;
+        uint32_t                        m_instanceStart;
+        uint32_t                        m_instanceSize;
+        uint32_t                        m_reserved;
+        
+        lldb::addr_t                    m_ivarLayout_ptr;
+        lldb::addr_t                    m_name_ptr;
+        lldb::addr_t                    m_baseMethods_ptr;
+        lldb::addr_t                    m_baseProtocols_ptr;
+        lldb::addr_t                    m_ivars_ptr;
+        
+        lldb::addr_t                    m_weakIvarLayout_ptr;
+        lldb::addr_t                    m_baseProperties_ptr;
+        
+        std::string                     m_name;
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t ptr_size = process->GetAddressByteSize();
+            
+            size_t size = sizeof(uint32_t)             // uint32_t flags;
+            + sizeof(uint32_t)                         // uint32_t instanceStart;
+            + sizeof(uint32_t)                         // uint32_t instanceSize;
+            + (ptr_size == 8 ? sizeof(uint32_t) : 0)   // uint32_t reserved; // __LP64__ only
+            + ptr_size                                 // const uint8_t *ivarLayout;
+            + ptr_size                                 // const char *name;
+            + ptr_size                                 // const method_list_t *baseMethods;
+            + ptr_size                                 // const protocol_list_t *baseProtocols;
+            + ptr_size                                 // const ivar_list_t *ivars;
+            + ptr_size                                 // const uint8_t *weakIvarLayout;
+            + ptr_size;                                // const property_list_t *baseProperties;
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_flags             = extractor.GetU32_unchecked(&cursor);
+            m_instanceStart     = extractor.GetU32_unchecked(&cursor);
+            m_instanceSize      = extractor.GetU32_unchecked(&cursor);
+            if (ptr_size == 8)
+                m_reserved      = extractor.GetU32_unchecked(&cursor);
+            else
+                m_reserved      = 0;
+            m_ivarLayout_ptr     = extractor.GetAddress_unchecked(&cursor);
+            m_name_ptr           = extractor.GetAddress_unchecked(&cursor);
+            m_baseMethods_ptr    = extractor.GetAddress_unchecked(&cursor);
+            m_baseProtocols_ptr  = extractor.GetAddress_unchecked(&cursor);
+            m_ivars_ptr          = extractor.GetAddress_unchecked(&cursor);
+            m_weakIvarLayout_ptr = extractor.GetAddress_unchecked(&cursor);
+            m_baseProperties_ptr = extractor.GetAddress_unchecked(&cursor);
+            
+            DataBufferHeap name_buf(1024, '\0');
+            
+            process->ReadCStringFromMemory(m_name_ptr, (char*)name_buf.GetBytes(), name_buf.GetByteSize(), error);
+            
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            m_name.assign((char*)name_buf.GetBytes());
+                
+            return true;
+        }
+    };
+    
+    struct class_rw_t {
+        uint32_t                        m_flags;
+        uint32_t                        m_version;
+        
+        lldb::addr_t                    m_ro_ptr;
+        union {
+            lldb::addr_t                m_method_list_ptr;
+            lldb::addr_t                m_method_lists_ptr;
+        };
+        lldb::addr_t                    m_properties_ptr;
+        lldb::addr_t                    m_protocols_ptr;
+        
+        ObjCLanguageRuntime::ObjCISA    m_firstSubclass;
+        ObjCLanguageRuntime::ObjCISA    m_nextSiblingClass;
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t ptr_size = process->GetAddressByteSize();
+            
+            size_t size = sizeof(uint32_t)  // uint32_t flags;
+            + sizeof(uint32_t)  // uint32_t version;
+            + ptr_size          // const class_ro_t *ro;
+            + ptr_size          // union { method_list_t **method_lists; method_list_t *method_list; };
+            + ptr_size          // struct chained_property_list *properties;
+            + ptr_size          // const protocol_list_t **protocols;
+            + ptr_size          // Class firstSubclass;
+            + ptr_size;         // Class nextSiblingClass;
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_flags             = extractor.GetU32_unchecked(&cursor);
+            m_version           = extractor.GetU32_unchecked(&cursor);
+            m_ro_ptr            = extractor.GetAddress_unchecked(&cursor);
+            m_method_list_ptr   = extractor.GetAddress_unchecked(&cursor);
+            m_properties_ptr    = extractor.GetAddress_unchecked(&cursor);
+            m_firstSubclass     = extractor.GetAddress_unchecked(&cursor);
+            m_nextSiblingClass  = extractor.GetAddress_unchecked(&cursor);
+            
+            return true;
+        }
+    };
+    
+    struct method_list_t
+    {
+        uint32_t        m_entsize;
+        uint32_t        m_count;
+        lldb::addr_t    m_first_ptr;
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t size = sizeof(uint32_t)  // uint32_t entsize_NEVER_USE;
+            + sizeof(uint32_t); // uint32_t count;
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_entsize   = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
+            m_count     = extractor.GetU32_unchecked(&cursor);
+            m_first_ptr  = addr + cursor;
+            
+            return true;
+        }
+    };
+    
+    struct method_t
+    {
+        lldb::addr_t    m_name_ptr;
+        lldb::addr_t    m_types_ptr;
+        lldb::addr_t    m_imp_ptr;
+        
+        std::string     m_name;
+        std::string     m_types;
+        
+        static size_t GetSize(Process *process)
+        {
+            size_t ptr_size = process->GetAddressByteSize();
+            
+            return ptr_size     // SEL name;
+            + ptr_size   // const char *types;
+            + ptr_size;  // IMP imp;
+        }
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t size = GetSize(process);
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_name_ptr   = extractor.GetAddress_unchecked(&cursor);
+            m_types_ptr  = extractor.GetAddress_unchecked(&cursor);
+            m_imp_ptr    = extractor.GetAddress_unchecked(&cursor);
+            
+            const size_t buffer_size = 1024;
+            size_t count;
+            
+            DataBufferHeap string_buf(buffer_size, 0);
+            
+            count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            m_name.assign((char*)string_buf.GetBytes(), count);
+            
+            count = process->ReadCStringFromMemory(m_types_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            m_types.assign((char*)string_buf.GetBytes(), count);
+            
+            return true;
+        }
+    };
+    
+    struct ivar_list_t
+    {
+        uint32_t        m_entsize;
+        uint32_t        m_count;
+        lldb::addr_t    m_first_ptr;
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t size = sizeof(uint32_t)  // uint32_t entsize;
+                        + sizeof(uint32_t); // uint32_t count;
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_entsize   = extractor.GetU32_unchecked(&cursor);
+            m_count     = extractor.GetU32_unchecked(&cursor);
+            m_first_ptr = addr + cursor;
+            
+            return true;
+        }
+    };
+    
+    struct ivar_t
+    {
+        lldb::addr_t    m_offset_ptr;
+        lldb::addr_t    m_name_ptr;
+        lldb::addr_t    m_type_ptr;
+        uint32_t        m_alignment;
+        uint32_t        m_size;
+        
+        std::string     m_name;
+        std::string     m_type;
+        
+        static size_t GetSize(Process *process)
+        {
+            size_t ptr_size = process->GetAddressByteSize();
+            
+            return ptr_size             // uintptr_t *offset;
+                 + ptr_size             // const char *name;
+                 + ptr_size             // const char *type;
+                 + sizeof(uint32_t)     // uint32_t alignment;
+                 + sizeof(uint32_t);    // uint32_t size;
+        }
+        
+        bool Read(Process *process, lldb::addr_t addr)
+        {
+            size_t size = GetSize(process);
+            
+            DataBufferHeap buffer (size, '\0');
+            Error error;
+            
+            process->ReadMemory(addr, buffer.GetBytes(), size, error);
+            if (error.Fail())
+            {
+                return false;
+            }
+            
+            DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+            
+            lldb::offset_t cursor = 0;
+            
+            m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
+            m_name_ptr   = extractor.GetAddress_unchecked(&cursor);
+            m_type_ptr   = extractor.GetAddress_unchecked(&cursor);
+            m_alignment  = extractor.GetU32_unchecked(&cursor);
+            m_size       = extractor.GetU32_unchecked(&cursor);
+            
+            const size_t buffer_size = 1024;
+            size_t count;
+            
+            DataBufferHeap string_buf(buffer_size, 0);
+            
+            count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            m_name.assign((char*)string_buf.GetBytes(), count);
+            
+            count = process->ReadCStringFromMemory(m_type_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+            m_type.assign((char*)string_buf.GetBytes(), count);
+            
+            return true;
+        }
+    };
+    
+    bool Read_objc_class (Process* process, std::unique_ptr<objc_class_t> &objc_class)
+    {
+        objc_class.reset(new objc_class_t);
+        
+        bool ret = objc_class->Read (process, m_objc_class_ptr);
+        
+        if (!ret)
+            objc_class.reset();
+        
+        return ret;
+    }
+    
+    bool Read_class_row (Process* process, const objc_class_t &objc_class, std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw)
+    {
+        class_ro.reset();
+        class_rw.reset();
+        
+        Error error;
+        uint32_t class_row_t_flags = process->ReadUnsignedIntegerFromMemory(objc_class.m_data_ptr, sizeof(uint32_t), 0, error);
+        if (!error.Success())
+            return false;
+
+        if (class_row_t_flags & RW_REALIZED)
+        {
+            class_rw.reset(new class_rw_t);
+            
+            if (!class_rw->Read(process, objc_class.m_data_ptr))
+            {
+                class_rw.reset();
+                return false;
+            }
+            
+            class_ro.reset(new class_ro_t);
+            
+            if (!class_ro->Read(process, class_rw->m_ro_ptr))
+            {
+                class_rw.reset();
+                class_ro.reset();
+                return false;
+            }
+        }
+        else
+        {
+            class_ro.reset(new class_ro_t);
+            
+            if (!class_ro->Read(process, objc_class.m_data_ptr))
+            {
+                class_ro.reset();
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+    AppleObjCRuntimeV2 &m_runtime;          // The runtime, so we can read information lazily.
+    lldb::addr_t        m_objc_class_ptr;   // The address of the objc_class_t.  (I.e., objects of this class type have this as their ISA)
+    ConstString         m_name;             // May be NULL
+};
+
+// tagged pointer descriptor
+class ClassDescriptorV2Tagged : public ObjCLanguageRuntime::ClassDescriptor
+{
+public:
+    ClassDescriptorV2Tagged (ConstString class_name,
+                             uint64_t payload)
+    {
+        m_name = class_name;
+        if (!m_name)
+        {
+            m_valid = false;
+            return;
+        }
+        m_valid = true;
+        m_payload = payload;
+        m_info_bits = (m_payload & 0xF0ULL) >> 4;
+        m_value_bits = (m_payload & ~0x0000000000000000FFULL) >> 8;
+    }
+    
+    ClassDescriptorV2Tagged (ObjCLanguageRuntime::ClassDescriptorSP actual_class_sp,
+                             uint64_t payload)
+    {
+        if (!actual_class_sp)
+        {
+            m_valid = false;
+            return;
+        }
+        m_name = actual_class_sp->GetClassName();
+        if (!m_name)
+        {
+            m_valid = false;
+            return;
+        }
+        m_valid = true;
+        m_payload = payload;
+        m_info_bits = (m_payload & 0x0FULL);
+        m_value_bits = (m_payload & ~0x0FULL) >> 4;
+    }
+    
+    virtual ConstString
+    GetClassName ()
+    {
+        return m_name;
+    }
+    
+    virtual ObjCLanguageRuntime::ClassDescriptorSP
+    GetSuperclass ()
+    {
+        // tagged pointers can represent a class that has a superclass, but since that information is not
+        // stored in the object itself, we would have to query the runtime to discover the hierarchy
+        // for the time being, we skip this step in the interest of static discovery
+        return ObjCLanguageRuntime::ClassDescriptorSP();
+    }
+    
+    virtual bool
+    IsValid ()
+    {
+        return m_valid;
+    }
+    
+    virtual bool
+    IsKVO ()
+    {
+        return false; // tagged pointers are not KVO'ed
+    }
+    
+    virtual bool
+    IsCFType ()
+    {
+        return false; // tagged pointers are not CF objects
+    }
+    
+    virtual bool
+    GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+                          uint64_t* value_bits = NULL,
+                          uint64_t* payload = NULL)
+    {
+        if (info_bits)
+            *info_bits = GetInfoBits();
+        if (value_bits)
+            *value_bits = GetValueBits();
+        if (payload)
+            *payload = GetPayload();
+        return true;
+    }
+    
+    virtual uint64_t
+    GetInstanceSize ()
+    {
+        return (IsValid() ? m_pointer_size : 0);
+    }
+    
+    virtual ObjCLanguageRuntime::ObjCISA
+    GetISA ()
+    {
+        return 0; // tagged pointers have no ISA
+    }
+    
+    // these calls are not part of any formal tagged pointers specification
+    virtual uint64_t
+    GetValueBits ()
+    {
+        return (IsValid() ? m_value_bits : 0);
+    }
+    
+    virtual uint64_t
+    GetInfoBits ()
+    {
+        return (IsValid() ? m_info_bits : 0);
+    }
+    
+    virtual uint64_t
+    GetPayload ()
+    {
+        return (IsValid() ? m_payload : 0);
+    }
+    
+    virtual
+    ~ClassDescriptorV2Tagged ()
+    {}
+
+private:
+    ConstString m_name;
+    uint8_t m_pointer_size;
+    bool m_valid;
+    uint64_t m_info_bits;
+    uint64_t m_value_bits;
+    uint64_t m_payload;
+
+};
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::GetClassDescriptor (ObjCISA isa)
+{
+    ObjCLanguageRuntime::ClassDescriptorSP class_descriptor_sp;
+    if (m_non_pointer_isa_cache_ap.get())
+        class_descriptor_sp = m_non_pointer_isa_cache_ap->GetClassDescriptor(isa);
+    if (!class_descriptor_sp)
+        class_descriptor_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA(isa);
+    return class_descriptor_sp;
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::GetClassDescriptor (ValueObject& valobj)
+{
+    ClassDescriptorSP objc_class_sp;
+    // if we get an invalid VO (which might still happen when playing around
+    // with pointers returned by the expression parser, don't consider this
+    // a valid ObjC object)
+    if (valobj.GetValue().GetContextType() != Value::eContextTypeInvalid)
+    {
+        addr_t isa_pointer = valobj.GetPointerValue();
+        
+        // tagged pointer
+        if (IsTaggedPointer(isa_pointer))
+        {
+            return m_tagged_pointer_vendor_ap->GetClassDescriptor(isa_pointer);
+        }
+        else
+        {
+            ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+            
+            Process *process = exe_ctx.GetProcessPtr();
+            if (process)
+            {
+                Error error;
+                ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error);
+                if (isa != LLDB_INVALID_ADDRESS)
+                {
+                    objc_class_sp = ObjCLanguageRuntime::GetClassDescriptorFromISA (isa);
+                    if (isa && !objc_class_sp)
+                    {
+                        Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+                        if (log)
+                            log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
+                                        isa_pointer,
+                                        isa);
+                    }
+                }
+            }
+        }
+    }
+    return objc_class_sp;
+}
+
+lldb::addr_t
+AppleObjCRuntimeV2::GetISAHashTablePointer ()
+{
+    if (m_isa_hash_table_ptr == LLDB_INVALID_ADDRESS)
+    {
+        Process *process = GetProcess();
+
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (!objc_module_sp)
+            return LLDB_INVALID_ADDRESS;
+
+        static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
+        
+        const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeData);
+        if (symbol)
+        {
+            lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+            
+            if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
+            {
+                Error error;
+                m_isa_hash_table_ptr = process->ReadPointerFromMemory(gdb_objc_realized_classes_ptr, error);
+            }
+        }
+    }
+    return m_isa_hash_table_ptr;
+}
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
+{
+    Process *process = GetProcess();
+    
+    if (process == NULL)
+        return false;
+    
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    
+    ExecutionContext exe_ctx;
+    
+    ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+    
+    if (!thread_sp)
+        return false;
+    
+    thread_sp->CalculateExecutionContext(exe_ctx);
+    ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+    
+    if (!ast)
+        return false;
+    
+    Address function_address;
+    
+    StreamString errors;
+    
+    const uint32_t addr_size = process->GetAddressByteSize();
+    
+    Error err;
+    
+    // Read the total number of classes from the hash table
+    const uint32_t num_classes = hash_table.GetCount();
+    if (num_classes == 0)
+    {
+        if (log)
+            log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
+        return false;
+    }
+    
+    // Make some types for our arguments
+    clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+    clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+    
+    if (!m_get_class_info_code.get())
+    {
+        m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
+                                                               g_get_dynamic_class_info_name));
+        
+        errors.Clear();
+        
+        if (!m_get_class_info_code->Install(errors, exe_ctx))
+        {
+            if (log)
+                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+            m_get_class_info_code.reset();
+        }
+    }
+    
+    if (m_get_class_info_code.get())
+        function_address.SetOffset(m_get_class_info_code->StartAddress());
+    else
+        return false;
+    
+    ValueList arguments;
+    
+    // Next make the runner function for our implementation utility function.
+    if (!m_get_class_info_function.get())
+    {
+        Value value;
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        arguments.PushValue (value);
+        
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        arguments.PushValue (value);
+        
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        arguments.PushValue (value);
+        
+        m_get_class_info_function.reset(new ClangFunction (*m_process,
+                                                           ast,
+                                                           clang_uint32_t_type,
+                                                           function_address,
+                                                           arguments));
+        
+        if (m_get_class_info_function.get() == NULL)
+            return false;
+        
+        errors.Clear();
+        
+        unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
+        if (num_errors)
+        {
+            if (log)
+                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+            return false;
+        }
+        
+        errors.Clear();
+        
+        if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+        {
+            if (log)
+                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+            return false;
+        }
+    }
+    else
+    {
+        arguments = m_get_class_info_function->GetArgumentValues ();
+    }
+    
+    const uint32_t class_info_byte_size = addr_size + 4;
+    const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+    lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
+                                                            ePermissionsReadable | ePermissionsWritable,
+                                                            err);
+    
+    if (class_infos_addr == LLDB_INVALID_ADDRESS)
+        return false;
+    
+    Mutex::Locker locker(m_get_class_info_args_mutex);
+    
+    // Fill in our function argument values
+    arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
+    arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+    arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+    
+    bool success = false;
+    
+    errors.Clear();
+    
+    // Write our function arguments into the process so we can run our function
+    if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
+                                                           m_get_class_info_args,
+                                                           function_address,
+                                                           arguments,
+                                                           errors))
+    {
+        bool stop_others = true;
+        bool try_all_threads = false;
+        bool unwind_on_error = true;
+        bool ignore_breakpoints = true;
+        
+        Value return_value;
+        return_value.SetValueType (Value::eValueTypeScalar);
+        return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        return_value.GetScalar() = 0;
+        
+        errors.Clear();
+        
+        // Run the function
+        ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
+                                                                               &m_get_class_info_args,
+                                                                               errors,
+                                                                               stop_others,
+                                                                               UTILITY_FUNCTION_TIMEOUT_USEC,
+                                                                               try_all_threads,
+                                                                               unwind_on_error,
+                                                                               ignore_breakpoints,
+                                                                               return_value);
+        
+        if (results == eExecutionCompleted)
+        {
+            // The result is the number of ClassInfo structures that were filled in
+            uint32_t num_class_infos = return_value.GetScalar().ULong();
+            if (log)
+                log->Printf("Discovered %u ObjC classes\n",num_class_infos);
+            if (num_class_infos > 0)
+            {
+                // Read the ClassInfo structures
+                DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+                if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
+                {
+                    DataExtractor class_infos_data (buffer.GetBytes(),
+                                                    buffer.GetByteSize(),
+                                                    process->GetByteOrder(),
+                                                    addr_size);
+                    ParseClassInfoArray (class_infos_data, num_class_infos);
+                }
+            }
+            success = true;
+        }
+        else
+        {
+            if (log)
+                log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+        }
+    }
+    else
+    {
+        if (log)
+            log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+    }
+    
+    // Deallocate the memory we allocated for the ClassInfo array
+    process->DeallocateMemory(class_infos_addr);
+    
+    return success;
+}
+
+void
+AppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
+{
+    // Parses an array of "num_class_infos" packed ClassInfo structures:
+    //
+    //    struct ClassInfo
+    //    {
+    //        Class isa;
+    //        uint32_t hash;
+    //    } __attribute__((__packed__));
+
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+    // Iterate through all ClassInfo structures
+    lldb::offset_t offset = 0;
+    for (uint32_t i=0; i<num_class_infos; ++i)
+    {
+        ObjCISA isa = data.GetPointer(&offset);
+        
+        if (isa == 0)
+        {
+            if (log)
+                log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+            continue;
+        }
+        // Check if we already know about this ISA, if we do, the info will
+        // never change, so we can just skip it.
+        if (ISAIsCached(isa))
+        {
+            offset += 4;
+        }
+        else
+        {
+            // Read the 32 bit hash for the class name
+            const uint32_t name_hash = data.GetU32(&offset);
+            ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
+            AddClass (isa, descriptor_sp, name_hash);
+            if (log && log->GetVerbose())
+                log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x", isa, name_hash);
+        }
+    }
+}
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
+{
+    Process *process = GetProcess();
+    
+    if (process == NULL)
+        return false;
+    
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    
+    ExecutionContext exe_ctx;
+    
+    ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+    
+    if (!thread_sp)
+        return false;
+    
+    thread_sp->CalculateExecutionContext(exe_ctx);
+    ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+    
+    if (!ast)
+        return false;
+    
+    Address function_address;
+    
+    StreamString errors;
+    
+    const uint32_t addr_size = process->GetAddressByteSize();
+    
+    Error err;
+    
+    const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+    
+    if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+        return false;
+    
+    // Read the total number of classes from the hash table
+    const uint32_t num_classes = 16*1024;
+    if (num_classes == 0)
+    {
+        if (log)
+            log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
+        return false;
+    }
+    
+    // Make some types for our arguments
+    clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+    clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+    
+    if (!m_get_shared_cache_class_info_code.get())
+    {
+        m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
+                                                                            g_get_shared_cache_class_info_name));
+        
+        errors.Clear();
+        
+        if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+        {
+            if (log)
+                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+            m_get_shared_cache_class_info_code.reset();
+        }
+    }
+    
+    if (m_get_shared_cache_class_info_code.get())
+        function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
+    else
+        return false;
+    
+    ValueList arguments;
+    
+    // Next make the runner function for our implementation utility function.
+    if (!m_get_shared_cache_class_info_function.get())
+    {
+        Value value;
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        arguments.PushValue (value);
+        
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+        arguments.PushValue (value);
+        
+        value.SetValueType (Value::eValueTypeScalar);
+        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        arguments.PushValue (value);
+        
+        m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
+                                                                        ast,
+                                                                        clang_uint32_t_type,
+                                                                        function_address,
+                                                                        arguments));
+        
+        if (m_get_shared_cache_class_info_function.get() == NULL)
+            return false;
+        
+        errors.Clear();
+        
+        unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
+        if (num_errors)
+        {
+            if (log)
+                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+            return false;
+        }
+        
+        errors.Clear();
+        
+        if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+        {
+            if (log)
+                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+            return false;
+        }
+    }
+    else
+    {
+        arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
+    }
     
-    //printf("name_pointer: %llx\n", name_pointer);
-    char cstr[512];
-    if (m_process->ReadCStringFromMemory(name_pointer, cstr, sizeof(cstr), error) > 0)
-    {
-        if (::strstr(cstr, "NSKVONotify") == cstr)
-        {
-            // the ObjC runtime implements KVO by replacing the isa with a special
-            // NSKVONotifying_className that overrides the relevant methods
-            // the side effect on us is that getting the typename for a KVO-ed object
-            // will return the swizzled class instead of the actual one
-            // this swizzled class is a descendant of the real class, so just
-            // return the parent type and all should be fine
-            ConstString class_name = GetActualTypeName(GetParentClass(isa));
-            m_isa_to_name_cache[isa] = class_name;
-            return class_name;
+    const uint32_t class_info_byte_size = addr_size + 4;
+    const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+    lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
+                                                             ePermissionsReadable | ePermissionsWritable,
+                                                             err);
+    
+    if (class_infos_addr == LLDB_INVALID_ADDRESS)
+        return false;
+    
+    Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
+    
+    // Fill in our function argument values
+    arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
+    arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+    arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+    
+    bool success = false;
+    
+    errors.Clear();
+    
+    // Write our function arguments into the process so we can run our function
+    if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
+                                                                        m_get_shared_cache_class_info_args,
+                                                                        function_address,
+                                                                        arguments,
+                                                                        errors))
+    {
+        bool stop_others = true;
+        bool try_all_threads = false;
+        bool unwind_on_error = true;
+        bool ignore_breakpoints = true;
+        
+        Value return_value;
+        return_value.SetValueType (Value::eValueTypeScalar);
+        return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+        return_value.GetScalar() = 0;
+        
+        errors.Clear();
+        
+        // Run the function
+        ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
+                                                                                            &m_get_shared_cache_class_info_args,
+                                                                                            errors,
+                                                                                            stop_others,
+                                                                                            UTILITY_FUNCTION_TIMEOUT_USEC,
+                                                                                            try_all_threads,
+                                                                                            unwind_on_error,
+                                                                                            ignore_breakpoints,
+                                                                                            return_value);
+        
+        if (results == eExecutionCompleted)
+        {
+            // The result is the number of ClassInfo structures that were filled in
+            uint32_t num_class_infos = return_value.GetScalar().ULong();
+            if (log)
+                log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
+            if (num_class_infos > 0)
+            {
+                // Read the ClassInfo structures
+                DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+                if (process->ReadMemory(class_infos_addr,
+                                        buffer.GetBytes(),
+                                        buffer.GetByteSize(),
+                                        err) == buffer.GetByteSize())
+                {
+                    DataExtractor class_infos_data (buffer.GetBytes(),
+                                                    buffer.GetByteSize(),
+                                                    process->GetByteOrder(),
+                                                    addr_size);
+                    
+                    ParseClassInfoArray (class_infos_data, num_class_infos);
+                }
+            }
+            success = true;
         }
         else
         {
-            ConstString class_name = ConstString(cstr);
-            m_isa_to_name_cache[isa] = class_name;
-            return class_name;
+            if (log)
+                log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
         }
     }
     else
-        return g_unknown;
+    {
+        if (log)
+            log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+    }
+    
+    // Deallocate the memory we allocated for the ClassInfo array
+    process->DeallocateMemory(class_infos_addr);
+    
+    return success;
+}
+
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
+{
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    
+    Process *process = GetProcess();
+
+    if (process == NULL)
+        return false;
+    
+    uint32_t num_map_table_isas = 0;
+    
+    ModuleSP objc_module_sp(GetObjCModule());
+    
+    if (objc_module_sp)
+    {
+        for (RemoteNXMapTable::element elt : hash_table)
+        {
+            ++num_map_table_isas;
+            
+            if (ISAIsCached(elt.second))
+                continue;
+            
+            ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
+            
+            if (log && log->GetVerbose())
+                log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
+            
+            AddClass (elt.second, descriptor_sp, elt.first.AsCString());
+        }
+    }
+    
+    return num_map_table_isas > 0;
 }
 
-ObjCLanguageRuntime::ObjCISA
-AppleObjCRuntimeV2::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
+lldb::addr_t
+AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
 {
-    if (!IsValidISA(isa))
-        return 0;
+    Process *process = GetProcess();
+    
+    if (process)
+    {
+        ModuleSP objc_module_sp(GetObjCModule());
+        
+        if (objc_module_sp)
+        {
+            ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+            
+            if (objc_object)
+            {
+                SectionList *section_list = objc_object->GetSectionList();
+                
+                if (section_list)
+                {
+                    SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
+                    
+                    if (text_segment_sp)
+                    {
+                        SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
+                        
+                        if (objc_opt_section_sp)
+                        {
+                            return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return LLDB_INVALID_ADDRESS;
+}
+
+void
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+{
+    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
     
+    // Else we need to check with our process to see when the map was updated.
+    Process *process = GetProcess();
+
+    if (process)
+    {
+        RemoteNXMapTable hash_table;
+        
+        // Update the process stop ID that indicates the last time we updated the
+        // map, wether it was successful or not.
+        m_isa_to_descriptor_stop_id = process->GetStopID();
+        
+        if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+            return;
+        
+        m_hash_signature.UpdateSignature (hash_table);
+
+        // Grab the dynamicly loaded objc classes from the hash table in memory
+        UpdateISAToDescriptorMapDynamic(hash_table);
+
+        // Now get the objc classes that are baked into the Objective C runtime
+        // in the shared cache, but only once per process as this data never
+        // changes
+        if (!m_loaded_objc_opt)
+            UpdateISAToDescriptorMapSharedCache();
+    }
+    else
+    {
+        m_isa_to_descriptor_stop_id = UINT32_MAX;
+    }
+}
+
+
+// TODO: should we have a transparent_kvo parameter here to say if we
+// want to replace the KVO swizzled class with the actual user-level type?
+ConstString
+AppleObjCRuntimeV2::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
+{
     if (isa == g_objc_Tagged_ISA)
-        return 0;
+    {
+        static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
+        return g_objc_tagged_isa_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSAtom)
+    {
+        static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
+        return g_objc_tagged_isa_nsatom_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSNumber)
+    {
+        static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
+        return g_objc_tagged_isa_nsnumber_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSDateTS)
+    {
+        static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
+        return g_objc_tagged_isa_nsdatets_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSManagedObject)
+    {
+        static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
+        return g_objc_tagged_isa_nsmanagedobject_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSDate)
+    {
+        static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
+        return g_objc_tagged_isa_nsdate_name;
+    }
+    return ObjCLanguageRuntime::GetActualTypeName(isa);
+}
+
+TypeVendor *
+AppleObjCRuntimeV2::GetTypeVendor()
+{
+    if (!m_type_vendor_ap.get())
+        m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
+    
+    return m_type_vendor_ap.get();
+}
+
+lldb::addr_t
+AppleObjCRuntimeV2::LookupRuntimeSymbol (const ConstString &name)
+{
+    lldb::addr_t ret = LLDB_INVALID_ADDRESS;
+
+    const char *name_cstr = name.AsCString();    
+    
+    if (name_cstr)
+    {
+        llvm::StringRef name_strref(name_cstr);
+        
+        static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
+        static const llvm::StringRef class_prefix("OBJC_CLASS_$_");
+        
+        if (name_strref.startswith(ivar_prefix))
+        {
+            llvm::StringRef ivar_skipped_prefix = name_strref.substr(ivar_prefix.size());
+            std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar = ivar_skipped_prefix.split('.');
+            
+            if (class_and_ivar.first.size() && class_and_ivar.second.size())
+            {
+                const ConstString class_name_cs(class_and_ivar.first);
+                ClassDescriptorSP descriptor = ObjCLanguageRuntime::GetClassDescriptorFromClassName(class_name_cs);
+                                
+                if (descriptor)
+                {
+                    const ConstString ivar_name_cs(class_and_ivar.second);
+                    const char *ivar_name_cstr = ivar_name_cs.AsCString();
+                    
+                    auto ivar_func = [&ret, ivar_name_cstr](const char *name, const char *type, lldb::addr_t offset_addr, uint64_t size) -> lldb::addr_t
+                    {
+                        if (!strcmp(name, ivar_name_cstr))
+                        {
+                            ret = offset_addr;
+                            return true;
+                        }
+                        return false;
+                    };
+
+                    descriptor->Describe(std::function<void (ObjCISA)>(nullptr),
+                                         std::function<bool (const char *, const char *)>(nullptr),
+                                         std::function<bool (const char *, const char *)>(nullptr),
+                                         ivar_func);
+                }
+            }
+        }
+        else if (name_strref.startswith(class_prefix))
+        {
+            llvm::StringRef class_skipped_prefix = name_strref.substr(class_prefix.size());
+            const ConstString class_name_cs(class_skipped_prefix);
+            ClassDescriptorSP descriptor = GetClassDescriptorFromClassName(class_name_cs);
+            
+            if (descriptor)
+                ret = descriptor->GetISA();
+        }
+    }
+    
+    return ret;
+}
+
+AppleObjCRuntimeV2::NonPointerISACache*
+AppleObjCRuntimeV2::NonPointerISACache::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
+{
+    Process* process(runtime.GetProcess());
+    
+    Error error;
     
-    ISAToParentIterator found = m_isa_to_parent_cache.find(isa);
-    ISAToParentIterator end = m_isa_to_parent_cache.end();
+    auto objc_debug_isa_magic_mask = ExtractRuntimeGlobalSymbol(process,
+                                                                ConstString("objc_debug_isa_magic_mask"),
+                                                                objc_module_sp,
+                                                                error);
+    if (error.Fail())
+        return NULL;
+
+    auto objc_debug_isa_magic_value = ExtractRuntimeGlobalSymbol(process,
+                                                                 ConstString("objc_debug_isa_magic_value"),
+                                                                 objc_module_sp,
+                                                                 error);
+    if (error.Fail())
+        return NULL;
+
+    auto objc_debug_isa_class_mask = ExtractRuntimeGlobalSymbol(process,
+                                                                ConstString("objc_debug_isa_class_mask"),
+                                                                objc_module_sp,
+                                                                error);
+    if (error.Fail())
+        return NULL;
+
+    // we might want to have some rules to outlaw these other values (e.g if the mask is zero but the value is non-zero, ...)
     
-    if (found != end)
-        return found->second;
+    return new NonPointerISACache(runtime,
+                                  objc_debug_isa_class_mask,
+                                  objc_debug_isa_magic_mask,
+                                  objc_debug_isa_magic_value);
+}
+
+AppleObjCRuntimeV2::TaggedPointerVendor*
+AppleObjCRuntimeV2::TaggedPointerVendor::CreateInstance (AppleObjCRuntimeV2& runtime, const lldb::ModuleSP& objc_module_sp)
+{
+    Process* process(runtime.GetProcess());
     
-    uint8_t pointer_size = m_process->GetAddressByteSize();
     Error error;
-    /*
-     struct class_t *isa;
--->     struct class_t *superclass;
-     */
-    addr_t parent_pointer = isa + pointer_size;
-    //printf("rw_pointer: %llx\n", rw_pointer);
-    
-    uint64_t parent_isa =  m_process->ReadUnsignedIntegerFromMemory(parent_pointer,
-                                                                    pointer_size,
-                                                                    0,
+    
+    auto objc_debug_taggedpointer_mask = ExtractRuntimeGlobalSymbol(process,
+                                                                    ConstString("objc_debug_taggedpointer_mask"),
+                                                                    objc_module_sp,
                                                                     error);
     if (error.Fail())
-        return 0;
+        return new TaggedPointerVendorLegacy(runtime);
+    
+    auto objc_debug_taggedpointer_slot_shift = ExtractRuntimeGlobalSymbol(process,
+                                                                          ConstString("objc_debug_taggedpointer_slot_shift"),
+                                                                          objc_module_sp,
+                                                                          error,
+                                                                          true,
+                                                                          4);
+    if (error.Fail())
+        return new TaggedPointerVendorLegacy(runtime);
+    
+    auto objc_debug_taggedpointer_slot_mask = ExtractRuntimeGlobalSymbol(process,
+                                                                          ConstString("objc_debug_taggedpointer_slot_mask"),
+                                                                          objc_module_sp,
+                                                                          error,
+                                                                          true,
+                                                                          4);
+    if (error.Fail())
+        return new TaggedPointerVendorLegacy(runtime);
+
+    auto objc_debug_taggedpointer_payload_lshift = ExtractRuntimeGlobalSymbol(process,
+                                                                              ConstString("objc_debug_taggedpointer_payload_lshift"),
+                                                                              objc_module_sp,
+                                                                              error,
+                                                                              true,
+                                                                              4);
+    if (error.Fail())
+        return new TaggedPointerVendorLegacy(runtime);
+    
+    auto objc_debug_taggedpointer_payload_rshift = ExtractRuntimeGlobalSymbol(process,
+                                                                              ConstString("objc_debug_taggedpointer_payload_rshift"),
+                                                                              objc_module_sp,
+                                                                              error,
+                                                                              true,
+                                                                              4);
+    if (error.Fail())
+        return new TaggedPointerVendorLegacy(runtime);
+    
+    auto objc_debug_taggedpointer_classes = ExtractRuntimeGlobalSymbol(process,
+                                                                       ConstString("objc_debug_taggedpointer_classes"),
+                                                                       objc_module_sp,
+                                                                       error,
+                                                                       false);
+    if (error.Fail())
+        return new TaggedPointerVendorLegacy(runtime);
+
+    
+    // we might want to have some rules to outlaw these values (e.g if the table's address is zero)
+    
+    return new TaggedPointerVendorRuntimeAssisted(runtime,
+                                                  objc_debug_taggedpointer_mask,
+                                                  objc_debug_taggedpointer_slot_shift,
+                                                  objc_debug_taggedpointer_slot_mask,
+                                                  objc_debug_taggedpointer_payload_lshift,
+                                                  objc_debug_taggedpointer_payload_rshift,
+                                                  objc_debug_taggedpointer_classes);
+}
+
+bool
+AppleObjCRuntimeV2::TaggedPointerVendorLegacy::IsPossibleTaggedPointer (lldb::addr_t ptr)
+{
+    return (ptr & 1);
+}
+
+// we use the version of Foundation to make assumptions about the ObjC runtime on a target
+uint32_t
+AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetFoundationVersion (Target &target)
+{
+    const ModuleList& modules = target.GetImages();
+    uint32_t major = UINT32_MAX;
+    for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
+    {
+        lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
+        if (!module_sp)
+            continue;
+        if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),"Foundation") == 0)
+        {
+            module_sp->GetVersion(&major,1);
+            break;
+        }
+    }
+    return major;
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::TaggedPointerVendorLegacy::GetClassDescriptor (lldb::addr_t ptr)
+{
+    if (!IsPossibleTaggedPointer(ptr))
+        return ObjCLanguageRuntime::ClassDescriptorSP();
+
+    Process* process(m_runtime.GetProcess());
+    
+    if (m_Foundation_version == 0)
+        m_Foundation_version = GetFoundationVersion(process->GetTarget());
+    
+    if (m_Foundation_version == UINT32_MAX)
+        return ObjCLanguageRuntime::ClassDescriptorSP();
     
-    m_isa_to_parent_cache[isa] = parent_isa;
+    uint64_t class_bits = (ptr & 0xE) >> 1;
+    ConstString name;
     
-    return parent_isa;
+    // TODO: make a table
+    if (m_Foundation_version >= 900)
+    {
+        switch (class_bits)
+        {
+            case 0:
+                name = ConstString("NSAtom");
+                break;
+            case 3:
+                name = ConstString("NSNumber");
+                break;
+            case 4:
+                name = ConstString("NSDateTS");
+                break;
+            case 5:
+                name = ConstString("NSManagedObject");
+                break;
+            case 6:
+                name = ConstString("NSDate");
+                break;
+            default:
+                return ObjCLanguageRuntime::ClassDescriptorSP();
+        }
+    }
+    else
+    {
+        switch (class_bits)
+        {
+            case 1:
+                name = ConstString("NSNumber");
+                break;
+            case 5:
+                name = ConstString("NSManagedObject");
+                break;
+            case 6:
+                name = ConstString("NSDate");
+                break;
+            case 7:
+                name = ConstString("NSDateTS");
+                break;
+            default:
+                return ObjCLanguageRuntime::ClassDescriptorSP();
+        }
+    }
+    return ClassDescriptorSP(new ClassDescriptorV2Tagged(name,ptr));
+}
+
+AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
+                                                                                            uint64_t objc_debug_taggedpointer_mask,
+                                                                                            uint32_t objc_debug_taggedpointer_slot_shift,
+                                                                                            uint32_t objc_debug_taggedpointer_slot_mask,
+                                                                                            uint32_t objc_debug_taggedpointer_payload_lshift,
+                                                                                            uint32_t objc_debug_taggedpointer_payload_rshift,
+                                                                                            lldb::addr_t objc_debug_taggedpointer_classes) :
+TaggedPointerVendor(runtime),
+m_cache(),
+m_objc_debug_taggedpointer_mask(objc_debug_taggedpointer_mask),
+m_objc_debug_taggedpointer_slot_shift(objc_debug_taggedpointer_slot_shift),
+m_objc_debug_taggedpointer_slot_mask(objc_debug_taggedpointer_slot_mask),
+m_objc_debug_taggedpointer_payload_lshift(objc_debug_taggedpointer_payload_lshift),
+m_objc_debug_taggedpointer_payload_rshift(objc_debug_taggedpointer_payload_rshift),
+m_objc_debug_taggedpointer_classes(objc_debug_taggedpointer_classes)
+{
+}
+
+bool
+AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::IsPossibleTaggedPointer (lldb::addr_t ptr)
+{
+    return (ptr & m_objc_debug_taggedpointer_mask) != 0;
 }
 
-SymbolVendor *
-AppleObjCRuntimeV2::GetSymbolVendor()
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb::addr_t ptr)
 {
-    if (!m_symbol_vendor_ap.get())
-        m_symbol_vendor_ap.reset(new AppleObjCSymbolVendor(m_process));
+    ClassDescriptorSP actual_class_descriptor_sp;
+    uint64_t data_payload;
+
+    if (!IsPossibleTaggedPointer(ptr))
+        return ObjCLanguageRuntime::ClassDescriptorSP();
+    
+    uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_slot_shift) & m_objc_debug_taggedpointer_slot_mask;
+    
+    CacheIterator iterator = m_cache.find(slot),
+    end = m_cache.end();
+    if (iterator != end)
+    {
+        actual_class_descriptor_sp = iterator->second;
+    }
+    else
+    {
+        Process* process(m_runtime.GetProcess());
+        uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_classes;
+        Error error;
+        uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
+        if (error.Fail() || slot_data == 0 || slot_data == LLDB_INVALID_ADDRESS)
+            return nullptr;
+        actual_class_descriptor_sp = m_runtime.GetClassDescriptor(slot_data);
+        if (!actual_class_descriptor_sp)
+            return ObjCLanguageRuntime::ClassDescriptorSP();
+        m_cache[slot] = actual_class_descriptor_sp;
+    }
+    
+    data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_payload_lshift) >> m_objc_debug_taggedpointer_payload_rshift);
     
-    return m_symbol_vendor_ap.get();
+    return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
+}
+
+AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
+                                                            uint64_t objc_debug_isa_class_mask,
+                                                            uint64_t objc_debug_isa_magic_mask,
+                                                            uint64_t objc_debug_isa_magic_value) :
+m_runtime(runtime),
+m_cache(),
+m_objc_debug_isa_class_mask(objc_debug_isa_class_mask),
+m_objc_debug_isa_magic_mask(objc_debug_isa_magic_mask),
+m_objc_debug_isa_magic_value(objc_debug_isa_magic_value)
+{
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor (ObjCISA isa)
+{
+    ObjCISA real_isa = 0;
+    if (EvaluateNonPointerISA(isa, real_isa) == false)
+        return ObjCLanguageRuntime::ClassDescriptorSP();
+    auto cache_iter = m_cache.find(real_isa);
+    if (cache_iter != m_cache.end())
+        return cache_iter->second;
+    auto descriptor_sp = m_runtime.ObjCLanguageRuntime::GetClassDescriptorFromISA(real_isa);
+    if (descriptor_sp) // cache only positive matches since the table might grow
+        m_cache[real_isa] = descriptor_sp;
+    return descriptor_sp;
+}
+
+bool
+AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa)
+{
+    if ( (isa & ~m_objc_debug_isa_class_mask) == 0)
+        return false;
+    if ( (isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value)
+    {
+        ret_isa = isa & m_objc_debug_isa_class_mask;
+        return (ret_isa != 0); // this is a pointer so 0 is not a valid value
+    }
+    return false;
 }

Modified: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=183468&r1=183467&r2=183468&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Thu Jun  6 19:06:43 2013
@@ -14,6 +14,7 @@
 // C++ Includes
 
 #include <map>
+#include <memory>
 
 // Other libraries and framework includes
 // Project includes
@@ -21,13 +22,15 @@
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "AppleObjCRuntime.h"
 
+class RemoteNXMapTable;
+
 namespace lldb_private {
 
 class AppleObjCRuntimeV2 :
         public AppleObjCRuntime
 {
 public:
-    virtual ~AppleObjCRuntimeV2() { }
+    virtual ~AppleObjCRuntimeV2();
     
     // These are generic runtime functions:
     virtual bool
@@ -52,15 +55,15 @@ public:
     static lldb_private::LanguageRuntime *
     CreateInstance (Process *process, lldb::LanguageType language);
     
+    static lldb_private::ConstString
+    GetPluginNameStatic();
+    
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
-    virtual const char *
+    virtual ConstString
     GetPluginName();
     
-    virtual const char *
-    GetShortPluginName();
-    
     virtual uint32_t
     GetPluginVersion();
     
@@ -72,29 +75,35 @@ public:
 
     virtual size_t
     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
+
+    virtual void
+    UpdateISAToDescriptorMapIfNeeded();
     
-    virtual bool
-    IsValidISA (ObjCLanguageRuntime::ObjCISA isa)
-    {
-        return (isa != 0);
-    }
-    
-    // this is not a valid ISA in the sense that no valid
-    // class pointer can live at address 1. we use it to refer to
-    // tagged types, where the ISA must be dynamically determined
+    // none of these are valid ISAs - we use them to infer the type
+    // of tagged pointers - if we have something meaningful to say
+    // we report an actual type - otherwise, we just say tagged
+    // there is no connection between the values here and the tagged pointers map
     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
-    
-    virtual ObjCLanguageRuntime::ObjCISA
-    GetISA(ValueObject& valobj);   
-    
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = 5;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
+
     virtual ConstString
     GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa);
     
-    virtual ObjCLanguageRuntime::ObjCISA
-    GetParentClass(ObjCLanguageRuntime::ObjCISA isa);
+    virtual ClassDescriptorSP
+    GetClassDescriptor (ValueObject& in_value);
     
-    virtual SymbolVendor *
-    GetSymbolVendor();
+    virtual ClassDescriptorSP
+    GetClassDescriptor (ObjCISA isa);
+    
+    virtual TypeVendor *
+    GetTypeVendor();
+    
+    virtual lldb::addr_t
+    LookupRuntimeSymbol (const ConstString &name);
     
 protected:
     virtual lldb::BreakpointResolverSP
@@ -102,33 +111,178 @@ protected:
 
 private:
     
-    typedef std::map<ObjCLanguageRuntime::ObjCISA, ConstString> ISAToNameCache;
-    typedef std::map<ObjCLanguageRuntime::ObjCISA, ObjCLanguageRuntime::ObjCISA> ISAToParentCache;
+    class HashTableSignature
+    {
+    public:
+        HashTableSignature ();
+
+        bool
+        NeedsUpdate (Process *process,
+                     AppleObjCRuntimeV2 *runtime,
+                     RemoteNXMapTable &hash_table);
+        
+        void
+        UpdateSignature (const RemoteNXMapTable &hash_table);
+    protected:
+        uint32_t m_count;
+        uint32_t m_num_buckets;
+        lldb::addr_t m_buckets_ptr;
+    };
+
+    class NonPointerISACache
+    {
+    public:
+        static NonPointerISACache*
+        CreateInstance (AppleObjCRuntimeV2& runtime,
+                        const lldb::ModuleSP& objc_module_sp);
+        
+
+        ObjCLanguageRuntime::ClassDescriptorSP
+        GetClassDescriptor (ObjCISA isa);
+    private:
+        NonPointerISACache (AppleObjCRuntimeV2& runtime,
+                            uint64_t objc_debug_isa_class_mask,
+                            uint64_t objc_debug_isa_magic_mask,
+                            uint64_t objc_debug_isa_magic_value);
+        
+        bool
+        EvaluateNonPointerISA (ObjCISA isa, ObjCISA& ret_isa);
+        
+        AppleObjCRuntimeV2&                                         m_runtime;
+        std::map<ObjCISA,ObjCLanguageRuntime::ClassDescriptorSP>    m_cache;
+        uint64_t                                                    m_objc_debug_isa_class_mask;
+        uint64_t                                                    m_objc_debug_isa_magic_mask;
+        uint64_t                                                    m_objc_debug_isa_magic_value;
+
+        DISALLOW_COPY_AND_ASSIGN(NonPointerISACache);
+    };
+    
+    class TaggedPointerVendor
+    {
+    public:
+        static TaggedPointerVendor*
+        CreateInstance (AppleObjCRuntimeV2& runtime,
+                        const lldb::ModuleSP& objc_module_sp);
+        
+        virtual bool
+        IsPossibleTaggedPointer (lldb::addr_t ptr) = 0;
+        
+        virtual ObjCLanguageRuntime::ClassDescriptorSP
+        GetClassDescriptor (lldb::addr_t ptr) = 0;
+        
+        virtual
+        ~TaggedPointerVendor () { }
+    protected:
+        AppleObjCRuntimeV2&                                         m_runtime;
+        
+        TaggedPointerVendor (AppleObjCRuntimeV2& runtime) :
+        m_runtime(runtime)
+        {
+        }
+    private:
+        
+        DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendor);
+    };
+    
+    class TaggedPointerVendorRuntimeAssisted : public TaggedPointerVendor
+    {
+    public:
+        virtual bool
+        IsPossibleTaggedPointer (lldb::addr_t ptr);
+        
+        virtual ObjCLanguageRuntime::ClassDescriptorSP
+        GetClassDescriptor (lldb::addr_t ptr);
+    protected:
+        TaggedPointerVendorRuntimeAssisted (AppleObjCRuntimeV2& runtime,
+                                             uint64_t objc_debug_taggedpointer_mask,
+                                             uint32_t objc_debug_taggedpointer_slot_shift,
+                                             uint32_t objc_debug_taggedpointer_slot_mask,
+                                             uint32_t objc_debug_taggedpointer_payload_lshift,
+                                             uint32_t objc_debug_taggedpointer_payload_rshift,
+                                             lldb::addr_t objc_debug_taggedpointer_classes);
+        
+        typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
+        typedef Cache::iterator CacheIterator;
+        Cache                                                       m_cache;
+        uint64_t                                                    m_objc_debug_taggedpointer_mask;
+        uint32_t                                                    m_objc_debug_taggedpointer_slot_shift;
+        uint32_t                                                    m_objc_debug_taggedpointer_slot_mask;
+        uint32_t                                                    m_objc_debug_taggedpointer_payload_lshift;
+        uint32_t                                                    m_objc_debug_taggedpointer_payload_rshift;
+        lldb::addr_t                                                m_objc_debug_taggedpointer_classes;
+        
+        friend class AppleObjCRuntimeV2::TaggedPointerVendor;
+        
+        DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
+    };
     
-    typedef ISAToNameCache::iterator ISAToNameIterator;
-    typedef ISAToParentCache::iterator ISAToParentIterator;
+    class TaggedPointerVendorLegacy : public TaggedPointerVendor
+    {
+    public:
+        virtual bool
+        IsPossibleTaggedPointer (lldb::addr_t ptr);
+        
+        virtual ObjCLanguageRuntime::ClassDescriptorSP
+        GetClassDescriptor (lldb::addr_t ptr);
+    protected:
+        TaggedPointerVendorLegacy (AppleObjCRuntimeV2& runtime) :
+        TaggedPointerVendor (runtime),
+        m_Foundation_version(0)
+        {
+        }
+        
+        static uint32_t
+        GetFoundationVersion (Target& target);
+        
+        uint32_t m_Foundation_version;
+        
+        friend class AppleObjCRuntimeV2::TaggedPointerVendor;
+        
+        DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorLegacy);
+    };
     
-    AppleObjCRuntimeV2 (Process *process, 
+    AppleObjCRuntimeV2 (Process *process,
                         const lldb::ModuleSP &objc_module_sp);
     
     bool
     IsTaggedPointer(lldb::addr_t ptr);
     
-    bool RunFunctionToFindClassName (lldb::addr_t class_addr, Thread *thread, char *name_dst, size_t max_name_len);
+    lldb::addr_t
+    GetISAHashTablePointer ();
+
+    bool
+    UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table);
     
-    bool                                m_has_object_getClass;
-    std::auto_ptr<ClangFunction>        m_get_class_name_function;
-    std::auto_ptr<ClangUtilityFunction> m_get_class_name_code;
-    lldb::addr_t                        m_get_class_name_args;
-    Mutex                               m_get_class_name_args_mutex;
+    bool
+    UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
     
-    ISAToNameCache                      m_isa_to_name_cache;
-    ISAToParentCache                    m_isa_to_parent_cache;
+    void
+    ParseClassInfoArray (const lldb_private::DataExtractor &data,
+                         uint32_t num_class_infos);
     
-    std::auto_ptr<SymbolVendor>         m_symbol_vendor_ap;
+    bool
+    UpdateISAToDescriptorMapSharedCache ();
+
+    lldb::addr_t
+    GetSharedCacheReadOnlyAddress();
     
-    static const char *g_find_class_name_function_name;
-    static const char *g_find_class_name_function_body;
+    std::unique_ptr<ClangFunction>            m_get_class_info_function;
+    std::unique_ptr<ClangUtilityFunction>     m_get_class_info_code;
+    lldb::addr_t                            m_get_class_info_args;
+    Mutex                                   m_get_class_info_args_mutex;
+
+    std::unique_ptr<ClangFunction>            m_get_shared_cache_class_info_function;
+    std::unique_ptr<ClangUtilityFunction>     m_get_shared_cache_class_info_code;
+    lldb::addr_t                            m_get_shared_cache_class_info_args;
+    Mutex                                   m_get_shared_cache_class_info_args_mutex;
+
+    std::unique_ptr<TypeVendor>               m_type_vendor_ap;
+    lldb::addr_t                            m_isa_hash_table_ptr;
+    HashTableSignature                      m_hash_signature;
+    bool                                    m_has_object_getClass;
+    bool                                    m_loaded_objc_opt;
+    std::unique_ptr<NonPointerISACache>       m_non_pointer_isa_cache_ap;
+    std::unique_ptr<TaggedPointerVendor>    m_tagged_pointer_vendor_ap;
 };
     
 } // namespace lldb_private

Removed: lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp?rev=183467&view=auto
==============================================================================
--- lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCSymbolVendor.cpp (removed)
@@ -1,82 +0,0 @@
-//===-- AppleObjCSymbolVendor.cpp -------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AppleObjCSymbolVendor.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-
-#include "clang/AST/ASTContext.h"
-
-using namespace lldb_private;
-
-AppleObjCSymbolVendor::AppleObjCSymbolVendor(Process *process) :
-    SymbolVendor(lldb::ModuleSP()),
-    m_process(process->shared_from_this()),
-    m_ast_ctx(process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str())
-{
-}
-
-uint32_t
-AppleObjCSymbolVendor::FindTypes (const SymbolContext& sc, 
-                                  const ConstString &name,
-                                  const ClangNamespaceDecl *namespace_decl, 
-                                  bool append, 
-                                  uint32_t max_matches, 
-                                  TypeList& types)
-{
-    lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));  // FIXME - a more appropriate log channel?
-        
-    if (log)
-        log->Printf("ObjC SymbolVendor asked for '%s'", 
-                    name.AsCString());
-    
-    if (!append)
-        types.Clear();
-    
-    uint32_t ret = 0;
-    
-    ModuleList &target_modules = m_process->GetTarget().GetImages();
-    Mutex::Locker modules_locker(target_modules.GetMutex());
-    
-    for (size_t image_index = 0, end_index = target_modules.GetSize();
-         image_index < end_index;
-         ++image_index)
-    {
-        Module *image = target_modules.GetModulePointerAtIndexUnlocked(image_index);
-        
-        if (!image)
-            continue;
-        
-        SymbolVendor *symbol_vendor = image->GetSymbolVendor();
-        
-        if (!symbol_vendor)
-            continue;
-        
-        SymbolFile *symbol_file = image->GetSymbolVendor()->GetSymbolFile();
-        
-        // Don't use a symbol file if it actually has types. We are specifically
-        // looking for something in runtime information, not from debug information,
-        // as the data in debug information will get parsed by the debug info
-        // symbol files. So we veto any symbol file that has actual variable
-        // type parsing abilities.
-        if (symbol_file == NULL || (symbol_file->GetAbilities() & SymbolFile::VariableTypes))
-            continue;
-        
-        const bool inferior_append = true;
-        
-        ret += symbol_file->FindTypes (sc, name, namespace_decl, inferior_append, max_matches -