//===-- Target.h ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Target_h_
#define liblldb_Target_h_

// C Includes
// C++ Includes
#include <list>

// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
#include "lldb/Breakpoint/BreakpointList.h"
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
#include "lldb/Breakpoint/WatchpointList.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Expression/ClangPersistentVariables.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Interpreter/OptionValueEnumeration.h"
#include "lldb/Interpreter/OptionValueFileSpec.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/PathMappingList.h"
#include "lldb/Target/SectionLoadList.h"

namespace lldb_private {

extern OptionEnumValueElement g_dynamic_value_types[];

typedef enum InlineStrategy
{
    eInlineBreakpointsNever = 0,
    eInlineBreakpointsHeaders,
    eInlineBreakpointsAlways
} InlineStrategy;
    
typedef enum LoadScriptFromSymFile
{
    eLoadScriptFromSymFileTrue,
    eLoadScriptFromSymFileFalse,
    eLoadScriptFromSymFileWarn
} LoadScriptFromSymFile;
    
//----------------------------------------------------------------------
// TargetProperties
//----------------------------------------------------------------------
class TargetProperties : public Properties
{
public:
    TargetProperties(Target *target);

    virtual
    ~TargetProperties();
    
    ArchSpec
    GetDefaultArchitecture () const;
    
    void
    SetDefaultArchitecture (const ArchSpec& arch);

    lldb::DynamicValueType
    GetPreferDynamicValue() const;
    
    bool
    GetDisableASLR () const;
    
    void
    SetDisableASLR (bool b);
    
    bool
    GetDisableSTDIO () const;
    
    void
    SetDisableSTDIO (bool b);
    
    const char *
    GetDisassemblyFlavor() const;

//    void
//    SetDisassemblyFlavor(const char *flavor);
    
    InlineStrategy
    GetInlineStrategy () const;

    const char *
    GetArg0 () const;
    
    void
    SetArg0 (const char *arg);

    bool
    GetRunArguments (Args &args) const;
    
    void
    SetRunArguments (const Args &args);
    
    size_t
    GetEnvironmentAsArgs (Args &env) const;
    
    bool
    GetSkipPrologue() const;
    
    PathMappingList &
    GetSourcePathMap () const;
    
    FileSpecList &
    GetExecutableSearchPaths ();
    
    bool
    GetEnableSyntheticValue () const;
    
    uint32_t
    GetMaximumNumberOfChildrenToDisplay() const;
    
    uint32_t
    GetMaximumSizeOfStringSummary() const;

    uint32_t
    GetMaximumMemReadSize () const;
    
    FileSpec
    GetStandardInputPath () const;
    
    void
    SetStandardInputPath (const char *path);
    
    FileSpec
    GetStandardOutputPath () const;
    
    void
    SetStandardOutputPath (const char *path);
    
    FileSpec
    GetStandardErrorPath () const;
    
    void
    SetStandardErrorPath (const char *path);
    
    bool
    GetBreakpointsConsultPlatformAvoidList ();
    
    const char *
    GetExpressionPrefixContentsAsCString ();
    
    bool
    GetUseFastStepping() const;
    
    LoadScriptFromSymFile
    GetLoadScriptFromSymbolFile() const;
    
};

typedef std::shared_ptr<TargetProperties> TargetPropertiesSP;

class EvaluateExpressionOptions
{
public:
    static const uint32_t default_timeout = 500000;
    EvaluateExpressionOptions() :
        m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
        m_coerce_to_id(false),
        m_unwind_on_error(true),
        m_ignore_breakpoints (false),
        m_keep_in_memory(false),
        m_run_others(true),
        m_use_dynamic(lldb::eNoDynamicValues),
        m_timeout_usec(default_timeout)
    {}
    
    ExecutionPolicy
    GetExecutionPolicy () const
    {
        return m_execution_policy;
    }
    
    EvaluateExpressionOptions&
    SetExecutionPolicy (ExecutionPolicy policy = eExecutionPolicyAlways)
    {
        m_execution_policy = policy;
        return *this;
    }
    
    bool
    DoesCoerceToId () const
    {
        return m_coerce_to_id;
    }
    
    EvaluateExpressionOptions&
    SetCoerceToId (bool coerce = true)
    {
        m_coerce_to_id = coerce;
        return *this;
    }
    
    bool
    DoesUnwindOnError () const
    {
        return m_unwind_on_error;
    }
    
    EvaluateExpressionOptions&
    SetUnwindOnError (bool unwind = false)
    {
        m_unwind_on_error = unwind;
        return *this;
    }
    
    bool
    DoesIgnoreBreakpoints () const
    {
        return m_ignore_breakpoints;
    }
    
    EvaluateExpressionOptions&
    SetIgnoreBreakpoints (bool ignore = false)
    {
        m_ignore_breakpoints = ignore;
        return *this;
    }
    
    bool
    DoesKeepInMemory () const
    {
        return m_keep_in_memory;
    }
    
    EvaluateExpressionOptions&
    SetKeepInMemory (bool keep = true)
    {
        m_keep_in_memory = keep;
        return *this;
    }
    
    lldb::DynamicValueType
    GetUseDynamic () const
    {
        return m_use_dynamic;
    }
    
    EvaluateExpressionOptions&
    SetUseDynamic (lldb::DynamicValueType dynamic = lldb::eDynamicCanRunTarget)
    {
        m_use_dynamic = dynamic;
        return *this;
    }
    
    uint32_t
    GetTimeoutUsec () const
    {
        return m_timeout_usec;
    }
    
    EvaluateExpressionOptions&
    SetTimeoutUsec (uint32_t timeout = 0)
    {
        m_timeout_usec = timeout;
        return *this;
    }
    
    bool
    GetRunOthers () const
    {
        return m_run_others;
    }
    
    EvaluateExpressionOptions&
    SetRunOthers (bool run_others = true)
    {
        m_run_others = run_others;
        return *this;
    }
    
private:
    ExecutionPolicy m_execution_policy;
    bool m_coerce_to_id;
    bool m_unwind_on_error;
    bool m_ignore_breakpoints;
    bool m_keep_in_memory;
    bool m_run_others;
    lldb::DynamicValueType m_use_dynamic;
    uint32_t m_timeout_usec;
};

//----------------------------------------------------------------------
// Target
//----------------------------------------------------------------------
class Target :
    public std::enable_shared_from_this<Target>,
    public TargetProperties,
    public Broadcaster,
    public ExecutionContextScope,
    public ModuleList::Notifier
{
public:
    friend class TargetList;

    //------------------------------------------------------------------
    /// Broadcaster event bits definitions.
    //------------------------------------------------------------------
    enum
    {
        eBroadcastBitBreakpointChanged  = (1 << 0),
        eBroadcastBitModulesLoaded      = (1 << 1),
        eBroadcastBitModulesUnloaded    = (1 << 2),
        eBroadcastBitWatchpointChanged  = (1 << 3),
        eBroadcastBitSymbolsLoaded      = (1 << 4)
    };
    
    // These two functions fill out the Broadcaster interface:
    
    static ConstString &GetStaticBroadcasterClass ();

    virtual ConstString &GetBroadcasterClass() const
    {
        return GetStaticBroadcasterClass();
    }

    // This event data class is for use by the TargetList to broadcast new target notifications.
    class TargetEventData : public EventData
    {
    public:

        static const ConstString &
        GetFlavorString ();

        virtual const ConstString &
        GetFlavor () const;

        TargetEventData (const lldb::TargetSP &new_target_sp);
        
        lldb::TargetSP &
        GetTarget()
        {
            return m_target_sp;
        }

        virtual
        ~TargetEventData();
        
        virtual void
        Dump (Stream *s) const;

        static const lldb::TargetSP
        GetTargetFromEvent (const lldb::EventSP &event_sp);
        
        static const TargetEventData *
        GetEventDataFromEvent (const Event *event_sp);

    private:
        lldb::TargetSP m_target_sp;

        DISALLOW_COPY_AND_ASSIGN (TargetEventData);
    };
    
    static void
    SettingsInitialize ();

    static void
    SettingsTerminate ();

//    static lldb::UserSettingsControllerSP &
//    GetSettingsController ();

    static FileSpecList
    GetDefaultExecutableSearchPaths ();

    static ArchSpec
    GetDefaultArchitecture ();

    static void
    SetDefaultArchitecture (const ArchSpec &arch);

//    void
//    UpdateInstanceName ();

    lldb::ModuleSP
    GetSharedModule (const ModuleSpec &module_spec,
                     Error *error_ptr = NULL);

    //----------------------------------------------------------------------
    // Settings accessors
    //----------------------------------------------------------------------

    static const TargetPropertiesSP &
    GetGlobalProperties();


private:
    //------------------------------------------------------------------
    /// Construct with optional file and arch.
    ///
    /// This member is private. Clients must use
    /// TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
    /// so all targets can be tracked from the central target list.
    ///
    /// @see TargetList::CreateTarget(const FileSpec*, const ArchSpec*)
    //------------------------------------------------------------------
    Target (Debugger &debugger,
            const ArchSpec &target_arch,
            const lldb::PlatformSP &platform_sp);

    // Helper function.
    bool
    ProcessIsValid ();

public:
    ~Target();

    Mutex &
    GetAPIMutex ()
    {
        return m_mutex;
    }

    void
    DeleteCurrentProcess ();

    void
    CleanupProcess ();
    //------------------------------------------------------------------
    /// Dump a description of this object to a Stream.
    ///
    /// Dump a description of the contents of this object to the
    /// supplied stream \a s. The dumped content will be only what has
    /// been loaded or parsed up to this point at which this function
    /// is called, so this is a good way to see what has been parsed
    /// in a target.
    ///
    /// @param[in] s
    ///     The stream to which to dump the object descripton.
    //------------------------------------------------------------------
    void
    Dump (Stream *s, lldb::DescriptionLevel description_level);

    const lldb::ProcessSP &
    CreateProcess (Listener &listener, 
                   const char *plugin_name,
                   const FileSpec *crash_file);

    const lldb::ProcessSP &
    GetProcessSP () const;

    bool
    IsValid()
    {
        return m_valid;
    }

    void
    Destroy();

    //------------------------------------------------------------------
    // This part handles the breakpoints.
    //------------------------------------------------------------------

    BreakpointList &
    GetBreakpointList(bool internal = false);

    const BreakpointList &
    GetBreakpointList(bool internal = false) const;
    
    lldb::BreakpointSP
    GetLastCreatedBreakpoint ()
    {
        return m_last_created_breakpoint;
    }

    lldb::BreakpointSP
    GetBreakpointByID (lldb::break_id_t break_id);

    // Use this to create a file and line breakpoint to a given module or all module it is NULL
    lldb::BreakpointSP
    CreateBreakpoint (const FileSpecList *containingModules,
                      const FileSpec &file,
                      uint32_t line_no,
                      LazyBool check_inlines = eLazyBoolCalculate,
                      LazyBool skip_prologue = eLazyBoolCalculate,
                      bool internal = false);

    // Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
    lldb::BreakpointSP
    CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
                                 const FileSpecList *source_file_list,
                                 RegularExpression &source_regex,
                                 bool internal = false);

    // Use this to create a breakpoint from a load address
    lldb::BreakpointSP
    CreateBreakpoint (lldb::addr_t load_addr,
                      bool internal = false);

    // Use this to create Address breakpoints:
    lldb::BreakpointSP
    CreateBreakpoint (Address &addr,
                      bool internal = false);

    // Use this to create a function breakpoint by regexp in containingModule/containingSourceFiles, or all modules if it is NULL
    // When "skip_prologue is set to eLazyBoolCalculate, we use the current target 
    // setting, else we use the values passed in
    lldb::BreakpointSP
    CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
                               const FileSpecList *containingSourceFiles,
                               RegularExpression &func_regexp,
                               LazyBool skip_prologue = eLazyBoolCalculate,
                               bool internal = false);

    // Use this to create a function breakpoint by name in containingModule, or all modules if it is NULL
    // When "skip_prologue is set to eLazyBoolCalculate, we use the current target 
    // setting, else we use the values passed in
    lldb::BreakpointSP
    CreateBreakpoint (const FileSpecList *containingModules,
                      const FileSpecList *containingSourceFiles,
                      const char *func_name,
                      uint32_t func_name_type_mask, 
                      LazyBool skip_prologue = eLazyBoolCalculate,
                      bool internal = false);
                      
    lldb::BreakpointSP
    CreateExceptionBreakpoint (enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal = false);
    
    // This is the same as the func_name breakpoint except that you can specify a vector of names.  This is cheaper
    // than a regular expression breakpoint in the case where you just want to set a breakpoint on a set of names
    // you already know.
    lldb::BreakpointSP
    CreateBreakpoint (const FileSpecList *containingModules,
                      const FileSpecList *containingSourceFiles,
                      const char *func_names[],
                      size_t num_names, 
                      uint32_t func_name_type_mask, 
                      LazyBool skip_prologue = eLazyBoolCalculate,
                      bool internal = false);

    lldb::BreakpointSP
    CreateBreakpoint (const FileSpecList *containingModules,
                      const FileSpecList *containingSourceFiles,
                      const std::vector<std::string> &func_names,
                      uint32_t func_name_type_mask,
                      LazyBool skip_prologue = eLazyBoolCalculate,
                      bool internal = false);


    // Use this to create a general breakpoint:
    lldb::BreakpointSP
    CreateBreakpoint (lldb::SearchFilterSP &filter_sp,
                      lldb::BreakpointResolverSP &resolver_sp,
                      bool internal = false);

    // Use this to create a watchpoint:
    lldb::WatchpointSP
    CreateWatchpoint (lldb::addr_t addr,
                      size_t size,
                      const ClangASTType *type,
                      uint32_t kind,
                      Error &error);

    lldb::WatchpointSP
    GetLastCreatedWatchpoint ()
    {
        return m_last_created_watchpoint;
    }

    WatchpointList &
    GetWatchpointList()
    {
        return m_watchpoint_list;
    }

    void
    RemoveAllBreakpoints (bool internal_also = false);

    void
    DisableAllBreakpoints (bool internal_also = false);

    void
    EnableAllBreakpoints (bool internal_also = false);

    bool
    DisableBreakpointByID (lldb::break_id_t break_id);

    bool
    EnableBreakpointByID (lldb::break_id_t break_id);

    bool
    RemoveBreakpointByID (lldb::break_id_t break_id);

    // The flag 'end_to_end', default to true, signifies that the operation is
    // performed end to end, for both the debugger and the debuggee.

    bool
    RemoveAllWatchpoints (bool end_to_end = true);

    bool
    DisableAllWatchpoints (bool end_to_end = true);

    bool
    EnableAllWatchpoints (bool end_to_end = true);

    bool
    ClearAllWatchpointHitCounts ();

    bool
    IgnoreAllWatchpoints (uint32_t ignore_count);

    bool
    DisableWatchpointByID (lldb::watch_id_t watch_id);

    bool
    EnableWatchpointByID (lldb::watch_id_t watch_id);

    bool
    RemoveWatchpointByID (lldb::watch_id_t watch_id);

    bool
    IgnoreWatchpointByID (lldb::watch_id_t watch_id, uint32_t ignore_count);

    //------------------------------------------------------------------
    /// Get \a load_addr as a callable code load address for this target
    ///
    /// Take \a load_addr and potentially add any address bits that are 
    /// needed to make the address callable. For ARM this can set bit
    /// zero (if it already isn't) if \a load_addr is a thumb function.
    /// If \a addr_class is set to eAddressClassInvalid, then the address
    /// adjustment will always happen. If it is set to an address class
    /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be 
    /// returned.
    //------------------------------------------------------------------
    lldb::addr_t
    GetCallableLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;

    //------------------------------------------------------------------
    /// Get \a load_addr as an opcode for this target.
    ///
    /// Take \a load_addr and potentially strip any address bits that are 
    /// needed to make the address point to an opcode. For ARM this can 
    /// clear bit zero (if it already isn't) if \a load_addr is a 
    /// thumb function and load_addr is in code.
    /// If \a addr_class is set to eAddressClassInvalid, then the address
    /// adjustment will always happen. If it is set to an address class
    /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be 
    /// returned.
    //------------------------------------------------------------------
    lldb::addr_t
    GetOpcodeLoadAddress (lldb::addr_t load_addr, lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;

protected:
    //------------------------------------------------------------------
    /// Implementing of ModuleList::Notifier.
    //------------------------------------------------------------------
    
    virtual void
    ModuleAdded (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
    
    virtual void
    ModuleRemoved (const ModuleList& module_list, const lldb::ModuleSP& module_sp);
    
    virtual void
    ModuleUpdated (const ModuleList& module_list,
                   const lldb::ModuleSP& old_module_sp,
                   const lldb::ModuleSP& new_module_sp);
    virtual void
    WillClearList (const ModuleList& module_list);

public:
    
    void
    ModulesDidLoad (ModuleList &module_list);

    void
    ModulesDidUnload (ModuleList &module_list);
    
    void
    SymbolsDidLoad (ModuleList &module_list);
    
    //------------------------------------------------------------------
    /// Gets the module for the main executable.
    ///
    /// Each process has a notion of a main executable that is the file
    /// that will be executed or attached to. Executable files can have
    /// dependent modules that are discovered from the object files, or
    /// discovered at runtime as things are dynamically loaded.
    ///
    /// @return
    ///     The shared pointer to the executable module which can
    ///     contains a NULL Module object if no executable has been
    ///     set.
    ///
    /// @see DynamicLoader
    /// @see ObjectFile::GetDependentModules (FileSpecList&)
    /// @see Process::SetExecutableModule(lldb::ModuleSP&)
    //------------------------------------------------------------------
    lldb::ModuleSP
    GetExecutableModule ();

    Module*
    GetExecutableModulePointer ();

    //------------------------------------------------------------------
    /// Set the main executable module.
    ///
    /// Each process has a notion of a main executable that is the file
    /// that will be executed or attached to. Executable files can have
    /// dependent modules that are discovered from the object files, or
    /// discovered at runtime as things are dynamically loaded.
    ///
    /// Setting the executable causes any of the current dependant
    /// image information to be cleared and replaced with the static
    /// dependent image information found by calling
    /// ObjectFile::GetDependentModules (FileSpecList&) on the main
    /// executable and any modules on which it depends. Calling
    /// Process::GetImages() will return the newly found images that
    /// were obtained from all of the object files.
    ///
    /// @param[in] module_sp
    ///     A shared pointer reference to the module that will become
    ///     the main executable for this process.
    ///
    /// @param[in] get_dependent_files
    ///     If \b true then ask the object files to track down any
    ///     known dependent files.
    ///
    /// @see ObjectFile::GetDependentModules (FileSpecList&)
    /// @see Process::GetImages()
    //------------------------------------------------------------------
    void
    SetExecutableModule (lldb::ModuleSP& module_sp, bool get_dependent_files);

    bool
    LoadScriptingResources (std::list<Error>& errors,
                            Stream* feedback_stream = NULL,
                            bool continue_on_error = true)
    {
        return m_images.LoadScriptingResourcesInTarget(this,errors,feedback_stream,continue_on_error);
    }
    
    //------------------------------------------------------------------
    /// Get accessor for the images for this process.
    ///
    /// Each process has a notion of a main executable that is the file
    /// that will be executed or attached to. Executable files can have
    /// dependent modules that are discovered from the object files, or
    /// discovered at runtime as things are dynamically loaded. After
    /// a main executable has been set, the images will contain a list
    /// of all the files that the executable depends upon as far as the
    /// object files know. These images will usually contain valid file
    /// virtual addresses only. When the process is launched or attached
    /// to, the DynamicLoader plug-in will discover where these images
    /// were loaded in memory and will resolve the load virtual
    /// addresses is each image, and also in images that are loaded by
    /// code.
    ///
    /// @return
    ///     A list of Module objects in a module list.
    //------------------------------------------------------------------
    const ModuleList&
    GetImages () const
    {
        return m_images;
    }
    
    ModuleList&
    GetImages ()
    {
        return m_images;
    }
    
    //------------------------------------------------------------------
    /// Return whether this FileSpec corresponds to a module that should be considered for general searches.
    ///
    /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches
    /// and any module that returns \b true will not be searched.  Note the
    /// SearchFilterForNonModuleSpecificSearches is the search filter that
    /// gets used in the CreateBreakpoint calls when no modules is provided.
    ///
    /// The target call at present just consults the Platform's call of the
    /// same name.
    /// 
    /// @param[in] module_sp
    ///     A shared pointer reference to the module that checked.
    ///
    /// @return \b true if the module should be excluded, \b false otherwise.
    //------------------------------------------------------------------
    bool
    ModuleIsExcludedForNonModuleSpecificSearches (const FileSpec &module_spec);
    
    //------------------------------------------------------------------
    /// Return whether this module should be considered for general searches.
    ///
    /// This API will be consulted by the SearchFilterForNonModuleSpecificSearches
    /// and any module that returns \b true will not be searched.  Note the
    /// SearchFilterForNonModuleSpecificSearches is the search filter that
    /// gets used in the CreateBreakpoint calls when no modules is provided.
    ///
    /// The target call at present just consults the Platform's call of the
    /// same name.
    ///
    /// FIXME: When we get time we should add a way for the user to set modules that they
    /// don't want searched, in addition to or instead of the platform ones.
    /// 
    /// @param[in] module_sp
    ///     A shared pointer reference to the module that checked.
    ///
    /// @return \b true if the module should be excluded, \b false otherwise.
    //------------------------------------------------------------------
    bool
    ModuleIsExcludedForNonModuleSpecificSearches (const lldb::ModuleSP &module_sp);

    ArchSpec &
    GetArchitecture ()
    {
        return m_arch;
    }
    
    const ArchSpec &
    GetArchitecture () const
    {
        return m_arch;
    }
    
    //------------------------------------------------------------------
    /// Set the architecture for this target.
    ///
    /// If the current target has no Images read in, then this just sets the architecture, which will
    /// be used to select the architecture of the ExecutableModule when that is set.
    /// If the current target has an ExecutableModule, then calling SetArchitecture with a different
    /// architecture from the currently selected one will reset the ExecutableModule to that slice
    /// of the file backing the ExecutableModule.  If the file backing the ExecutableModule does not
    /// contain a fork of this architecture, then this code will return false, and the architecture
    /// won't be changed.
    /// If the input arch_spec is the same as the already set architecture, this is a no-op.
    ///
    /// @param[in] arch_spec
    ///     The new architecture.
    ///
    /// @return
    ///     \b true if the architecture was successfully set, \bfalse otherwise.
    //------------------------------------------------------------------
    bool
    SetArchitecture (const ArchSpec &arch_spec);

    Debugger &
    GetDebugger ()
    {
        return m_debugger;
    }

    size_t
    ReadMemoryFromFileCache (const Address& addr, 
                             void *dst, 
                             size_t dst_len, 
                             Error &error);

    // Reading memory through the target allows us to skip going to the process
    // for reading memory if possible and it allows us to try and read from 
    // any constant sections in our object files on disk. If you always want
    // live program memory, read straight from the process. If you possibly 
    // want to read from const sections in object files, read from the target.
    // This version of ReadMemory will try and read memory from the process
    // if the process is alive. The order is:
    // 1 - if (prefer_file_cache == true) then read from object file cache
    // 2 - if there is a valid process, try and read from its memory
    // 3 - if (prefer_file_cache == false) then read from object file cache
    size_t
    ReadMemory (const Address& addr,
                bool prefer_file_cache,
                void *dst,
                size_t dst_len,
                Error &error,
                lldb::addr_t *load_addr_ptr = NULL);
    
    size_t
    ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error);
    
    size_t
    ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error);
    
    size_t
    ReadScalarIntegerFromMemory (const Address& addr, 
                                 bool prefer_file_cache,
                                 uint32_t byte_size, 
                                 bool is_signed, 
                                 Scalar &scalar, 
                                 Error &error);

    uint64_t
    ReadUnsignedIntegerFromMemory (const Address& addr, 
                                   bool prefer_file_cache,
                                   size_t integer_byte_size, 
                                   uint64_t fail_value, 
                                   Error &error);

    bool
    ReadPointerFromMemory (const Address& addr, 
                           bool prefer_file_cache,
                           Error &error,
                           Address &pointer_addr);

    SectionLoadList&
    GetSectionLoadList()
    {
        return m_section_load_list;
    }

    const SectionLoadList&
    GetSectionLoadList() const
    {
        return m_section_load_list;
    }

    static Target *
    GetTargetFromContexts (const ExecutionContext *exe_ctx_ptr, 
                           const SymbolContext *sc_ptr);

    //------------------------------------------------------------------
    // lldb::ExecutionContextScope pure virtual functions
    //------------------------------------------------------------------
    virtual lldb::TargetSP
    CalculateTarget ();
    
    virtual lldb::ProcessSP
    CalculateProcess ();
    
    virtual lldb::ThreadSP
    CalculateThread ();
    
    virtual lldb::StackFrameSP
    CalculateStackFrame ();

    virtual void
    CalculateExecutionContext (ExecutionContext &exe_ctx);

    PathMappingList &
    GetImageSearchPathList ();
    
    ClangASTContext *
    GetScratchClangASTContext(bool create_on_demand=true);
    
    ClangASTImporter *
    GetClangASTImporter();
    
    
    // Since expressions results can persist beyond the lifetime of a process,
    // and the const expression results are available after a process is gone,
    // we provide a way for expressions to be evaluated from the Target itself.
    // If an expression is going to be run, then it should have a frame filled
    // in in th execution context. 
    ExecutionResults
    EvaluateExpression (const char *expression,
                        StackFrame *frame,
                        lldb::ValueObjectSP &result_valobj_sp,
                        const EvaluateExpressionOptions& options = EvaluateExpressionOptions());

    ClangPersistentVariables &
    GetPersistentVariables()
    {
        return m_persistent_variables;
    }

    //------------------------------------------------------------------
    // Target Stop Hooks
    //------------------------------------------------------------------
    class StopHook : public UserID
    {
    public:
        ~StopHook ();
        
        StopHook (const StopHook &rhs);
                
        StringList *
        GetCommandPointer ()
        {
            return &m_commands;
        }
        
        const StringList &
        GetCommands()
        {
            return m_commands;
        }
        
        lldb::TargetSP &
        GetTarget()
        {
            return m_target_sp;
        }
        
        void
        SetCommands (StringList &in_commands)
        {
            m_commands = in_commands;
        }
        
        // Set the specifier.  The stop hook will own the specifier, and is responsible for deleting it when we're done.
        void
        SetSpecifier (SymbolContextSpecifier *specifier)
        {
            m_specifier_sp.reset (specifier);
        }
        
        SymbolContextSpecifier *
        GetSpecifier ()
        {
            return m_specifier_sp.get();
        }
        
        // Set the Thread Specifier.  The stop hook will own the thread specifier, and is responsible for deleting it when we're done.
        void
        SetThreadSpecifier (ThreadSpec *specifier);
        
        ThreadSpec *
        GetThreadSpecifier()
        {
            return m_thread_spec_ap.get();
        }
        
        bool
        IsActive()
        {
            return m_active;
        }
        
        void
        SetIsActive (bool is_active)
        {
            m_active = is_active;
        }
        
        void
        GetDescription (Stream *s, lldb::DescriptionLevel level) const;
        
    private:
        lldb::TargetSP m_target_sp;
        StringList   m_commands;
        lldb::SymbolContextSpecifierSP m_specifier_sp;
        std::unique_ptr<ThreadSpec> m_thread_spec_ap;
        bool m_active;
        
        // Use AddStopHook to make a new empty stop hook.  The GetCommandPointer and fill it with commands,
        // and SetSpecifier to set the specifier shared pointer (can be null, that will match anything.)
        StopHook (lldb::TargetSP target_sp, lldb::user_id_t uid);
        friend class Target;
    };
    typedef std::shared_ptr<StopHook> StopHookSP;
    
    // Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook.  
    // Returns the id of the new hook.        
    lldb::user_id_t
    AddStopHook (StopHookSP &new_hook);
    
    void
    RunStopHooks ();
    
    size_t
    GetStopHookSize();
    
    bool
    SetSuppresStopHooks (bool suppress)
    {
        bool old_value = m_suppress_stop_hooks;
        m_suppress_stop_hooks = suppress;
        return old_value;
    }
    
    bool
    GetSuppressStopHooks ()
    {
        return m_suppress_stop_hooks;
    }
    
    bool
    SetSuppressSyntheticValue (bool suppress)
    {
        bool old_value = m_suppress_synthetic_value;
        m_suppress_synthetic_value = suppress;
        return old_value;
    }
    
    bool
    GetSuppressSyntheticValue ()
    {
        return m_suppress_synthetic_value;
    }
    
//    StopHookSP &
//    GetStopHookByIndex (size_t index);
//    
    bool
    RemoveStopHookByID (lldb::user_id_t uid);
    
    void
    RemoveAllStopHooks ();
    
    StopHookSP
    GetStopHookByID (lldb::user_id_t uid);
    
    bool
    SetStopHookActiveStateByID (lldb::user_id_t uid, bool active_state);
    
    void
    SetAllStopHooksActiveState (bool active_state);
    
    size_t GetNumStopHooks () const
    {
        return m_stop_hooks.size();
    }
    
    StopHookSP
    GetStopHookAtIndex (size_t index)
    {
        if (index >= GetNumStopHooks())
            return StopHookSP();
        StopHookCollection::iterator pos = m_stop_hooks.begin();
        
        while (index > 0)
        {
            pos++;
            index--;
        }
        return (*pos).second;
    }
    
    lldb::PlatformSP
    GetPlatform ()
    {
        return m_platform_sp;
    }

    void
    SetPlatform (const lldb::PlatformSP &platform_sp)
    {
        m_platform_sp = platform_sp;
    }

    SourceManager &
    GetSourceManager ();

    //------------------------------------------------------------------
    // Methods.
    //------------------------------------------------------------------
    lldb::SearchFilterSP
    GetSearchFilterForModule (const FileSpec *containingModule);

    lldb::SearchFilterSP
    GetSearchFilterForModuleList (const FileSpecList *containingModuleList);
    
    lldb::SearchFilterSP
    GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);

protected:
    //------------------------------------------------------------------
    // Member variables.
    //------------------------------------------------------------------
    Debugger &      m_debugger;
    lldb::PlatformSP m_platform_sp;     ///< The platform for this target.
    Mutex           m_mutex;            ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe
    ArchSpec        m_arch;
    ModuleList      m_images;           ///< The list of images for this process (shared libraries and anything dynamically loaded).
    SectionLoadList m_section_load_list;
    BreakpointList  m_breakpoint_list;
    BreakpointList  m_internal_breakpoint_list;
    lldb::BreakpointSP m_last_created_breakpoint;
    WatchpointList  m_watchpoint_list;
    lldb::WatchpointSP m_last_created_watchpoint;
    // We want to tightly control the process destruction process so
    // we can correctly tear down everything that we need to, so the only
    // class that knows about the process lifespan is this target class.
    lldb::ProcessSP m_process_sp;
    bool m_valid;
    lldb::SearchFilterSP  m_search_filter_sp;
    PathMappingList m_image_search_paths;
    std::unique_ptr<ClangASTContext> m_scratch_ast_context_ap;
    std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap;
    std::unique_ptr<ClangASTImporter> m_ast_importer_ap;
    ClangPersistentVariables m_persistent_variables;      ///< These are the persistent variables associated with this process for the expression parser.

    std::unique_ptr<SourceManager> m_source_manager_ap;

    typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
    StopHookCollection      m_stop_hooks;
    lldb::user_id_t         m_stop_hook_next_id;
    bool                    m_suppress_stop_hooks;
    bool                    m_suppress_synthetic_value;
    
    static void
    ImageSearchPathsChanged (const PathMappingList &path_list,
                             void *baton);

private:
    DISALLOW_COPY_AND_ASSIGN (Target);
};

} // namespace lldb_private

#endif  // liblldb_Target_h_
