Example #1
0
void
IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
{
    error.Clear();
    
    if (size == UINT32_MAX)
        size = scalar.GetByteSize();
    
    if (size > 0)
    {
        uint8_t buf[32];
        const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
        if (mem_size > 0)
        {
            return WriteMemory(process_address, buf, mem_size, error);
        }
        else
        {
            error.SetErrorToGenericError();
            error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
        }
    }
    else
    {
        error.SetErrorToGenericError();
        error.SetErrorString ("Couldn't write scalar: its size was zero");
    }
    return;
}
Example #2
0
OperatingSystemGo::Goroutine
OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err)
{
    err.Clear();
    Goroutine result;
    ValueObjectSP g = m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
    if (err.Fail())
    {
        return result;
    }

    ConstString name("goid");
    ValueObjectSP val = g->GetChildMemberWithName(name, true);
    bool success = false;
    result.m_goid = val->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read goid");
        return result;
    }
    name.SetCString("atomicstatus");
    val = g->GetChildMemberWithName(name, true);
    result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read atomicstatus");
        return result;
    }
    name.SetCString("sched");
    val = g->GetChildMemberWithName(name, true);
    result.m_gobuf = val->GetAddressOf(false);
    name.SetCString("stack");
    val = g->GetChildMemberWithName(name, true);
    name.SetCString("lo");
    ValueObjectSP child = val->GetChildMemberWithName(name, true);
    result.m_lostack = child->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read stack.lo");
        return result;
    }
    name.SetCString("hi");
    child = val->GetChildMemberWithName(name, true);
    result.m_histack = child->GetValueAsUnsigned(0, &success);
    if (!success)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("unable to read stack.hi");
        return result;
    }
    return result;
}
Example #3
0
Error
ClangExpressionParser::MakeDWARF ()
{
    Error err;
    
    llvm::Module *module = m_code_generator->GetModule();
    
    if (!module)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    ClangExpressionVariableList *local_variables = m_expr.LocalVariables();
    ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
    
    if (!local_variables)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Can't convert an expression without a VariableList to DWARF");
        return err;
    }
    
    if (!decl_map)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Can't convert an expression without a DeclMap to DWARF");
        return err;
    }
    
    std::string function_name;
    
    if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    
    IRToDWARF ir_to_dwarf(*local_variables, decl_map, m_expr.DwarfOpcodeStream(), function_name.c_str());
    
    if (!ir_to_dwarf.runOnModule(*module))
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't convert the expression to DWARF");
        return err;
    }
    
    err.Clear();
    return err;
}
Example #4
0
Error
File::Sync ()
{
    Error error;
    if (DescriptorIsValid())
    {
#ifdef _WIN32
        int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor));
        if (err == 0)
            error.SetErrorToGenericError();
#else
        int err = 0;
        do
        {
            err = ::fsync (m_descriptor);
        } while (err == -1 && errno == EINTR);
        
        if (err == -1)
            error.SetErrorToErrno();
#endif
    }
    else 
    {
        error.SetErrorString("invalid file handle");
    }
    return error;
}
static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
{
    Error *err = static_cast<Error*>(Context);

    if (err && err->Success())
    {
        err->SetErrorToGenericError();
        err->SetErrorStringWithFormat("Inline assembly error: %s", diagnostic.getMessage().str().c_str());
    }
}
Example #6
0
void IRMemoryMap::ReadScalarFromMemory(Scalar &scalar,
                                       lldb::addr_t process_address,
                                       size_t size, Error &error) {
  error.Clear();

  if (size > 0) {
    DataBufferHeap buf(size, 0);
    ReadMemory(buf.GetBytes(), process_address, size, error);

    if (!error.Success())
      return;

    DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(),
                            GetAddressByteSize());

    lldb::offset_t offset = 0;

    switch (size) {
    default:
      error.SetErrorToGenericError();
      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;
    case 4:
      scalar = extractor.GetU32(&offset);
      break;
    case 8:
      scalar = extractor.GetU64(&offset);
      break;
    }
  } else {
    error.SetErrorToGenericError();
    error.SetErrorString("Couldn't read scalar: its size was zero");
  }
  return;
}
Example #7
0
void
IRMemoryMap::Free (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 free: allocation doesn't exist");
        return;
    }
    
    Allocation &allocation = iter->second;
        
    switch (allocation.m_policy)
    {
    default:
    case eAllocationPolicyHostOnly:
        {
            lldb::ProcessSP process_sp = m_process_wp.lock();
            if (process_sp)
            {
                if (process_sp->CanJIT() && process_sp->IsAlive())
                    process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
            }
    
            break;
        }
    case eAllocationPolicyMirror:
    case eAllocationPolicyProcessOnly:
        {
            lldb::ProcessSP process_sp = m_process_wp.lock();
            if (process_sp)
                process_sp->DeallocateMemory(allocation.m_process_alloc);
        }
    }
    
    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
    {        
        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);
    }
    
    m_allocations.erase(iter);
}
Example #8
0
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;
}
Example #9
0
void
IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
{
    error.Clear();
    
    AllocationMap::iterator iter = FindAllocation(process_address, size);
    
    if (iter == m_allocations.end())
    {
        lldb::ProcessSP process_sp = m_process_wp.lock();
        
        if (process_sp)
        {
            process_sp->ReadMemory(process_address, bytes, size, error);
            return;
        }
        
        lldb::TargetSP target_sp = m_target_wp.lock();
        
        if (target_sp)
        {
            Address absolute_address(process_address);
            target_sp->ReadMemory(absolute_address, false, bytes, size, error);
            return;
        }
        
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist");
        return;
    }
    
    Allocation &allocation = iter->second;
    
    uint64_t offset = process_address - allocation.m_process_start;
    
    if (offset > allocation.m_size)
    {
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't read: data is not in the allocation");
        return;
    }
    
    lldb::ProcessSP process_sp;
    
    switch (allocation.m_policy)
    {
    default:
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't read: invalid allocation policy");
        return;
    case eAllocationPolicyHostOnly:
        if (!allocation.m_data.GetByteSize())
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't read: data buffer is empty");
            return;
        }
        if (allocation.m_data.GetByteSize() < offset + size)
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't read: not enough underlying data");
            return;
        }

        ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
        break;
    case eAllocationPolicyMirror:
        process_sp = m_process_wp.lock();
        if (process_sp)
        {
            process_sp->ReadMemory(process_address, bytes, size, error);
            if (!error.Success())
                return;
        }
        else
        {
            if (!allocation.m_data.GetByteSize())
            {
                error.SetErrorToGenericError();
                error.SetErrorString("Couldn't read: data buffer is empty");
                return;
            }
            ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size);
        }
        break;
    case eAllocationPolicyProcessOnly:
        process_sp = m_process_wp.lock();
        if (process_sp)
        {
            process_sp->ReadMemory(process_address, bytes, size, error);
            if (!error.Success())
                return;
        }
        break;
    }
    
    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
    {
        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,
                    (uint64_t)allocation.m_process_start,
                    (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
    }
}
Example #10
0
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, 
                                            lldb::addr_t &func_addr, 
                                            lldb::addr_t &func_end, 
                                            ExecutionContext &exe_ctx,
                                            IRForTarget::StaticDataAllocator *data_allocator,
                                            bool &evaluated_statically,
                                            lldb::ClangExpressionVariableSP &const_result,
                                            ExecutionPolicy execution_policy)
{
    func_allocation_addr = LLDB_INVALID_ADDRESS;
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    std::auto_ptr<llvm::ExecutionEngine> execution_engine;
    
    Error err;
    
    llvm::Module *module = m_code_generator->ReleaseModule();

    if (!module)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    // Find the actual name of the function (it's often mangled somehow)
    
    std::string function_name;
    
    if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
    }
    
    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
    
    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = &target->GetDebugger().GetErrorStream();
    
        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  execution_policy,
                                  const_result,
                                  data_allocator,
                                  error_stream,
                                  function_name.c_str());
        
        ir_for_target.runOnModule(*module);
        
        Error &interpreter_error(ir_for_target.getInterpreterError());
        
        if (execution_policy != eExecutionPolicyAlways && interpreter_error.Success())
        {
            if (const_result)
                const_result->TransferAddress();
            evaluated_statically = true;
            err.Clear();
            return err;
        }
        
        Process *process = exe_ctx.GetProcessPtr();

        if (!process || execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorToGenericError();
            if (execution_policy == eExecutionPolicyAlways)
                err.SetErrorString("Execution needed to run in the target, but the target can't be run");
            else
                err.SetErrorStringWithFormat("Interpreting the expression locally failed: %s", interpreter_error.AsCString());

            return err;
        }
        
        if (execution_policy != eExecutionPolicyNever &&
            m_expr.NeedsValidation() && 
            process)
        {
            if (!process->GetDynamicCheckers())
            {                
                DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
                
                StreamString install_errors;
                
                if (!dynamic_checkers->Install(install_errors, exe_ctx))
                {
                    if (install_errors.GetString().empty())
                        err.SetErrorString ("couldn't install checkers, unknown error");
                    else
                        err.SetErrorString (install_errors.GetString().c_str());
                    
                    return err;
                }
                
                process->SetDynamicCheckers(dynamic_checkers);
                
                if (log)
                    log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
            }
            
            IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str());
        
            if (!ir_dynamic_checks.runOnModule(*module))
            {
                err.SetErrorToGenericError();
                err.SetErrorString("Couldn't add dynamic checks to the expression");
                return err;
            }
        }
    }
    
    // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called 
    // below so we don't need to free it.
    RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager();
    
    std::string error_string;

    if (log)
    {
        std::string s;
        raw_string_ostream oss(s);
        
        module->print(oss, NULL);
        
        oss.flush();
        
        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
    }
    
    EngineBuilder builder(module);
    builder.setEngineKind(EngineKind::JIT)
        .setErrorStr(&error_string)
        .setRelocationModel(llvm::Reloc::PIC_)
        .setJITMemoryManager(jit_memory_manager)
        .setOptLevel(CodeGenOpt::Less)
        .setAllocateGVsWithCode(true)
        .setCodeModel(CodeModel::Small)
        .setUseMCJIT(true);
    execution_engine.reset(builder.create());
        
    if (!execution_engine.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
        return err;
    }
    
    execution_engine->DisableLazyCompilation();
    
    llvm::Function *function = module->getFunction (function_name.c_str());
    
    // We don't actually need the function pointer here, this just forces it to get resolved.
    
    void *fun_ptr = execution_engine->getPointerToFunction(function);
        
    // Errors usually cause failures in the JIT, but if we're lucky we get here.
    
    if (!function)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str());
        return err;
    }
    
    if (!fun_ptr)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str());
        return err;
    }
    
    m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
    

    Process *process = exe_ctx.GetProcessPtr();
    if (process == NULL)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
        return err;
    }
        
    jit_memory_manager->CommitAllocations(*process);
    jit_memory_manager->ReportAllocations(*execution_engine);
    jit_memory_manager->WriteData(*process);
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos != end; pos++)
    {
        (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr);
    
        if (!(*pos).m_name.compare(function_name.c_str()))
        {
            RecordingMemoryManager::AddrRange func_range = jit_memory_manager->GetRemoteRangeForLocal((*pos).m_local_addr);
            func_end = func_range.first + func_range.second;
            func_addr = (*pos).m_remote_addr;
        }
    }
    
    if (log)
    {
        log->Printf("Code can be run in the target.");
        
        StreamString disassembly_stream;
        
        Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager);
        
        if (!err.Success())
        {
            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
        }
        else
        {
            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
        }
    }
    
    execution_engine.reset();
    
    err.Clear();
    return err;
}
Example #11
0
void
IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
{
    error.Clear();
    
    AllocationMap::iterator iter = FindAllocation(process_address, size);
    
    if (iter == m_allocations.end())
    {
        lldb::ProcessSP process_sp = m_process_wp.lock();
        
        if (process_sp)
        {
            process_sp->WriteMemory(process_address, bytes, size, error);
            return;
        }
        
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist");
        return;
    }
    
    Allocation &allocation = iter->second;
    
    uint64_t offset = process_address - allocation.m_process_start;
    
    lldb::ProcessSP process_sp;

    switch (allocation.m_policy)
    {
    default:
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't write: invalid allocation policy");
        return;
    case eAllocationPolicyHostOnly:
        if (!allocation.m_data.GetByteSize())
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't write: data buffer is empty");
            return;
        }
        ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
        break;
    case eAllocationPolicyMirror:
        if (!allocation.m_data.GetByteSize())
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't write: data buffer is empty");
            return;
        }
        ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size);
        process_sp = m_process_wp.lock();
        if (process_sp)
        {
            process_sp->WriteMemory(process_address, bytes, size, error);
            if (!error.Success())
                return;
        }
        break;
    case eAllocationPolicyProcessOnly:
        process_sp = m_process_wp.lock();
        if (process_sp)
        {
            process_sp->WriteMemory(process_address, bytes, size, error);
            if (!error.Success())
                return;
        }
        break;
    }
    
    if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
    {        
        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,
                    (uint64_t)allocation.m_process_start,
                    (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
    }
}
Example #12
0
lldb::addr_t
IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
{
    lldb_private::Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    error.Clear();
    
    lldb::ProcessSP process_sp;
    lldb::addr_t    allocation_address  = LLDB_INVALID_ADDRESS;
    lldb::addr_t    aligned_address     = LLDB_INVALID_ADDRESS;

    size_t          alignment_mask = alignment - 1;
    size_t          allocation_size;

    if (size == 0)
        allocation_size = alignment;
    else
        allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size;
    
    switch (policy)
    {
    default:
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't malloc: invalid allocation policy");
        return LLDB_INVALID_ADDRESS;
    case eAllocationPolicyHostOnly:
        allocation_address = FindSpace(allocation_size);
        if (allocation_address == LLDB_INVALID_ADDRESS)
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't malloc: address space is full");
            return LLDB_INVALID_ADDRESS;
        }
        break;
    case eAllocationPolicyMirror:
        process_sp = m_process_wp.lock();
        if (log)
            log->Printf ("IRMemoryMap::%s process_sp=0x%" PRIx64 ", process_sp->CanJIT()=%s, process_sp->IsAlive()=%s", __FUNCTION__, (lldb::addr_t) process_sp.get (), process_sp && process_sp->CanJIT () ? "true" : "false", process_sp && process_sp->IsAlive () ? "true" : "false");
        if (process_sp && process_sp->CanJIT() && process_sp->IsAlive())
        {
            allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
            if (!error.Success())
                return LLDB_INVALID_ADDRESS;
        }
        else
        {
            if (log)
                log->Printf ("IRMemoryMap::%s switching to eAllocationPolicyHostOnly due to failed condition (see previous expr log message)", __FUNCTION__);
            policy = eAllocationPolicyHostOnly;
            allocation_address = FindSpace(allocation_size);
            if (allocation_address == LLDB_INVALID_ADDRESS)
            {
                error.SetErrorToGenericError();
                error.SetErrorString("Couldn't malloc: address space is full");
                return LLDB_INVALID_ADDRESS;
            }
        }
        break;
    case eAllocationPolicyProcessOnly:
        process_sp = m_process_wp.lock();
        if (process_sp)
        {
            if (process_sp->CanJIT() && process_sp->IsAlive())
            {
                allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error);
                if (!error.Success())
                    return LLDB_INVALID_ADDRESS;
            }
            else
            {
                error.SetErrorToGenericError();
                error.SetErrorString("Couldn't malloc: process doesn't support allocating memory");
                return LLDB_INVALID_ADDRESS;
            }
        }
        else
        {
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process");
            return LLDB_INVALID_ADDRESS;
        }
        break;
    }
    
    
    lldb::addr_t mask = alignment - 1;
    aligned_address = (allocation_address + mask) & (~mask);

    m_allocations[aligned_address] = Allocation(allocation_address,
                                                aligned_address,
                                                allocation_size,
                                                permissions,
                                                alignment,
                                                policy);
    
    if (log)
    {
        const char * policy_string;
        
        switch (policy)
        {
        default:
            policy_string = "<invalid policy>";
            break;
        case eAllocationPolicyHostOnly:
            policy_string = "eAllocationPolicyHostOnly";
            break;
        case eAllocationPolicyProcessOnly:
            policy_string = "eAllocationPolicyProcessOnly";
            break;
        case eAllocationPolicyMirror:
            policy_string = "eAllocationPolicyMirror";
            break;
        }
        
        log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64,
                    (uint64_t)allocation_size,
                    (uint64_t)alignment,
                    (uint64_t)permissions,
                    policy_string,
                    aligned_address);
    }
    
    return aligned_address;
}
Example #13
0
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, 
                                            lldb::addr_t &func_addr, 
                                            lldb::addr_t &func_end, 
                                            ExecutionContext &exe_ctx,
                                            IRForTarget::StaticDataAllocator *data_allocator,
                                            bool &evaluated_statically,
                                            lldb::ClangExpressionVariableSP &const_result,
                                            ExecutionPolicy execution_policy)
{
    func_allocation_addr = LLDB_INVALID_ADDRESS;
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;
    
    llvm::Module *module = m_code_generator->ReleaseModule();

    if (!module)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    // Find the actual name of the function (it's often mangled somehow)
    
    std::string function_name;
    
    if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
    }
    
    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
    
    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = &target->GetDebugger().GetErrorStream();
    
        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  execution_policy,
                                  const_result,
                                  data_allocator,
                                  error_stream,
                                  function_name.c_str());
        
        if (!ir_for_target.runOnModule(*module))
        {
            err.SetErrorToGenericError();
            err.SetErrorString("Couldn't prepare the expression for execution in the target");
            return err;
        }
        
        if (execution_policy != eExecutionPolicyAlways && ir_for_target.interpretSuccess())
        {
            evaluated_statically = true;
            err.Clear();
            return err;
        }
        
        Process *process = exe_ctx.GetProcessPtr();

        if (!process || execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorToGenericError();
            err.SetErrorString("Execution needed to run in the target, but the target can't be run");
            return err;
        }
        
        if (execution_policy != eExecutionPolicyNever &&
            m_expr.NeedsValidation() && 
            process)
        {
            if (!process->GetDynamicCheckers())
            {                
                DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
                
                StreamString install_errors;
                
                if (!dynamic_checkers->Install(install_errors, exe_ctx))
                {
                    if (install_errors.GetString().empty())
                        err.SetErrorString ("couldn't install checkers, unknown error");
                    else
                        err.SetErrorString (install_errors.GetString().c_str());
                    
                    return err;
                }
                
                process->SetDynamicCheckers(dynamic_checkers);
                
                if (log)
                    log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
            }
            
            IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str());
        
            if (!ir_dynamic_checks.runOnModule(*module))
            {
                err.SetErrorToGenericError();
                err.SetErrorString("Couldn't add dynamic checks to the expression");
                return err;
            }
        }
    }
    
    // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called 
    // below so we don't need to free it.
    RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager();
    
    std::string error_string;

    if (log)
    {
        std::string s;
        raw_string_ostream oss(s);
        
        module->print(oss, NULL);
        
        oss.flush();
        
        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
    }
    
#if defined (USE_STANDARD_JIT)
    m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, 
                                                               &error_string, 
                                                               jit_memory_manager,
                                                               CodeGenOpt::Less,
                                                               true,
                                                               Reloc::Default,
                                                               CodeModel::Small));
#else
    EngineBuilder builder(module);
    builder.setEngineKind(EngineKind::JIT)
        .setErrorStr(&error_string)
        .setRelocationModel(llvm::Reloc::PIC_)
        .setJITMemoryManager(jit_memory_manager)
        .setOptLevel(CodeGenOpt::Less)
        .setAllocateGVsWithCode(true)
        .setCodeModel(CodeModel::Small)
        .setUseMCJIT(true);
    m_execution_engine.reset(builder.create());
#endif
        
    if (!m_execution_engine.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
        return err;
    }
    
    m_execution_engine->DisableLazyCompilation();
    
    llvm::Function *function = module->getFunction (function_name.c_str());
    
    // We don't actually need the function pointer here, this just forces it to get resolved.
    
    void *fun_ptr = m_execution_engine->getPointerToFunction(function);
    
    // Errors usually cause failures in the JIT, but if we're lucky we get here.
    
    if (!function)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str());
        return err;
    }
    
    if (!fun_ptr)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str());
        return err;
    }
    
    m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
    

    Process *process = exe_ctx.GetProcessPtr();
    if (process == NULL)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
        return err;
    }
    
    // Look over the regions allocated for the function compiled.  The JIT
    // tries to allocate the functions & stubs close together, so we should try to
    // write them that way too...
    // For now I only write functions with no stubs, globals, exception tables,
    // etc.  So I only need to write the functions.
    
    size_t alloc_size = 0;
    
    std::map<uint8_t *, uint8_t *>::iterator fun_pos = jit_memory_manager->m_functions.begin();
    std::map<uint8_t *, uint8_t *>::iterator fun_end = jit_memory_manager->m_functions.end();

    for (; fun_pos != fun_end; ++fun_pos)
    {
        size_t mem_size = fun_pos->second - fun_pos->first;
        if (log)
            log->Printf ("JIT memory: [%p - %p) size = %zu", fun_pos->first, fun_pos->second, mem_size);
        alloc_size += mem_size;
    }
    
    Error alloc_error;
    func_allocation_addr = process->AllocateMemory (alloc_size, 
                                                                lldb::ePermissionsReadable|lldb::ePermissionsExecutable, 
                                                                alloc_error);
    
    if (func_allocation_addr == LLDB_INVALID_ADDRESS)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't allocate memory for the JITted function: %s", alloc_error.AsCString("unknown error"));
        return err;
    }
    
    lldb::addr_t cursor = func_allocation_addr;
        
    for (fun_pos = jit_memory_manager->m_functions.begin(); fun_pos != fun_end; fun_pos++)
    {
        lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first;
        lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second;
        size_t size = lend - lstart;
        
        Error write_error;
        
        if (process->WriteMemory(cursor, (void *) lstart, size, write_error) != size)
        {
            err.SetErrorToGenericError();
            err.SetErrorStringWithFormat("Couldn't copy JIT code for function into the target: %s", write_error.AsCString("unknown error"));
            return err;
        }
            
        jit_memory_manager->AddToLocalToRemoteMap (lstart, size, cursor);
        cursor += size;
    }
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos != end; pos++)
    {
        (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr);
    
        if (!(*pos).m_name.compare(function_name.c_str()))
        {
            func_end = jit_memory_manager->GetRemoteRangeForLocal ((*pos).m_local_addr).second;
            func_addr = (*pos).m_remote_addr;
        }
    }
    
    if (log)
    {
        log->Printf("Code can be run in the target.");
        
        StreamString disassembly_stream;
        
        Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager);
        
        if (!err.Success())
        {
            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
        }
        else
        {
            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
        }
    }
    
    err.Clear();
    return err;
}
Example #14
0
Error
ClangExpressionParser::MakeJIT (lldb::addr_t &func_allocation_addr, 
                                lldb::addr_t &func_addr, 
                                lldb::addr_t &func_end, 
                                ExecutionContext &exe_ctx,
                                lldb::ClangExpressionVariableSP *const_result)
{
    func_allocation_addr = LLDB_INVALID_ADDRESS;
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;
    
    llvm::Module *module = m_code_generator->ReleaseModule();

    if (!module)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    // Find the actual name of the function (it's often mangled somehow)
    
    std::string function_name;
    
    if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if(log)
            log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
    }
    
    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
    
    if (decl_map)
    {
        Stream *error_stream = NULL;
        
        if (exe_ctx.target)
            error_stream = &exe_ctx.target->GetDebugger().GetErrorStream();
    
        IRForTarget ir_for_target(decl_map, 
                                  m_expr.NeedsVariableResolution(),
                                  const_result,
                                  error_stream,
                                  function_name.c_str());
        
        if (!ir_for_target.runOnModule(*module))
        {
            err.SetErrorToGenericError();
            err.SetErrorString("Couldn't convert the expression to DWARF");
            return err;
        }
        
        if (m_expr.NeedsValidation() && exe_ctx.process->GetDynamicCheckers())
        {
            IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), function_name.c_str());
        
            if (!ir_dynamic_checks.runOnModule(*module))
            {
                err.SetErrorToGenericError();
                err.SetErrorString("Couldn't add dynamic checks to the expression");
                return err;
            }
        }
    }
    
    // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called 
    // below so we don't need to free it.
    RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager();
    
    std::string error_string;
        
    llvm::TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
    
    m_execution_engine.reset(llvm::ExecutionEngine::createJIT (module, 
                                                               &error_string, 
                                                               jit_memory_manager,
                                                               CodeGenOpt::Less,
                                                               true,
                                                               CodeModel::Small));
        
    if (!m_execution_engine.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
        return err;
    }
    
    m_execution_engine->DisableLazyCompilation();
    
    llvm::Function *function = module->getFunction (function_name.c_str());
    
    // We don't actually need the function pointer here, this just forces it to get resolved.
    
    void *fun_ptr = m_execution_engine->getPointerToFunction(function);
    
    // Errors usually cause failures in the JIT, but if we're lucky we get here.
    
    if (!fun_ptr)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't JIT the function");
        return err;
    }
    
    m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
    
    ExecutionContext &exc_context(exe_ctx);
    
    if (exc_context.process == NULL)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
        return err;
    }
    
    // Look over the regions allocated for the function compiled.  The JIT
    // tries to allocate the functions & stubs close together, so we should try to
    // write them that way too...
    // For now I only write functions with no stubs, globals, exception tables,
    // etc.  So I only need to write the functions.
    
    size_t alloc_size = 0;
    
    std::map<uint8_t *, uint8_t *>::iterator fun_pos = jit_memory_manager->m_functions.begin();
    std::map<uint8_t *, uint8_t *>::iterator fun_end = jit_memory_manager->m_functions.end();
    
    for (; fun_pos != fun_end; ++fun_pos)
        alloc_size += (*fun_pos).second - (*fun_pos).first;
    
    Error alloc_error;
    func_allocation_addr = exc_context.process->AllocateMemory (alloc_size, 
                                                                lldb::ePermissionsReadable|lldb::ePermissionsExecutable, 
                                                                alloc_error);
    
    if (func_allocation_addr == LLDB_INVALID_ADDRESS)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't allocate memory for the JITted function: %s", alloc_error.AsCString("unknown error"));
        return err;
    }
    
    lldb::addr_t cursor = func_allocation_addr;
        
    for (fun_pos = jit_memory_manager->m_functions.begin(); fun_pos != fun_end; fun_pos++)
    {
        lldb::addr_t lstart = (lldb::addr_t) (*fun_pos).first;
        lldb::addr_t lend = (lldb::addr_t) (*fun_pos).second;
        size_t size = lend - lstart;
        
        Error write_error;
        
        if (exc_context.process->WriteMemory(cursor, (void *) lstart, size, write_error) != size)
        {
            err.SetErrorToGenericError();
            err.SetErrorStringWithFormat("Couldn't copy JITted function into the target: %s", write_error.AsCString("unknown error"));
            return err;
        }
            
        jit_memory_manager->AddToLocalToRemoteMap (lstart, size, cursor);
        cursor += size;
    }
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos != end; pos++)
    {
        (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr);
    
        if (!(*pos).m_name.compare(function_name.c_str()))
        {
            func_end = jit_memory_manager->GetRemoteRangeForLocal ((*pos).m_local_addr).second;
            func_addr = (*pos).m_remote_addr;
        }
    }
    
    if (log)
    {
        log->Printf("Code can be run in the target.");
        
        StreamString disassembly_stream;
        
        Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager);
        
        if (!err.Success())
        {
            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
        }
        else
        {
            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
        }
    }
    
    err.Clear();
    return err;
}
Example #15
0
Error
PlatformKalimba::ResolveExecutable (const FileSpec &exe_file,
                                  const ArchSpec &exe_arch,
                                  lldb::ModuleSP &exe_module_sp,
                                  const FileSpecList *module_search_paths_ptr)
{
    Error error;
    char exe_path[PATH_MAX];
    FileSpec resolved_exe_file (exe_file);

    if (!resolved_exe_file.Exists())
    {
        exe_file.GetPath(exe_path, sizeof(exe_path));
        error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
    }

    if (error.Success())
    {
        ModuleSpec module_spec (resolved_exe_file, exe_arch);
        if (exe_arch.IsValid())
        {
            error = ModuleList::GetSharedModule (module_spec, 
                                                 exe_module_sp, 
                                                 NULL, 
                                                 NULL,
                                                 NULL);
            if (error.Fail())
            {
                // If we failed, it may be because the vendor and os aren't known. If that is the
                // case, try setting them to the host architecture and give it another try.
                llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); 
                bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
                bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
                if (!is_vendor_specified || !is_os_specified)
                {
                    const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple();

                    if (!is_vendor_specified)
                        module_triple.setVendorName (host_triple.getVendorName());
                    if (!is_os_specified)
                        module_triple.setOSName (host_triple.getOSName());

                    error = ModuleList::GetSharedModule (module_spec, 
                                                         exe_module_sp, 
                                                         NULL, 
                                                         NULL,
                                                         NULL);
                }
            }
        
            // TODO find out why exe_module_sp might be NULL            
            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
            {
                exe_module_sp.reset();
                error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
                                                exe_file.GetPath().c_str(),
                                                exe_arch.GetArchitectureName());
            }
        }
        else
        {
            // No valid architecture was specified, ask the platform for
            // the architectures that we should be using (in the correct order)
            // and see if we can find a match that way
            StreamString arch_names;
            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
            {
                error = ModuleList::GetSharedModule (module_spec, 
                                                     exe_module_sp, 
                                                     NULL, 
                                                     NULL,
                                                     NULL);
                // Did we find an executable using one of the 
                if (error.Success())
                {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }
                
                if (idx > 0)
                    arch_names.PutCString (", ");
                arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
            }
            
            if (error.Fail() || !exe_module_sp)
            {
                error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                exe_file.GetPath().c_str(),
                                                GetPluginName().GetCString(),
                                                arch_names.GetString().c_str());
            }
        }
    }

    return error;
}
void
IRExecutionUnit::GetRunnableInfo(Error &error,
                                 lldb::addr_t &func_addr,
                                 lldb::addr_t &func_end)
{
    lldb::ProcessSP process_sp(GetProcessWP().lock());

    static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);

    func_addr = LLDB_INVALID_ADDRESS;
    func_end = LLDB_INVALID_ADDRESS;

    if (!process_sp)
    {
        error.SetErrorToGenericError();
        error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
        return;
    }

    if (m_did_jit)
    {
        func_addr = m_function_load_addr;
        func_end = m_function_end_load_addr;

        return;
    };

    Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);

    m_did_jit = true;

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    std::string error_string;

    if (log)
    {
        std::string s;
        llvm::raw_string_ostream oss(s);

        m_module->print(oss, NULL);

        oss.flush();

        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
    }

    llvm::Triple triple(m_module->getTargetTriple());
    llvm::Function *function = m_module->getFunction (m_name.AsCString());
    llvm::Reloc::Model relocModel;
    llvm::CodeModel::Model codeModel;

    if (triple.isOSBinFormatELF())
    {
        relocModel = llvm::Reloc::Static;
        // This will be small for 32-bit and large for 64-bit.
        codeModel = llvm::CodeModel::JITDefault;
    }
    else
    {
        relocModel = llvm::Reloc::PIC_;
        codeModel = llvm::CodeModel::Small;
    }

    m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);

    llvm::EngineBuilder builder(std::move(m_module_ap));

    builder.setEngineKind(llvm::EngineKind::JIT)
    .setErrorStr(&error_string)
    .setRelocationModel(relocModel)
    .setMCJITMemoryManager(std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
    .setCodeModel(codeModel)
    .setOptLevel(llvm::CodeGenOpt::Less);

    llvm::StringRef mArch;
    llvm::StringRef mCPU;
    llvm::SmallVector<std::string, 0> mAttrs;

    for (std::string &feature : m_cpu_features)
        mAttrs.push_back(feature);

    llvm::TargetMachine *target_machine = builder.selectTarget(triple,
                                                               mArch,
                                                               mCPU,
                                                               mAttrs);

    m_execution_engine_ap.reset(builder.create(target_machine));

    if (!m_execution_engine_ap.get())
    {
        error.SetErrorToGenericError();
        error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
        return;
    }

    // Make sure we see all sections, including ones that don't have relocations...
    m_execution_engine_ap->setProcessAllSections(true);

    m_execution_engine_ap->DisableLazyCompilation();

    // We don't actually need the function pointer here, this just forces it to get resolved.

    void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);

    if (!error.Success())
    {
        // We got an error through our callback!
        return;
    }

    if (!function)
    {
        error.SetErrorToGenericError();
        error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
        return;
    }

    if (!fun_ptr)
    {
        error.SetErrorToGenericError();
        error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
        return;
    }

    m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));

    CommitAllocations(process_sp);
    ReportAllocations(*m_execution_engine_ap);
    WriteData(process_sp);

    for (JittedFunction &jitted_function : m_jitted_functions)
    {
        jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);

        if (!jitted_function.m_name.compare(m_name.AsCString()))
        {
            AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
            m_function_end_load_addr = func_range.first + func_range.second;
            m_function_load_addr = jitted_function.m_remote_addr;
        }
    }

    if (log)
    {
        log->Printf("Code can be run in the target.");

        StreamString disassembly_stream;

        Error err = DisassembleFunction(disassembly_stream, process_sp);

        if (!err.Success())
        {
            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
        }
        else
        {
            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
        }

        log->Printf("Sections: ");
        for (AllocationRecord &record : m_records)
        {
            if (record.m_process_address != LLDB_INVALID_ADDRESS)
            {
                record.dump(log);

                DataBufferHeap my_buffer(record.m_size, 0);
                Error err;
                ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);

                if (err.Success())
                {
                    DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
                    my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), record.m_process_address, 16, DataExtractor::TypeUInt8);
                }
            }
        }
    }

    func_addr = m_function_load_addr;
    func_end = m_function_end_load_addr;

    return;
}
Example #17
0
void
TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
        const char *index_value,
        const char *value,
        const ConstString &instance_name,
        const SettingEntry &entry,
        lldb::VarSetOperationType op,
        Error &err,
        bool pending)
{
    int new_enum = -1;

    if (var_name == GetSettingNameForExpressionPrefix ())
    {
        switch (op)
        {
        default:
            err.SetErrorToGenericError ();
            err.SetErrorString ("Unrecognized operation. Cannot update value.\n");
            return;
        case lldb::eVarSetOperationAssign:
        {
            FileSpec file_spec(value, true);

            if (!file_spec.Exists())
            {
                err.SetErrorToGenericError ();
                err.SetErrorStringWithFormat ("%s does not exist.\n", value);
                return;
            }

            DataBufferSP data_sp (file_spec.ReadFileContents());

            if (!data_sp && data_sp->GetByteSize() == 0)
            {
                err.SetErrorToGenericError ();
                err.SetErrorStringWithFormat ("Couldn't read from %s\n", value);
                return;
            }

            m_expr_prefix_path = value;
            m_expr_prefix_contents.assign(reinterpret_cast<const char *>(data_sp->GetBytes()), data_sp->GetByteSize());
        }
        return;
        case lldb::eVarSetOperationAppend:
            err.SetErrorToGenericError ();
            err.SetErrorString ("Cannot append to a path.\n");
            return;
        case lldb::eVarSetOperationClear:
            m_expr_prefix_path.clear ();
            m_expr_prefix_contents.clear ();
            return;
        }
    }
    else if (var_name == GetSettingNameForExecutionLevel ())
    {
        UserSettingsController::UpdateEnumVariable (entry.enum_values, &new_enum, value, err);
        if (err.Success())
            m_execution_level = (ExecutionLevel)new_enum;
    }
    else if (var_name == GetSettingNameForExecutionMode ())
    {
        UserSettingsController::UpdateEnumVariable (entry.enum_values, &new_enum, value, err);
        if (err.Success())
            m_execution_mode = (ExecutionMode)new_enum;
    }
    else if (var_name == GetSettingNameForExecutionOSType ())
    {
        UserSettingsController::UpdateEnumVariable (entry.enum_values, &new_enum, value, err);
        if (err.Success())
            m_execution_os_type = (ExecutionOSType)new_enum;
    }
}
Example #18
0
Error
ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, RecordingMemoryManager *jit_memory_manager)
{
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    
    const char *name = m_expr.FunctionName();
    
    Error ret;
    
    ret.Clear();
    
    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos < end; pos++)
    {
        if (strstr(pos->m_name.c_str(), name))
        {
            func_local_addr = pos->m_local_addr;
            func_remote_addr = pos->m_remote_addr;
        }
    }
    
    if (func_local_addr == LLDB_INVALID_ADDRESS)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name);
        return ret;
    }
    
    if(log)
        log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
    
    std::pair <lldb::addr_t, lldb::addr_t> func_range;
    
    func_range = jit_memory_manager->GetRemoteRangeForLocal(func_local_addr);
    
    if (func_range.first == 0 && func_range.second == 0)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name);
        return ret;
    }
    
    if(log)
        log->Printf("Function's code range is [0x%llx-0x%llx]", func_range.first, func_range.second);
    
    if (!exe_ctx.target)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the target");
    }
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second - func_remote_addr, 0));
    
    Error err;
    exe_ctx.process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
    
    if (!err.Success())
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
        return ret;
    }
    
    ArchSpec arch(exe_ctx.target->GetArchitecture());
    
    Disassembler *disassembler = Disassembler::FindPlugin(arch);
    
    if (disassembler == NULL)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
        return ret;
    }
    
    if (!exe_ctx.process)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the process");
        return ret;
    }
    
    DataExtractor extractor(buffer_sp, 
                            exe_ctx.process->GetByteOrder(),
                            exe_ctx.target->GetArchitecture().GetAddressByteSize());
    
    if (log)
    {
        log->Printf("Function data has contents:");
        extractor.PutToLog (log.get(),
                            0,
                            extractor.GetByteSize(),
                            func_remote_addr,
                            16,
                            DataExtractor::TypeUInt8);
    }
    
    disassembler->DecodeInstructions (Address (NULL, func_remote_addr), extractor, 0, UINT32_MAX);
    
    InstructionList &instruction_list = disassembler->GetInstructionList();
    
    uint32_t bytes_offset = 0;
    
    for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); 
         instruction_index < num_instructions; 
         ++instruction_index)
    {
        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
        instruction->Dump (&stream,
                           true,
                           &extractor, 
                           bytes_offset, 
                           &exe_ctx, 
                           true);
        stream.PutChar('\n');
        bytes_offset += instruction->GetByteSize();
    }
    
    return ret;
}
Example #19
0
void
IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error)
{
    error.Clear();
    
    if (size > 0)
    {
        AllocationMap::iterator iter = FindAllocation(process_address, size);
        
        if (iter == m_allocations.end())
        {
            error.SetErrorToGenericError();
            error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size);
            return;
        }
        
        Allocation &allocation = iter->second;
        
        switch (allocation.m_policy)
        {
        default:
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't get memory data: invalid allocation policy");
            return;
        case eAllocationPolicyProcessOnly:
            error.SetErrorToGenericError();
            error.SetErrorString("Couldn't get memory data: memory is only in the target");
            return;
        case eAllocationPolicyMirror:
            {
                lldb::ProcessSP process_sp = m_process_wp.lock();

                if (!allocation.m_data.GetByteSize())
                {
                    error.SetErrorToGenericError();
                    error.SetErrorString("Couldn't get memory data: data buffer is empty");
                    return;
                }
                if (process_sp)
                {
                    process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error);
                    if (!error.Success())
                        return;
                    uint64_t offset = process_address - allocation.m_process_start;
                    extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
                    return;
                }
            }
        case eAllocationPolicyHostOnly:
            if (!allocation.m_data.GetByteSize())
            {
                error.SetErrorToGenericError();
                error.SetErrorString("Couldn't get memory data: data buffer is empty");
                return;
            }
            uint64_t offset = process_address - allocation.m_process_start;
            extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize());
            return;
        }
    }
    else
    {
        error.SetErrorToGenericError();
        error.SetErrorString ("Couldn't get memory data: its size was zero");
        return;
    }
}
Example #20
0
Error PlatformFreeBSD::ResolveExecutable(
    const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
    const FileSpecList *module_search_paths_ptr) {
  Error error;
  // Nothing special to do here, just use the actual file and architecture

  char exe_path[PATH_MAX];
  ModuleSpec resolved_module_spec(module_spec);

  if (IsHost()) {
    // If we have "ls" as the module_spec's file, resolve the executable
    // location based on
    // the current path variables
    if (!resolved_module_spec.GetFileSpec().Exists()) {
      module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
      resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
    }

    if (!resolved_module_spec.GetFileSpec().Exists())
      resolved_module_spec.GetFileSpec().ResolveExecutableLocation();

    if (resolved_module_spec.GetFileSpec().Exists())
      error.Clear();
    else {
      error.SetErrorStringWithFormat(
          "unable to find executable for '%s'",
          resolved_module_spec.GetFileSpec().GetPath().c_str());
    }
  } else {
    if (m_remote_platform_sp) {
      error =
          GetCachedExecutable(resolved_module_spec, exe_module_sp,
                              module_search_paths_ptr, *m_remote_platform_sp);
    } else {
      // We may connect to a process and use the provided executable (Don't use
      // local $PATH).

      // Resolve any executable within a bundle on MacOSX
      Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());

      if (resolved_module_spec.GetFileSpec().Exists()) {
        error.Clear();
      } else {
        error.SetErrorStringWithFormat(
            "the platform is not currently connected, and '%s' doesn't exist "
            "in the system root.",
            resolved_module_spec.GetFileSpec().GetPath().c_str());
      }
    }
  }

  if (error.Success()) {
    if (resolved_module_spec.GetArchitecture().IsValid()) {
      error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                          module_search_paths_ptr, NULL, NULL);

      if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) {
        exe_module_sp.reset();
        error.SetErrorStringWithFormat(
            "'%s' doesn't contain the architecture %s",
            resolved_module_spec.GetFileSpec().GetPath().c_str(),
            resolved_module_spec.GetArchitecture().GetArchitectureName());
      }
    } else {
      // No valid architecture was specified, ask the platform for
      // the architectures that we should be using (in the correct order)
      // and see if we can find a match that way
      StreamString arch_names;
      for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
               idx, resolved_module_spec.GetArchitecture());
           ++idx) {
        error =
            ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
                                        module_search_paths_ptr, NULL, NULL);
        // Did we find an executable using one of the
        if (error.Success()) {
          if (exe_module_sp && exe_module_sp->GetObjectFile())
            break;
          else
            error.SetErrorToGenericError();
        }

        if (idx > 0)
          arch_names.PutCString(", ");
        arch_names.PutCString(
            resolved_module_spec.GetArchitecture().GetArchitectureName());
      }

      if (error.Fail() || !exe_module_sp) {
        if (resolved_module_spec.GetFileSpec().Readable()) {
          error.SetErrorStringWithFormat(
              "'%s' doesn't contain any '%s' platform architectures: %s",
              resolved_module_spec.GetFileSpec().GetPath().c_str(),
              GetPluginName().GetCString(), arch_names.GetData());
        } else {
          error.SetErrorStringWithFormat(
              "'%s' is not readable",
              resolved_module_spec.GetFileSpec().GetPath().c_str());
        }
      }
    }
  }

  return error;
}
Error
PlatformLinux::ResolveExecutable (const ModuleSpec &ms,
                                  lldb::ModuleSP &exe_module_sp,
                                  const FileSpecList *module_search_paths_ptr)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    char exe_path[PATH_MAX];
    ModuleSpec resolved_module_spec (ms);
    
    if (IsHost())
    {
        // If we have "ls" as the exe_file, resolve the executable location based on
        // the current path variables
        if (!resolved_module_spec.GetFileSpec().Exists())
        {
            resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
            resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
        }

        if (!resolved_module_spec.GetFileSpec().Exists())
            resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();

        if (resolved_module_spec.GetFileSpec().Exists())
            error.Clear();
        else
        {
            error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
        }
    }
    else
    {
        if (m_remote_platform_sp)
        {
            error = m_remote_platform_sp->ResolveExecutable (ms,
                                                             exe_module_sp,
                                                             NULL);
        }
        else
        {
            // We may connect to a process and use the provided executable (Don't use local $PATH).
            
            if (resolved_module_spec.GetFileSpec().Exists())
                error.Clear();
            else
                error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
        }
    }

    if (error.Success())
    {
        if (resolved_module_spec.GetArchitecture().IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp, 
                                                 NULL, 
                                                 NULL,
                                                 NULL);
            if (error.Fail())
            {
                // If we failed, it may be because the vendor and os aren't known. If that is the
                // case, try setting them to the host architecture and give it another try.
                llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple();
                bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);
                bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);
                if (!is_vendor_specified || !is_os_specified)
                {
                    const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();

                    if (!is_vendor_specified)
                        module_triple.setVendorName (host_triple.getVendorName());
                    if (!is_os_specified)
                        module_triple.setOSName (host_triple.getOSName());

                    error = ModuleList::GetSharedModule (resolved_module_spec,
                                                         exe_module_sp, 
                                                         NULL, 
                                                         NULL,
                                                         NULL);
                }
            }
        
            // TODO find out why exe_module_sp might be NULL            
            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
            {
                exe_module_sp.reset();
                error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
                                                resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                resolved_module_spec.GetArchitecture().GetArchitectureName());
            }
        }
        else
        {
            // No valid architecture was specified, ask the platform for
            // the architectures that we should be using (in the correct order)
            // and see if we can find a match that way
            StreamString arch_names;
            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
            {
                error = ModuleList::GetSharedModule (resolved_module_spec,
                                                     exe_module_sp, 
                                                     NULL, 
                                                     NULL,
                                                     NULL);
                // Did we find an executable using one of the 
                if (error.Success())
                {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }
                
                if (idx > 0)
                    arch_names.PutCString (", ");
                arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
            }
            
            if (error.Fail() || !exe_module_sp)
            {
                if (resolved_module_spec.GetFileSpec().Readable())
                {
                    error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                    resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                    GetPluginName().GetCString(),
                                                    arch_names.GetString().c_str());
                }
                else
                {
                    error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
                }
            }
        }
    }

    return error;
}
Error
IRExecutionUnit::DisassembleFunction (Stream &stream,
                                      lldb::ProcessSP &process_wp)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    ExecutionContext exe_ctx(process_wp);

    Error ret;

    ret.Clear();

    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;

    for (JittedFunction &function : m_jitted_functions)
    {
        if (strstr(function.m_name.c_str(), m_name.AsCString()))
        {
            func_local_addr = function.m_local_addr;
            func_remote_addr = function.m_remote_addr;
        }
    }

    if (func_local_addr == LLDB_INVALID_ADDRESS)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
        return ret;
    }

    if (log)
        log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);

    std::pair <lldb::addr_t, lldb::addr_t> func_range;

    func_range = GetRemoteRangeForLocal(func_local_addr);

    if (func_range.first == 0 && func_range.second == 0)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
        return ret;
    }

    if (log)
        log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);

    Target *target = exe_ctx.GetTargetPtr();
    if (!target)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the target");
        return ret;
    }

    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));

    Process *process = exe_ctx.GetProcessPtr();
    Error err;
    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);

    if (!err.Success())
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
        return ret;
    }

    ArchSpec arch(target->GetArchitecture());

    const char *plugin_name = NULL;
    const char *flavor_string = NULL;
    lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);

    if (!disassembler_sp)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
        return ret;
    }

    if (!process)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the process");
        return ret;
    }

    DataExtractor extractor(buffer_sp,
                            process->GetByteOrder(),
                            target->GetArchitecture().GetAddressByteSize());

    if (log)
    {
        log->Printf("Function data has contents:");
        extractor.PutToLog (log,
                            0,
                            extractor.GetByteSize(),
                            func_remote_addr,
                            16,
                            DataExtractor::TypeUInt8);
    }

    disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);

    InstructionList &instruction_list = disassembler_sp->GetInstructionList();
    const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
    const char *disassemble_format = "${addr-file-or-load}: ";
    if (exe_ctx.HasTargetScope())
    {
        disassemble_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
    }

    for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
         instruction_index < num_instructions;
         ++instruction_index)
    {
        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
        instruction->Dump (&stream,
                           max_opcode_byte_size,
                           true,
                           true,
                           &exe_ctx,
                           NULL,
                           NULL,
                           disassemble_format);
        stream.PutChar('\n');
    }
    // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
    // I'll fix that but for now, just clear the list and it will go away nicely.
    disassembler_sp->GetInstructionList().Clear();
    return ret;
}
Example #23
0
Error
PlatformLinux::ResolveExecutable (const FileSpec &exe_file,
                                  const ArchSpec &exe_arch,
                                  lldb::ModuleSP &exe_module_sp,
                                  const FileSpecList *module_search_paths_ptr)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    char exe_path[PATH_MAX];
    FileSpec resolved_exe_file (exe_file);
    
    if (IsHost())
    {
        // If we have "ls" as the exe_file, resolve the executable location based on
        // the current path variables
        if (!resolved_exe_file.Exists())
        {
            exe_file.GetPath(exe_path, sizeof(exe_path));
            resolved_exe_file.SetFile(exe_path, true);
        }

        if (!resolved_exe_file.Exists())
            resolved_exe_file.ResolveExecutableLocation ();

        if (resolved_exe_file.Exists())
            error.Clear();
        else
        {
            exe_file.GetPath(exe_path, sizeof(exe_path));
            error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path);
        }
    }
    else
    {
        if (m_remote_platform_sp)
        {
            error = m_remote_platform_sp->ResolveExecutable (exe_file,
                                                             exe_arch,
                                                             exe_module_sp,
                                                             NULL);
        }
        else
        {
            // We may connect to a process and use the provided executable (Don't use local $PATH).
            
            if (resolved_exe_file.Exists())
                error.Clear();
            else
                error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path);
        }
    }

    if (error.Success())
    {
        ModuleSpec module_spec (resolved_exe_file, exe_arch);
        if (exe_arch.IsValid())
        {
            error = ModuleList::GetSharedModule (module_spec, 
                                                 exe_module_sp, 
                                                 NULL, 
                                                 NULL,
                                                 NULL);
        
            // TODO find out why exe_module_sp might be NULL            
            if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
            {
                exe_module_sp.reset();
                error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s",
                                                exe_file.GetDirectory().AsCString(""),
                                                exe_file.GetDirectory() ? "/" : "",
                                                exe_file.GetFilename().AsCString(""),
                                                exe_arch.GetArchitectureName());
            }
        }
        else
        {
            // No valid architecture was specified, ask the platform for
            // the architectures that we should be using (in the correct order)
            // and see if we can find a match that way
            StreamString arch_names;
            for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
            {
                error = ModuleList::GetSharedModule (module_spec, 
                                                     exe_module_sp, 
                                                     NULL, 
                                                     NULL,
                                                     NULL);
                // Did we find an executable using one of the 
                if (error.Success())
                {
                    if (exe_module_sp && exe_module_sp->GetObjectFile())
                        break;
                    else
                        error.SetErrorToGenericError();
                }
                
                if (idx > 0)
                    arch_names.PutCString (", ");
                arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
            }
            
            if (error.Fail() || !exe_module_sp)
            {
                error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
                                                exe_file.GetDirectory().AsCString(""),
                                                exe_file.GetDirectory() ? "/" : "",
                                                exe_file.GetFilename().AsCString(""),
                                                GetShortPluginName(),
                                                arch_names.GetString().c_str());
            }
        }
    }

    return error;
}
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
                                            lldb::addr_t &func_end,
                                            std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
                                            ExecutionContext &exe_ctx,
                                            bool &can_interpret,
                                            ExecutionPolicy execution_policy)
{
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;

    std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());

    if (!llvm_module_ap.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }

    // Find the actual name of the function (it's often mangled somehow)

    ConstString function_name;

    if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
    }

    execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                 llvm_module_ap, // handed off here
                                                 function_name,
                                                 exe_ctx.GetTargetSP(),
                                                 m_compiler->getTargetOpts().Features));

    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL

    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = target->GetDebugger().GetErrorFile().get();

        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  *execution_unit_sp,
                                  error_stream,
                                  function_name.AsCString());

        bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());

        Error interpret_error;

        can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error);

        Process *process = exe_ctx.GetProcessPtr();

        if (!ir_can_run)
        {
            err.SetErrorString("The expression could not be prepared to run in the target");
            return err;
        }

        if (!can_interpret && execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyAlways)
        {
            err.SetErrorString("Expression needed to run in the target, but the target can't be run");
            return err;
        }

        if (execution_policy == eExecutionPolicyAlways || !can_interpret)
        {
            if (m_expr.NeedsValidation() && process)
            {
                if (!process->GetDynamicCheckers())
                {
                    DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();

                    StreamString install_errors;

                    if (!dynamic_checkers->Install(install_errors, exe_ctx))
                    {
                        if (install_errors.GetString().empty())
                            err.SetErrorString ("couldn't install checkers, unknown error");
                        else
                            err.SetErrorString (install_errors.GetString().c_str());

                        return err;
                    }

                    process->SetDynamicCheckers(dynamic_checkers);

                    if (log)
                        log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
                }

                IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());

                if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
                {
                    err.SetErrorToGenericError();
                    err.SetErrorString("Couldn't add dynamic checks to the expression");
                    return err;
                }
            }

            execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
        }
    }
    else
    {
        execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
    }

    return err;
}
Example #25
0
Error
PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
                                      const ArchSpec &exe_arch,
                                      lldb::ModuleSP &exe_module_sp)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    FileSpec resolved_exe_file (exe_file);
    
    // If we have "ls" as the exe_file, resolve the executable loation based on
    // the current path variables
    // TODO: resolve bare executables in the Platform SDK
//    if (!resolved_exe_file.Exists())
//        resolved_exe_file.ResolveExecutableLocation ();

    // Resolve any executable within a bundle on MacOSX
    // TODO: verify that this handles shallow bundles, if not then implement one ourselves
    Host::ResolveExecutableInBundle (resolved_exe_file);

    if (resolved_exe_file.Exists())
    {
        if (exe_arch.IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_exe_file, 
                                                 exe_arch, 
                                                 NULL,
                                                 NULL, 
                                                 0, 
                                                 exe_module_sp, 
                                                 NULL, 
                                                 NULL);
        
            if (exe_module_sp->GetObjectFile())
                return error;
            exe_module_sp.reset();
        }
        // No valid architecture was specified or the exact ARM slice wasn't
        // found so ask the platform for the architectures that we should be
        // using (in the correct order) and see if we can find a match that way
        StreamString arch_names;
        ArchSpec platform_arch;
        for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx)
        {
            error = ModuleList::GetSharedModule (resolved_exe_file, 
                                                 platform_arch, 
                                                 NULL,
                                                 NULL, 
                                                 0, 
                                                 exe_module_sp, 
                                                 NULL, 
                                                 NULL);
            // Did we find an executable using one of the 
            if (error.Success())
            {
                if (exe_module_sp && exe_module_sp->GetObjectFile())
                    break;
                else
                    error.SetErrorToGenericError();
            }
            
            if (idx > 0)
                arch_names.PutCString (", ");
            arch_names.PutCString (platform_arch.GetArchitectureName());
        }
        
        if (error.Fail() || !exe_module_sp)
        {
            error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s",
                                            exe_file.GetDirectory().AsCString(""),
                                            exe_file.GetDirectory() ? "/" : "",
                                            exe_file.GetFilename().AsCString(""),
                                            GetShortPluginName(),
                                            arch_names.GetString().c_str());
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("'%s%s%s' does not exist",
                                        exe_file.GetDirectory().AsCString(""),
                                        exe_file.GetDirectory() ? "/" : "",
                                        exe_file.GetFilename().AsCString(""));
    }

    return error;
}
Error
PlatformRemoteiOS::ResolveExecutable (const ModuleSpec &ms,
                                      lldb::ModuleSP &exe_module_sp,
                                      const FileSpecList *module_search_paths_ptr)
{
    Error error;
    // Nothing special to do here, just use the actual file and architecture

    ModuleSpec resolved_module_spec(ms);

    // Resolve any executable within a bundle on MacOSX
    // TODO: verify that this handles shallow bundles, if not then implement one ourselves
    Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());

    if (resolved_module_spec.GetFileSpec().Exists())
    {
        if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid())
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp, 
                                                 NULL,
                                                 NULL, 
                                                 NULL);

            if (exe_module_sp && exe_module_sp->GetObjectFile())
                return error;
            exe_module_sp.reset();
        }
        // No valid architecture was specified or the exact ARM slice wasn't
        // found so ask the platform for the architectures that we should be
        // using (in the correct order) and see if we can find a match that way
        StreamString arch_names;
        for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
        {
            error = ModuleList::GetSharedModule (resolved_module_spec,
                                                 exe_module_sp, 
                                                 NULL,
                                                 NULL, 
                                                 NULL);
            // Did we find an executable using one of the 
            if (error.Success())
            {
                if (exe_module_sp && exe_module_sp->GetObjectFile())
                    break;
                else
                    error.SetErrorToGenericError();
            }
            
            if (idx > 0)
                arch_names.PutCString (", ");
            arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
        }
        
        if (error.Fail() || !exe_module_sp)
        {
            if (resolved_module_spec.GetFileSpec().Readable())
            {
                error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
                                                resolved_module_spec.GetFileSpec().GetPath().c_str(),
                                                GetPluginName().GetCString(),
                                                arch_names.GetString().c_str());
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
            }
        }
    }
    else
    {
        error.SetErrorStringWithFormat ("'%s' does not exist",
                                        resolved_module_spec.GetFileSpec().GetPath().c_str());
    }

    return error;
}
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
                                            lldb::addr_t &func_end,
                                            lldb::IRExecutionUnitSP &execution_unit_sp,
                                            ExecutionContext &exe_ctx,
                                            bool &can_interpret,
                                            ExecutionPolicy execution_policy)
{
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;

    std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());

    if (!llvm_module_ap.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    for (llvm::Function &function : *llvm_module_ap.get()) {
        llvm::AttributeSet attributes = function.getAttributes();
        llvm::AttrBuilder attributes_to_remove;
        
        attributes_to_remove.addAttribute("target-cpu");
        
        function.setAttributes(attributes.removeAttributes(function.getContext(), llvm::AttributeSet::FunctionIndex, llvm::AttributeSet::get(function.getContext(), llvm::AttributeSet::FunctionIndex, attributes_to_remove)));
    }

    ConstString function_name;

    if (execution_policy != eExecutionPolicyTopLevel)
    {
        // Find the actual name of the function (it's often mangled somehow)

        if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
        {
            err.SetErrorToGenericError();
            err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
            return err;
        }
        else
        {
            if (log)
                log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
        }
    }

    SymbolContext sc;

    if (lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP())
    {
        sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything);
    }
    else if (lldb::TargetSP target_sp = exe_ctx.GetTargetSP())
    {
        sc.target_sp = target_sp;
    }

    execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                 llvm_module_ap, // handed off here
                                                 function_name,
                                                 exe_ctx.GetTargetSP(),
                                                 sc,
                                                 m_compiler->getTargetOpts().Features));

    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
    ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL

    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = target->GetDebugger().GetErrorFile().get();

        IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), *execution_unit_sp, error_stream,
                                  function_name.AsCString());

        bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());

        Process *process = exe_ctx.GetProcessPtr();

        if (execution_policy != eExecutionPolicyAlways && execution_policy != eExecutionPolicyTopLevel)
        {
            Error interpret_error;

            bool interpret_function_calls = !process ? false : process->CanInterpretFunctionCalls();
            can_interpret =
                IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(),
                                            interpret_error, interpret_function_calls);

            if (!can_interpret && execution_policy == eExecutionPolicyNever)
            {
                err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
                return err;
            }
        }

        if (!ir_can_run)
        {
            err.SetErrorString("The expression could not be prepared to run in the target");
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyAlways)
        {
            err.SetErrorString("Expression needed to run in the target, but the target can't be run");
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyTopLevel)
        {
            err.SetErrorString(
                "Top-level code needs to be inserted into a runnable target, but the target can't be run");
            return err;
        }

        if (execution_policy == eExecutionPolicyAlways ||
            (execution_policy != eExecutionPolicyTopLevel && !can_interpret))
        {
            if (m_expr.NeedsValidation() && process)
            {
                if (!process->GetDynamicCheckers())
                {
                    DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();

                    DiagnosticManager install_diagnostics;

                    if (!dynamic_checkers->Install(install_diagnostics, exe_ctx))
                    {
                        if (install_diagnostics.Diagnostics().size())
                            err.SetErrorString("couldn't install checkers, unknown error");
                        else
                            err.SetErrorString(install_diagnostics.GetString().c_str());

                        return err;
                    }

                    process->SetDynamicCheckers(dynamic_checkers);

                    if (log)
                        log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
                }

                IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());

                if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
                {
                    err.SetErrorToGenericError();
                    err.SetErrorString("Couldn't add dynamic checks to the expression");
                    return err;
                }
            }
        }

        if (execution_policy == eExecutionPolicyAlways || execution_policy == eExecutionPolicyTopLevel ||
            !can_interpret)
        {
            execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
        }
    }
    else
    {
        execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
    }

    return err;
}