[Lldb-commits] [lldb] r198976 - Get the breakpoint setting, and the Mac OS X DYLD trampolines and expression evaluator to handle Indirect

Jim Ingham jingham at apple.com
Fri Jan 10 15:47:00 PST 2014


Author: jingham
Date: Fri Jan 10 17:46:59 2014
New Revision: 198976

URL: http://llvm.org/viewvc/llvm-project?rev=198976&view=rev
Log:
Get the breakpoint setting, and the Mac OS X DYLD trampolines and expression evaluator to handle Indirect
symbols correctly.  There were a couple of pieces to this.

1) When a breakpoint location finds itself pointing to an Indirect symbol, when the site for it is created
   it needs to resolve the symbol and actually set the site at its target.
2) Not all breakpoints want to do this (i.e. a straight address breakpoint should always set itself on the
   specified address, so somem machinery was needed to specify that.
3) I added some info to the break list output for indirect symbols so you could see what was happening. 
   Also I made it clear when we re-route through re-exported symbols.
4) I moved ResolveIndirectFunction from ProcessPosix to Process since it works the exact same way on Mac OS X
   and the other posix systems.  If we find a platform that doesn't do it this way, they can override the
   call in Process.
5) Fixed one bug in RunThreadPlan, if you were trying to run a thread plan after a "running" event had
   been broadcast, the event coalescing would cause you to miss the ThreadPlan running event.  So I added
   a way to override the coalescing.
6) Made DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan handle Indirect & Re-exported symbols.

<rdar://problem/15280639>

Modified:
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointLocationList.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/Breakpoint/Breakpoint.cpp
    lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
    lldb/trunk/source/Breakpoint/BreakpointLocationList.cpp
    lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp
    lldb/trunk/source/Core/Address.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
    lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
    lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h
    lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
    lldb/trunk/source/Target/LanguageRuntime.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Fri Jan 10 17:46:59 2014
@@ -612,12 +612,30 @@ protected:
     /// Only the Target can make a breakpoint, and it owns the breakpoint lifespans.
     /// The constructor takes a filter and a resolver.  Up in Target there are convenience
     /// variants that make breakpoints for some common cases.
+    ///
+    /// @param[in] target
+    ///    The target in which the breakpoint will be set.
+    ///
+    /// @param[in] filter_sp
+    ///    Shared pointer to the search filter that restricts the search domain of the breakpoint.
+    ///
+    /// @param[in] resolver_sp
+    ///    Shared pointer to the resolver object that will determine breakpoint matches.
+    ///
+    /// @param hardware
+    ///    If true, request a hardware breakpoint to be used to implement the breakpoint locations.
+    ///
+    /// @param resolve_indirect_symbols
+    ///    If true, and the address of a given breakpoint location in this breakpoint is set on an
+    ///    indirect symbol (i.e. Symbol::IsIndirect returns true) then the actual breakpoint site will
+    ///    be set on the target of the indirect symbol.
     //------------------------------------------------------------------
     // This is the generic constructor
     Breakpoint(Target &target,
                lldb::SearchFilterSP &filter_sp,
                lldb::BreakpointResolverSP &resolver_sp,
-               bool hardware);
+               bool hardware,
+               bool resolve_indirect_symbols = true);
     
     friend class BreakpointLocation;  // To call the following two when determining whether to stop.
 
@@ -643,6 +661,7 @@ private:
     BreakpointOptions m_options;              // Settable breakpoint options
     BreakpointLocationList m_locations;       // The list of locations currently found for this breakpoint.
     std::string m_kind_description;
+    bool m_resolve_indirect_symbols;
     
     void
     SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h Fri Jan 10 17:46:59 2014
@@ -321,7 +321,59 @@ public:
     //------------------------------------------------------------------
     bool
     InvokeCallback (StoppointCallbackContext *context);
+    
+    //------------------------------------------------------------------
+    /// Returns whether we should resolve Indirect functions in setting the breakpoint site
+    /// for this location.
+    ///
+    /// @return
+    ///     \b true if the breakpoint SITE for this location should be set on the
+    ///     resolved location for Indirect functions.
+    //------------------------------------------------------------------
+    bool
+    ShouldResolveIndirectFunctions ()
+    {
+        return m_should_resolve_indirect_functions;
+    }
 
+    //------------------------------------------------------------------
+    /// Returns whether the address set in the breakpoint site for this location was found by resolving
+    /// an indirect symbol.
+    ///
+    /// @return
+    ///     \b true or \b false as given in the description above.
+    //------------------------------------------------------------------
+    bool
+    IsIndirect ()
+    {
+        return m_is_indirect;
+    }
+    
+    void
+    SetIsIndirect (bool is_indirect)
+    {
+        m_is_indirect = is_indirect;
+    }
+    
+    //------------------------------------------------------------------
+    /// Returns whether the address set in the breakpoint location was re-routed to the target of a
+    /// re-exported symbol.
+    ///
+    /// @return
+    ///     \b true or \b false as given in the description above.
+    //------------------------------------------------------------------
+    bool
+    IsReExported ()
+    {
+        return m_is_reexported;
+    }
+    
+    void
+    SetIsReExported (bool is_reexported)
+    {
+        m_is_reexported = is_reexported;
+    }
+    
 protected:
     friend class BreakpointLocationList;
     friend class Process;
@@ -375,12 +427,16 @@ private:
                         Breakpoint &owner,
                         const Address &addr,
                         lldb::tid_t tid,
-                        bool hardware);
-
+                        bool hardware,
+                        bool check_for_resolver = true);
+    
     //------------------------------------------------------------------
     // Data members:
     //------------------------------------------------------------------
     bool m_being_created;
+    bool m_should_resolve_indirect_functions;
+    bool m_is_reexported;
+    bool m_is_indirect;
     Address m_address; ///< The address defining this location.
     Breakpoint &m_owner; ///< The breakpoint that produced this object.
     std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
@@ -390,6 +446,12 @@ private:
     size_t m_condition_hash; ///< For testing whether the condition source code changed.
 
     void
+    SetShouldResolveIndirectFunctions (bool do_resolve)
+    {
+        m_should_resolve_indirect_functions = do_resolve;
+    }
+    
+    void
     SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind);
     
     DISALLOW_COPY_AND_ASSIGN (BreakpointLocation);

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointLocationList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointLocationList.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointLocationList.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointLocationList.h Fri Jan 10 17:46:59 2014
@@ -236,7 +236,7 @@ protected:
     ///     Returns breakpoint location id.
     //------------------------------------------------------------------
     lldb::BreakpointLocationSP
-    Create (const Address &addr);
+    Create (const Address &addr, bool resolve_indirect_symbols);
     
     void
     StartRecordingNewLocations(BreakpointLocationCollection &new_locations);
@@ -246,6 +246,7 @@ protected:
     
     lldb::BreakpointLocationSP
     AddLocation (const Address &addr,
+                 bool resolve_indirect_symbols,
                  bool *new_location = NULL);
 
     bool

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Fri Jan 10 17:46:59 2014
@@ -2986,11 +2986,7 @@ public:
     //------------------------------------------------------------------
 
     virtual lldb::addr_t
-    ResolveIndirectFunction(const Address *address, Error &error)
-    {
-        error.SetErrorStringWithFormat("error: %s does not support indirect functions in the debug process", GetPluginName().GetCString());
-        return LLDB_INVALID_ADDRESS;
-    }
+    ResolveIndirectFunction(const Address *address, Error &error);
 
     virtual Error
     GetMemoryRegionInfo (lldb::addr_t load_addr, 
@@ -3670,6 +3666,12 @@ protected:
     {
         return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
     }
+    
+    void
+    ForceNextEventDelivery()
+    {
+        m_force_next_event_delivery = true;
+    }
 
     //------------------------------------------------------------------
     // Type definitions
@@ -3744,7 +3746,9 @@ protected:
     bool                        m_resume_requested;         // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
     bool                        m_finalize_called;
     bool                        m_clear_thread_plans_on_stop;
+    bool                        m_force_next_event_delivery;
     lldb::StateType             m_last_broadcast_state;   /// This helps with the Public event coalescing in ShouldBroadcastEvent.
+    std::map<lldb::addr_t,lldb::addr_t> m_resolved_indirect_addresses;
     bool m_destroy_in_process;
     
     enum {

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Fri Jan 10 17:46:59 2014
@@ -637,7 +637,8 @@ public:
     CreateBreakpoint (lldb::SearchFilterSP &filter_sp,
                       lldb::BreakpointResolverSP &resolver_sp,
                       bool internal,
-                      bool request_hardware);
+                      bool request_hardware,
+                      bool resolve_indirect_symbols);
 
     // Use this to create a watchpoint:
     lldb::WatchpointSP

Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Fri Jan 10 17:46:59 2014
@@ -45,14 +45,19 @@ Breakpoint::GetEventIdentifier ()
 //----------------------------------------------------------------------
 // Breakpoint constructor
 //----------------------------------------------------------------------
-Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool hardware) :
+Breakpoint::Breakpoint(Target &target,
+                       SearchFilterSP &filter_sp,
+                       BreakpointResolverSP &resolver_sp,
+                       bool hardware,
+                       bool resolve_indirect_symbols) :
     m_being_created(true),
     m_hardware(hardware),
     m_target (target),
     m_filter_sp (filter_sp),
     m_resolver_sp (resolver_sp),
     m_options (),
-    m_locations (*this)
+    m_locations (*this),
+    m_resolve_indirect_symbols(resolve_indirect_symbols)
 {
     m_being_created = false;
 }
@@ -87,7 +92,7 @@ Breakpoint::GetTarget () const
 BreakpointLocationSP
 Breakpoint::AddLocation (const Address &addr, bool *new_location)
 {
-    return m_locations.AddLocation (addr, new_location);
+    return m_locations.AddLocation (addr, m_resolve_indirect_symbols, new_location);
 }
 
 BreakpointLocationSP

Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Fri Jan 10 17:46:59 2014
@@ -39,16 +39,29 @@ BreakpointLocation::BreakpointLocation
     Breakpoint &owner,
     const Address &addr,
     lldb::tid_t tid,
-    bool hardware
+    bool hardware,
+    bool check_for_resolver
 ) :
     StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
     m_being_created(true),
+    m_should_resolve_indirect_functions (false),
+    m_is_reexported (false),
+    m_is_indirect (false),
     m_address (addr),
     m_owner (owner),
     m_options_ap (),
     m_bp_site_sp (),
     m_condition_mutex ()
 {
+    if (check_for_resolver)
+    {
+        Symbol *symbol = m_address.CalculateSymbolContextSymbol();
+        if (symbol && symbol->IsIndirect())
+        {
+            SetShouldResolveIndirectFunctions (true);
+        }
+    }
+    
     SetThreadID (tid);
     m_being_created = false;
 }
@@ -545,7 +558,10 @@ BreakpointLocation::GetDescription (Stre
 
         if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
         {
-            s->PutCString("where = ");
+            if (IsReExported())
+                s->PutCString ("re-exported target = ");
+            else
+                s->PutCString("where = ");
             sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
         }
         else
@@ -584,7 +600,10 @@ BreakpointLocation::GetDescription (Stre
                 if (sc.symbol)
                 {
                     s->EOL();
-                    s->Indent("symbol = ");
+                    if (IsReExported())
+                        s->Indent ("re-exported target = ");
+                    else
+                        s->Indent("symbol = ");
                     s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
                 }
             }
@@ -612,6 +631,24 @@ BreakpointLocation::GetDescription (Stre
         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
     else
         m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
+    
+    if (IsIndirect() && m_bp_site_sp)
+    {
+        Address resolved_address;
+        resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
+        Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
+        if (resolved_symbol)
+        {
+            if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
+                s->Printf (", ");
+            else if (level == lldb::eDescriptionLevelVerbose)
+            {
+                s->EOL();
+                s->Indent();
+            }
+            s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
+        }
+    }
 
     if (level == lldb::eDescriptionLevelVerbose)
     {

Modified: lldb/trunk/source/Breakpoint/BreakpointLocationList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocationList.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointLocationList.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointLocationList.cpp Fri Jan 10 17:46:59 2014
@@ -41,12 +41,12 @@ BreakpointLocationList::~BreakpointLocat
 }
 
 BreakpointLocationSP
-BreakpointLocationList::Create (const Address &addr)
+BreakpointLocationList::Create (const Address &addr, bool resolve_indirect_symbols)
 {
     Mutex::Locker locker (m_mutex);
     // The location ID is just the size of the location list + 1
     lldb::break_id_t bp_loc_id = ++m_next_id;
-    BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware()));
+    BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr, LLDB_INVALID_THREAD_ID, m_owner.IsHardware(), resolve_indirect_symbols));
     m_locations.push_back (bp_loc_sp);
     m_address_to_location[addr] = bp_loc_sp;
     return bp_loc_sp;
@@ -247,7 +247,7 @@ BreakpointLocationList::GetDescription (
 }
 
 BreakpointLocationSP
-BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
+BreakpointLocationList::AddLocation (const Address &addr, bool resolve_indirect_symbols, bool *new_location)
 {
     Mutex::Locker locker (m_mutex);
 
@@ -256,7 +256,7 @@ BreakpointLocationList::AddLocation (con
     BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
     if (!bp_loc_sp)
 	{
-		bp_loc_sp = Create (addr);
+		bp_loc_sp = Create (addr, resolve_indirect_symbols);
 		if (bp_loc_sp)
 		{
 	    	bp_loc_sp->ResolveBreakpointSite();

Modified: lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverName.cpp Fri Jan 10 17:46:59 2014
@@ -272,6 +272,8 @@ BreakpointResolverName::SearchCallback
         {
             if (func_list.GetContextAtIndex(i, sc))
             {
+                bool is_reexported = false;
+                
                 if (sc.block && sc.block->GetInlinedFunctionInfo())
                 {
                     if (!sc.block->GetStartAddress(break_addr))
@@ -293,7 +295,10 @@ BreakpointResolverName::SearchCallback
                     {
                         const Symbol *actual_symbol = sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget());
                         if (actual_symbol)
+                        {
+                            is_reexported = true;
                             break_addr = actual_symbol->GetAddress();
+                        }
                     }
                     else
                     {
@@ -313,6 +318,7 @@ BreakpointResolverName::SearchCallback
                     if (filter.AddressPasses(break_addr))
                     {
                         BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(break_addr, &new_location));
+                        bp_loc_sp->SetIsReExported(is_reexported);
                         if (bp_loc_sp && new_location && !m_breakpoint->IsInternal())
                         {
                             if (log)

Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Fri Jan 10 17:46:59 2014
@@ -328,15 +328,27 @@ Address::GetLoadAddress (Target *target)
 addr_t
 Address::GetCallableLoadAddress (Target *target, bool is_indirect) const
 {
-    if (is_indirect && target) {
+    addr_t code_addr = LLDB_INVALID_ADDRESS;
+    
+    if (is_indirect && target)
+    {
         ProcessSP processSP = target->GetProcessSP();
         Error error;
         if (processSP.get())
-            return processSP->ResolveIndirectFunction(this, error);
+        {
+            code_addr = processSP->ResolveIndirectFunction(this, error);
+            if (!error.Success())
+                code_addr = LLDB_INVALID_ADDRESS;
+        }
     }
-
-    addr_t code_addr = GetLoadAddress (target);
-
+    else
+    {
+        code_addr = GetLoadAddress (target);
+    }
+    
+    if (code_addr == LLDB_INVALID_ADDRESS)
+        return code_addr;
+    
     if (target)
         return target->GetCallableLoadAddress (code_addr, GetAddressClass());
     return code_addr;

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Fri Jan 10 17:46:59 2014
@@ -1596,14 +1596,6 @@ DynamicLoaderMacOSXDYLD::PrivateProcessS
     }
 }
 
-// This bit in the n_desc field of the mach file means that this is a
-// stub that runs arbitrary code to determine the trampoline target.
-// We've established a naming convention with the CoreOS folks for the
-// equivalent symbols they will use for this (which the objc guys didn't follow...) 
-// For now we'll just look for all symbols matching that naming convention...
-
-#define MACH_O_N_SYMBOL_RESOLVER 0x100
-
 ThreadPlanSP
 DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
 {
@@ -1612,104 +1604,123 @@ DynamicLoaderMacOSXDYLD::GetStepThroughT
     const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
     Symbol *current_symbol = current_context.symbol;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    TargetSP target_sp (thread.CalculateTarget());
 
     if (current_symbol != NULL)
     {
+        std::vector<Address>  addresses;
+        
         if (current_symbol->IsTrampoline())
         {
             const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
             
             if (trampoline_name)
             {
-                SymbolContextList target_symbols;
-                TargetSP target_sp (thread.CalculateTarget());
                 const ModuleList &images = target_sp->GetImages();
                 
-                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
-
-                size_t num_original_symbols = target_symbols.GetSize();
-                // FIXME: The resolver symbol is only valid in object files.  In binaries it is reused for the
-                // shared library slot number.  So we'll have to look this up in the dyld info.
-                // For now, just turn this off.
-                
-                // bool orig_is_resolver = (current_symbol->GetFlags() & MACH_O_N_SYMBOL_RESOLVER) == MACH_O_N_SYMBOL_RESOLVER;
-                // FIXME: Actually that isn't true, the N_SYMBOL_RESOLVER bit is only valid in .o files.  You can't use
-                // the symbol flags to tell whether something is a symbol resolver in a linked image.
-                bool orig_is_resolver = false;
+                SymbolContextList code_symbols;
+                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
+                size_t num_code_symbols = code_symbols.GetSize();
                 
-                if (num_original_symbols > 0)
+                if (num_code_symbols > 0)
                 {
-                    // We found symbols that look like they are the targets to our symbol.  Now look through the
-                    // modules containing our symbols to see if there are any for our symbol.  
-                    
-                    ModuleList modules_to_search;
-                    
-                    for (size_t i = 0; i < num_original_symbols; i++)
+                    for (uint32_t i = 0; i < num_code_symbols; i++)
                     {
-                        SymbolContext sc;
-                        target_symbols.GetContextAtIndex(i, sc);
-                        
-                        ModuleSP module_sp (sc.symbol->CalculateSymbolContextModule());
-                        if (module_sp)
-                             modules_to_search.AppendIfNeeded(module_sp);
-                    }
-                    
-                    // If the original stub symbol is a resolver, then we don't want to break on the symbol with the
-                    // original name, but instead on all the symbols it could resolve to since otherwise we would stop 
-                    // in the middle of the resolution...
-                    // Note that the stub is not of the resolver type it will point to the equivalent symbol,
-                    // not the original name, so in that case we don't need to do anything.
-                    
-                    if (orig_is_resolver)
-                    {
-                        target_symbols.Clear();
-                        
-                        FindEquivalentSymbols (current_symbol, modules_to_search, target_symbols);
-                    }
-                                            
-                    // FIXME - Make the Run to Address take multiple addresses, and
-                    // run to any of them.
-                    uint32_t num_symbols = target_symbols.GetSize();
-                    if (num_symbols > 0)
-                    {
-                        std::vector<lldb::addr_t>  addresses;
-                        addresses.resize (num_symbols);
-                        for (uint32_t i = 0; i < num_symbols; i++)
+                        SymbolContext context;
+                        AddressRange addr_range;
+                        if (code_symbols.GetContextAtIndex(i, context))
                         {
-                            SymbolContext context;
-                            AddressRange addr_range;
-                            if (target_symbols.GetContextAtIndex(i, context))
+                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+                            addresses.push_back(addr_range.GetBaseAddress());
+                            if (log)
                             {
-                                context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
-                                lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-                                addresses[i] = load_addr;
+                                addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+                                log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
                             }
                         }
-                        if (addresses.size() > 0)
-                            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
-                        else
-                        {
-                            if (log)
-                                log->Printf ("Couldn't resolve the symbol contexts.");
-                        }
                     }
-                    else
+                }
+                
+                SymbolContextList reexported_symbols;
+                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
+                size_t num_reexported_symbols = reexported_symbols.GetSize();
+                if (num_reexported_symbols > 0)
+                {
+                    for (uint32_t i = 0; i < num_reexported_symbols; i++)
                     {
-                        if (log)
+                        SymbolContext context;
+                        if (reexported_symbols.GetContextAtIndex(i, context))
                         {
-                            log->Printf ("Found a resolver stub for: \"%s\" but could not find any symbols it resolves to.", 
-                                         trampoline_name.AsCString());
+                            if (context.symbol)
+                            {
+                                Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
+                                if (actual_symbol)
+                                {
+                                    if (actual_symbol->GetAddress().IsValid())
+                                    {
+                                        addresses.push_back(actual_symbol->GetAddress());
+                                        if (log)
+                                        {
+                                            lldb::addr_t load_addr = actual_symbol->GetAddress().GetLoadAddress(target_sp.get());
+                                            log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+                                                         actual_symbol->GetName().GetCString(), load_addr);
+                                        }
+                                    }
+                                }
+                            }
                         }
                     }
                 }
-                else
+            }
+        }
+        else if (current_symbol->GetType() == eSymbolTypeReExported)
+        {
+            // I am not sure we could ever end up stopped AT a re-exported symbol.  But just in case:
+            
+            const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+            if (actual_symbol)
+            {
+                Address target_addr(actual_symbol->GetAddress());
+                if (target_addr.IsValid())
                 {
                     if (log)
+                        log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
+                                     current_symbol->GetName().GetCString(),
+                                     actual_symbol->GetName().GetCString(),
+                                     target_addr.GetLoadAddress(target_sp.get()));
+                    addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
+                
+                }
+            }
+        }
+        
+        if (addresses.size() > 0)
+        {
+            // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
+            std::vector<lldb::addr_t> load_addrs;
+            for (Address address : addresses)
+            {
+                Symbol *symbol = address.CalculateSymbolContextSymbol();
+                if (symbol && symbol->IsIndirect())
+                {
+                    Error error;
+                    addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol->GetAddress(), error);
+                    if (error.Success())
                     {
-                        log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
+                        load_addrs.push_back(resolved_addr);
+                        if (log)
+                            log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
+                                        symbol->GetName().GetCString(), resolved_addr);
                     }
                 }
+                else
+                {
+                    load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+                }
+                
             }
+            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
         }
     }
     else
@@ -1732,7 +1743,7 @@ DynamicLoaderMacOSXDYLD::FindEquivalentS
         
     size_t initial_size = equivalent_symbols.GetSize();
     
-    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Z0-9]+)$";
+    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
     std::string equivalent_regex_buf("^");
     equivalent_regex_buf.append (trampoline_name.GetCString());
     equivalent_regex_buf.append (resolver_name_regex);

Modified: lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Fri Jan 10 17:46:59 2014
@@ -403,7 +403,9 @@ ItaniumABILanguageRuntime::CreateExcepti
     FileSpecList filter_modules;
     BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
     SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
-    return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, false);
+    const bool hardware = false;
+    const bool resolve_indirect_functions = false;
+    return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions);
 }
 
 void

Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp Fri Jan 10 17:46:59 2014
@@ -632,20 +632,6 @@ ProcessPOSIX::DoDeallocateMemory(lldb::a
     return error;
 }
 
-addr_t
-ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
-{
-    addr_t function_addr = LLDB_INVALID_ADDRESS;
-    if (address == NULL) {
-        error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
-    } else if (!InferiorCall(this, address, function_addr)) {
-        function_addr = LLDB_INVALID_ADDRESS;
-        error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
-                                       address->CalculateSymbolContextSymbol()->GetName().AsCString());
-    }
-    return function_addr;
-}
-
 size_t
 ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
 {

Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h Fri Jan 10 17:46:59 2014
@@ -104,9 +104,6 @@ public:
     virtual lldb_private::Error
     DoDeallocateMemory(lldb::addr_t ptr);
 
-    virtual lldb::addr_t
-    ResolveIndirectFunction(const lldb_private::Address *address, lldb_private::Error &error);
-
     virtual size_t
     GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
 

Modified: lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp Fri Jan 10 17:46:59 2014
@@ -34,9 +34,16 @@
 using namespace lldb;
 using namespace lldb_private;
 
-bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
-                                    addr_t addr, addr_t length, unsigned prot,
-                                    unsigned flags, addr_t fd, addr_t offset) {
+bool
+lldb_private::InferiorCallMmap (Process *process,
+                                addr_t &allocated_addr,
+                                addr_t addr,
+                                addr_t length,
+                                unsigned prot,
+                                unsigned flags,
+                                addr_t fd,
+                                addr_t offset)
+{
     Thread *thread = process->GetThreadList().GetSelectedThread().get();
     if (thread == NULL)
         return false;
@@ -139,8 +146,11 @@ bool lldb_private::InferiorCallMmap(Proc
     return false;
 }
 
-bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
-                                      addr_t length) {
+bool
+lldb_private::InferiorCallMunmap (Process *process,
+                                  addr_t addr,
+                                  addr_t length)
+{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL)
        return false;
@@ -209,7 +219,14 @@ bool lldb_private::InferiorCallMunmap(Pr
     return false;
 }
 
-bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
+// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
+// function of the form "void * (*)(void)".  We should find a better place to put this.
+
+bool
+lldb_private::InferiorCall (Process *process,
+                            const Address *address,
+                            addr_t &returned_func)
+{
     Thread *thread = process->GetThreadList().GetSelectedThread().get();
     if (thread == NULL || address == NULL)
         return false;
@@ -233,7 +250,7 @@ bool lldb_private::InferiorCall(Process
     lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
     if (call_plan_sp)
     {
-        StreamFile error_strm;
+        StreamString error_strm;
         // This plan is a utility plan, so set it to discard itself when done.
         call_plan_sp->SetIsMasterPlan (true);
         call_plan_sp->SetOkayToDiscard(true);

Modified: lldb/trunk/source/Target/LanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/LanguageRuntime.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Target/LanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/LanguageRuntime.cpp Fri Jan 10 17:46:59 2014
@@ -269,7 +269,8 @@ LanguageRuntime::CreateExceptionBreakpoi
     BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
     SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
     bool hardware = false;
-    BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware));
+    bool resolve_indirect_functions = false;
+    BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
     if (is_internal)
         exc_breakpt_sp->SetBreakpointKind("exception");
     

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Jan 10 17:46:59 2014
@@ -21,6 +21,7 @@
 #include "lldb/Core/InputReader.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Symbol/Symbol.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/State.h"
 #include "lldb/Expression/ClangUserExpression.h"
@@ -41,6 +42,7 @@
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlan.h"
 #include "lldb/Target/ThreadPlanBase.h"
+#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
 
 #ifndef LLDB_DISABLE_POSIX
 #include <spawn.h>
@@ -1052,6 +1054,7 @@ Process::Process(Target &target, Listene
     m_currently_handling_event(false),
     m_finalize_called(false),
     m_clear_thread_plans_on_stop (false),
+    m_force_next_event_delivery(false),
     m_last_broadcast_state (eStateInvalid),
     m_destroy_in_process (false),
     m_can_jit(eCanJITDontKnow)
@@ -2143,7 +2146,60 @@ Process::EnableBreakpointSiteByID (lldb:
 lldb::break_id_t
 Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardware)
 {
-    const addr_t load_addr = owner->GetAddress().GetOpcodeLoadAddress (&m_target);
+    addr_t load_addr = LLDB_INVALID_ADDRESS;
+    
+    bool show_error = true;
+    switch (GetState())
+    {
+        case eStateInvalid:
+        case eStateUnloaded:
+        case eStateConnected:
+        case eStateAttaching:
+        case eStateLaunching:
+        case eStateDetached:
+        case eStateExited:
+            show_error = false;
+            break;
+            
+        case eStateStopped:
+        case eStateRunning:
+        case eStateStepping:
+        case eStateCrashed:
+        case eStateSuspended:
+            show_error = IsAlive();
+            break;
+    }
+
+    // Reset the IsIndirect flag here, in case the location changes from
+    // pointing to a indirect symbol to a regular symbol.
+    owner->SetIsIndirect (false);
+    
+    if (owner->ShouldResolveIndirectFunctions())
+    {
+        Symbol *symbol = owner->GetAddress().CalculateSymbolContextSymbol();
+        if (symbol && symbol->IsIndirect())
+        {
+            Error error;
+            load_addr = ResolveIndirectFunction (&symbol->GetAddress(), error);
+            if (!error.Success() && show_error)
+            {
+                m_target.GetDebugger().GetErrorFile().Printf ("warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
+                                                              symbol->GetAddress().GetLoadAddress(&m_target),
+                                                              owner->GetBreakpoint().GetID(),
+                                                              owner->GetID(),
+                                                              error.AsCString() ? error.AsCString() : "unkown error");
+                return LLDB_INVALID_BREAK_ID;
+            }
+            Address resolved_address(load_addr);
+            load_addr = resolved_address.GetOpcodeLoadAddress (&m_target);
+            owner->SetIsIndirect(true);
+        }
+        else
+            load_addr = owner->GetAddress().GetOpcodeLoadAddress (&m_target);
+    }
+    else
+        load_addr = owner->GetAddress().GetOpcodeLoadAddress (&m_target);
+    
     if (load_addr != LLDB_INVALID_ADDRESS)
     {
         BreakpointSiteSP bp_site_sp;
@@ -2172,28 +2228,6 @@ Process::CreateBreakpointSite (const Bre
                 }
                 else
                 {
-                    bool show_error = true;
-                    switch (GetState())
-                    {
-                        case eStateInvalid:
-                        case eStateUnloaded:
-                        case eStateConnected:
-                        case eStateAttaching:
-                        case eStateLaunching:
-                        case eStateDetached:
-                        case eStateExited:
-                            show_error = false;
-                            break;
-                            
-                        case eStateStopped:
-                        case eStateRunning:
-                        case eStateStepping:
-                        case eStateCrashed:
-                        case eStateSuspended:
-                            show_error = IsAlive();
-                            break;
-                    }
-                    
                     if (show_error)
                     {
                         // Report error for setting breakpoint...
@@ -3804,33 +3838,38 @@ Process::ShouldBroadcastEvent (Event *ev
             // stopped -> running: Report except when there is one or more no votes
             //     and no yes votes.
             SynchronouslyNotifyStateChanged (state);
-            switch (m_last_broadcast_state)
+            if (m_force_next_event_delivery)
+                return_value = true;
+            else
             {
-                case eStateRunning:
-                case eStateStepping:
-                    // We always suppress multiple runnings with no PUBLIC stop in between.
-                    return_value = false;
-                    break;
-                default:
-                    // TODO: make this work correctly. For now always report
-                    // run if we aren't running so we don't miss any runnning
-                    // events. If I run the lldb/test/thread/a.out file and
-                    // break at main.cpp:58, run and hit the breakpoints on
-                    // multiple threads, then somehow during the stepping over
-                    // of all breakpoints no run gets reported.
+                switch (m_last_broadcast_state)
+                {
+                    case eStateRunning:
+                    case eStateStepping:
+                        // We always suppress multiple runnings with no PUBLIC stop in between.
+                        return_value = false;
+                        break;
+                    default:
+                        // TODO: make this work correctly. For now always report
+                        // run if we aren't running so we don't miss any runnning
+                        // events. If I run the lldb/test/thread/a.out file and
+                        // break at main.cpp:58, run and hit the breakpoints on
+                        // multiple threads, then somehow during the stepping over
+                        // of all breakpoints no run gets reported.
 
-                    // This is a transition from stop to run.
-                    switch (m_thread_list.ShouldReportRun (event_ptr))
-                    {
-                        case eVoteYes:
-                        case eVoteNoOpinion:
-                            return_value = true;
-                            break;
-                        case eVoteNo:
-                            return_value = false;
-                            break;
-                    }
-                    break;
+                        // This is a transition from stop to run.
+                        switch (m_thread_list.ShouldReportRun (event_ptr))
+                        {
+                            case eVoteYes:
+                            case eVoteNoOpinion:
+                                return_value = true;
+                                break;
+                            case eVoteNo:
+                                return_value = false;
+                                break;
+                        }
+                        break;
+                }
             }
             break;
         case eStateStopped:
@@ -3903,6 +3942,9 @@ Process::ShouldBroadcastEvent (Event *ev
         break;
     }
     
+    // Forcing the next event delivery is a one shot deal.  So reset it here.
+    m_force_next_event_delivery = false;
+
     // We do some coalescing of events (for instance two consecutive running events get coalesced.)
     // But we only coalesce against events we actually broadcast.  So we use m_last_broadcast_state
     // to track that.  NB - you can't use "m_public_state.GetValue()" for that purpose, as was originally done,
@@ -4984,6 +5026,22 @@ Process::RunThreadPlan (ExecutionContext
                 final_timeout.OffsetWithMicroSeconds(timeout_usec);
         }
 
+        // This isn't going to work if there are unfetched events on the queue.
+        // Are there cases where we might want to run the remaining events here, and then try to
+        // call the function?  That's probably being too tricky for our own good.
+        
+        Event *other_events = listener.PeekAtNextEvent();
+        if (other_events != NULL)
+        {
+            errors.Printf("Calling RunThreadPlan with pending events on the queue.");
+            return eExecutionSetupError;
+        }
+        
+        // We also need to make sure that the next event is delivered.  We might be calling a function as part of
+        // a thread plan, in which case the last delivered event could be the running event, and we don't want
+        // event coalescing to cause us to lose OUR running event...
+        ForceNextEventDelivery();
+        
         // This while loop must exit out the bottom, there's cleanup that we need to do when we are done.
         // So don't call return anywhere within it.
         
@@ -5772,3 +5830,39 @@ Process::DidExec ()
     target.DidExec();
 }
 
+addr_t
+Process::ResolveIndirectFunction(const Address *address, Error &error)
+{
+    if (address == nullptr)
+    {
+        Symbol *symbol = address->CalculateSymbolContextSymbol();
+        error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
+                                          symbol ? symbol->GetName().AsCString() : "<UNKNOWN>");
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    addr_t function_addr = LLDB_INVALID_ADDRESS;
+    
+    addr_t addr = address->GetLoadAddress(&GetTarget());
+    std::map<addr_t,addr_t>::const_iterator iter = m_resolved_indirect_addresses.find(addr);
+    if (iter != m_resolved_indirect_addresses.end())
+    {
+        function_addr = (*iter).second;
+    }
+    else
+    {
+        if (!InferiorCall(this, address, function_addr))
+        {
+            Symbol *symbol = address->CalculateSymbolContextSymbol();
+            error.SetErrorStringWithFormat ("Unable to call resolver for indirect function %s",
+                                          symbol ? symbol->GetName().AsCString() : "<UNKNOWN>");
+            function_addr = LLDB_INVALID_ADDRESS;
+        }
+        else
+        {
+            m_resolved_indirect_addresses.insert(std::pair<addr_t, addr_t>(addr, function_addr));
+        }
+    }
+    return function_addr;
+}
+

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=198976&r1=198975&r2=198976&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Fri Jan 10 17:46:59 2014
@@ -250,7 +250,7 @@ Target::CreateSourceRegexBreakpoint (con
 {
     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
     BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
 }
 
 
@@ -304,7 +304,7 @@ Target::CreateBreakpoint (const FileSpec
                                                                      line_no,
                                                                      check_inlines,
                                                                      skip_prologue));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
 }
 
 
@@ -331,7 +331,7 @@ Target::CreateBreakpoint (Address &addr,
 {
     SearchFilterSP filter_sp(new SearchFilterForNonModuleSpecificSearches (shared_from_this()));
     BreakpointResolverSP resolver_sp (new BreakpointResolverAddress (NULL, addr));
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, false);
 }
 
 BreakpointSP
@@ -356,7 +356,7 @@ Target::CreateBreakpoint (const FileSpec
                                                                       func_name_type_mask, 
                                                                       Breakpoint::Exact, 
                                                                       skip_prologue));
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
     }
     return bp_sp;
 }
@@ -383,7 +383,7 @@ Target::CreateBreakpoint (const FileSpec
                                                                       func_names,
                                                                       func_name_type_mask,
                                                                       skip_prologue));
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
     }
     return bp_sp;
 }
@@ -411,7 +411,7 @@ Target::CreateBreakpoint (const FileSpec
                                                                       num_names, 
                                                                       func_name_type_mask,
                                                                       skip_prologue));
-        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+        bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
     }
     return bp_sp;
 }
@@ -489,7 +489,7 @@ Target::CreateFuncRegexBreakpoint (const
                                                                  func_regex, 
                                                                  skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
 
-    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware);
+    return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
 }
 
 lldb::BreakpointSP
@@ -499,12 +499,12 @@ Target::CreateExceptionBreakpoint (enum
 }
     
 BreakpointSP
-Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal, bool request_hardware)
+Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols)
 {
     BreakpointSP bp_sp;
     if (filter_sp && resolver_sp)
     {
-        bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp, request_hardware));
+        bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp, request_hardware, resolve_indirect_symbols));
         resolver_sp->SetBreakpoint (bp_sp.get());
 
         if (internal)





More information about the lldb-commits mailing list