Index: source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
===================================================================
--- source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp	(revision 137946)
+++ source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp	(working copy)
@@ -519,8 +519,53 @@
     return false;
 }
 
+size_t
+ABISysV_x86_64::TrampolineSize()
+{
+    return 14; // 2 (mov rax,) + 8 (addr) + 2 (jmp [rax]) + 2 (ud2)
+}
 
+bool
+ABISysV_x86_64::MakeTrampoline (lldb_private::Process *process,
+                lldb::addr_t addr,
+                lldb_private::ModuleList *modules,
+                lldb::addr_t destination)
+{
 
+    Error error;
+
+    // Instructions:
+    // mov rax, addr
+    // jmp [rax]
+    // ud2 ; undefined instruction
+
+    // REX.W (0x40 | 0x08), 0xb8 + rd (mov r64, imm64)
+    const uint8_t mov_opcode[]  = { 0x48, 0xb8 };
+    // FF /4 (JMP r/m64)
+    const uint8_t jmp_opcode[]  = { 0xff, // unconditional jmp
+                                    0xc0 | 0x20 | 0x00}; // mod=11b, opcode FF /4 (100b), register rax (000b)
+    const uint8_t trap_opcode[] = { 0x0f, 0x0b }; // ud2
+
+    if (process->WriteMemory(addr, mov_opcode, sizeof(mov_opcode), error) != sizeof(mov_opcode))
+        return false;
+
+    addr += sizeof(mov_opcode);
+    Scalar s;
+    s = destination;
+    if (process->WriteScalarToMemory(addr, s, 8, error) != 8)
+        return false;
+
+    addr += 8;
+    if (process->WriteMemory(addr, jmp_opcode, sizeof(jmp_opcode), error) != sizeof(jmp_opcode))
+        return false;
+
+    addr += sizeof(jmp_opcode);
+    if (process->WriteMemory(addr, trap_opcode, sizeof(trap_opcode), error) != sizeof(trap_opcode))
+        return false;
+
+    return true;
+}
+
 void
 ABISysV_x86_64::Initialize()
 {
Index: source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
===================================================================
--- source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h	(revision 137946)
+++ source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h	(working copy)
@@ -220,7 +220,16 @@
         // aren't fixed width...
         return true;
     }
+
+    virtual size_t
+    TrampolineSize();
     
+    virtual bool
+    MakeTrampoline (lldb_private::Process *process,
+                    lldb::addr_t addr,
+                    lldb_private::ModuleList *modules,
+                    lldb::addr_t destination);
+
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------
Index: source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
===================================================================
--- source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp	(revision 137946)
+++ source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp	(working copy)
@@ -12,6 +12,7 @@
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/RegisterValue.h"
 #include "lldb/Core/Scalar.h"
@@ -710,6 +711,43 @@
     return false;
 }
 
+size_t
+ABIMacOSX_i386::TrampolineSize()
+{
+    return 7; // 1 (JMP) + 4 byte offset + 2 (ud2)
+}
+
+bool
+ABIMacOSX_i386::MakeTrampoline (Process *process,
+                                addr_t addr,
+                                ModuleList *modules,
+                                addr_t destination)
+{
+    Error error;
+
+    // Instructions:
+    // jmp imm32 ; jmp [eip+imm32]
+    // ud2 ; undefined instruction
+
+    const uint8_t jmp_opcode[]  = { 0xe9 }; // unconditional jmp rel32
+    const uint8_t trap_opcode[] = { 0x0f, 0x0b }; // ud2 (invalid opcode)
+
+    if (process->WriteMemory(addr, jmp_opcode, sizeof(jmp_opcode), error) != sizeof(jmp_opcode))
+        return false;
+
+    addr += sizeof(jmp_opcode);
+    Scalar s;
+    s = (unsigned long)(destination - (addr + 4));
+    if (process->WriteScalarToMemory(addr, s, 4, error) != 4)
+        return false;
+
+    addr += 4;
+    if (process->WriteMemory(addr, trap_opcode, sizeof(trap_opcode), error) != sizeof(trap_opcode))
+        return false;
+
+    return true;
+}
+
 void
 ABIMacOSX_i386::Initialize()
 {
Index: source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
===================================================================
--- source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h	(revision 137946)
+++ source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h	(working copy)
@@ -201,7 +201,15 @@
         return pc <= UINT32_MAX;
     }
     
+    virtual size_t
+    TrampolineSize();
 
+    virtual bool
+    MakeTrampoline (lldb_private::Process *process,
+                    lldb::addr_t addr,
+                    lldb_private::ModuleList *modules,
+                    lldb::addr_t destination);
+
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------
Index: source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
===================================================================
--- source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp	(revision 137946)
+++ source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp	(working copy)
@@ -553,6 +553,21 @@
     return false;
 }
 
+size_t
+ABIMacOSX_arm::TrampolineSize()
+{
+    return 0;
+}
+
+bool
+ABIMacOSX_arm::MakeTrampoline (lldb_private::Process *process,
+                lldb::addr_t addr,
+                lldb_private::ModuleList *modules,
+                lldb::addr_t destination)
+{
+    return false;
+}
+
 void
 ABIMacOSX_arm::Initialize()
 {
Index: source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
===================================================================
--- source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h	(revision 137946)
+++ source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h	(working copy)
@@ -80,6 +80,15 @@
         return pc <= UINT32_MAX;
     }
 
+    virtual size_t
+    TrampolineSize();
+
+    virtual bool
+    MakeTrampoline (lldb_private::Process *process,
+                    lldb::addr_t addr,
+                    lldb_private::ModuleList *modules,
+                    lldb::addr_t destination);
+
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------
Index: source/Commands/CommandObjectProcess.cpp
===================================================================
--- source/Commands/CommandObjectProcess.cpp	(revision 137946)
+++ source/Commands/CommandObjectProcess.cpp	(working copy)
@@ -1131,7 +1131,161 @@
     { 0,                false, NULL,      0 , 0,                 NULL, 0, eArgTypeNone,   NULL }
 };
 
+
 //-------------------------------------------------------------------------
+// CommandObjectProcessFix
+//-------------------------------------------------------------------------
+#pragma mark CommandObjectProcessFix
+
+class CommandObjectProcessFix : public CommandObject
+{
+public:
+    CommandObjectProcessFix (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "process fix",
+                   "Reloads a shared library, redirecting the symbols to the new functions.",
+                   NULL,
+                   eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+    {
+        CommandArgumentEntry arg;
+        CommandArgumentData run_args_arg;
+
+        // Define the first (and only) variant of this arg.
+        run_args_arg.arg_type = eArgTypeFilename;
+        run_args_arg.arg_repetition = eArgRepeatPlus;
+
+        // There is only one variant this argument could be; put it into the argument entry.
+        arg.push_back (run_args_arg);
+
+        // Push the data for the first argument into the m_arguments vector.
+        m_arguments.push_back (arg);
+    }
+
+    ~CommandObjectProcessFix()
+    {
+    }
+
+    // TODO: If modules are provided, only change the function in those modules (updating the GOT)
+    // Current (only) behaviour:
+    // If no modules are provided change the old function to a trampoline targetting the new one.
+    bool
+    Execute
+    (
+     Args& command,
+     CommandReturnObject &result
+     )
+    {
+        result.SetStatus (eReturnStatusInvalid);
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
+        Process *process = exe_ctx.process;
+        Target  *target  = exe_ctx.target;
+        bool all_modules = true;
+
+        const uint32_t argc = command.GetArgumentCount();
+
+        for (uint32_t i=0; i<argc; ++i)
+        {
+            Error error;
+            const char *image_path = command.GetArgumentAtIndex(i);
+            FileSpec image_spec (image_path, false);
+            process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec);
+            uint32_t image_token = process->LoadImage(image_spec, error);
+            if (image_token != LLDB_INVALID_IMAGE_TOKEN)
+            {
+                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded. Substituting symbols...\n", image_path, image_token);
+
+                ModuleList modules = target->GetImages();
+                size_t num_modules = modules.GetSize();
+                for (size_t m = 0; m<num_modules; ++m) {
+                    Module *module = modules.GetModuleAtIndex(m).get();
+                    if (module->GetFileSpec() == image_spec) {
+                        ObjectFile *objfile = module->GetObjectFile();
+                        if (objfile)
+                        {
+                            Symtab *symtab = objfile->GetSymtab();
+                            if (symtab)
+                            {
+                                for (uint32_t i=0; i<symtab->GetNumSymbols(); ++i) {
+                                    Symbol *sym = symtab->SymbolAtIndex(i);
+                                    if (!sym || (sym->GetType() != eSymbolTypeCode)) {
+                                        continue;
+                                    }
+
+                                    SymbolContextList sc_list;
+                                    if (all_modules) {
+                                        // Substitute functions defined in this solib by changing the currently used function
+                                        modules.FindSymbolsWithNameAndType(sym->GetName(),
+                                                                           eSymbolTypeCode,
+                                                                           sc_list);
+
+                                        for (uint32_t j=0; j<sc_list.GetSize(); ++j) {
+                                            SymbolContext sc;
+                                            sc_list.GetContextAtIndex(j, sc);
+
+                                            if (sc.module_sp && image_spec == sc.module_sp->GetFileSpec()) {
+                                                continue;
+                                            }
+
+                                            Symbol *old_sym = sc.symbol;
+                                            if (old_sym && (old_sym->GetType() == eSymbolTypeCode)) {
+                                                AddressRange &addr_range = old_sym->GetAddressRangeRef();
+                                                // TODO: Make sure no thread is executing halfway through the trampoline's instructions
+                                                process->GetABI()->MakeTrampoline(process,
+                                                                                  addr_range.GetBaseAddress().GetLoadAddress(&process->GetTarget()),
+                                                                                  NULL,
+                                                                                  sym->GetAddressRangeRef().GetBaseAddress().GetLoadAddress(&process->GetTarget()));
+                                            }
+                                        }
+                                    } else { // Only substitute in specified modules (updating the GOT)
+                                        modules.FindSymbolsWithNameAndType(sym->GetName(),
+                                                                           eSymbolTypeTrampoline,
+                                                                           sc_list);
+                                        result.AppendError("Module substitution of functions is not yet implemented.");
+                                        result.SetStatus(eReturnStatusFailed);
+                                        return false;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+        }
+
+        return result.Succeeded();
+    }
+
+    virtual int
+    HandleArgumentCompletion (Args &input,
+                              int &cursor_index,
+                              int &cursor_char_position,
+                              OptionElementVector &opt_element_vector,
+                              int match_start_point,
+                              int max_return_elements,
+                              bool &word_complete,
+                              StringList &matches)
+    {
+        std::string completion_str (input.GetArgumentAtIndex(cursor_index));
+        completion_str.erase (cursor_char_position);
+
+        CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
+                                                             CommandCompletions::eDiskFileCompletion,
+                                                             completion_str.c_str(),
+                                                             match_start_point,
+                                                             max_return_elements,
+                                                             NULL,
+                                                             word_complete,
+                                                             matches);
+        return matches.GetSize();
+    }
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectProcessLoad
 //-------------------------------------------------------------------------
 #pragma mark CommandObjectProcessLoad
@@ -1147,6 +1301,18 @@
                        "process load <filename> [<filename> ...]",
                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
     {
+        CommandArgumentEntry arg;
+        CommandArgumentData run_args_arg;
+
+        // Define the first (and only) variant of this arg.
+        run_args_arg.arg_type = eArgTypeFilename;
+        run_args_arg.arg_repetition = eArgRepeatPlus;
+
+        // There is only one variant this argument could be; put it into the argument entry.
+        arg.push_back (run_args_arg);
+
+        // Push the data for the first argument into the m_arguments vector.
+        m_arguments.push_back (arg);
     }
 
     ~CommandObjectProcessLoad ()
@@ -1838,6 +2004,7 @@
     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue  (interpreter)));
     LoadSubCommand ("connect",     CommandObjectSP (new CommandObjectProcessConnect   (interpreter)));
     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach    (interpreter)));
+    LoadSubCommand ("fix",         CommandObjectSP (new CommandObjectProcessFix      (interpreter)));
     LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad      (interpreter)));
     LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload    (interpreter)));
     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal    (interpreter)));
Index: include/lldb/Target/ABI.h
===================================================================
--- include/lldb/Target/ABI.h	(revision 137946)
+++ include/lldb/Target/ABI.h	(working copy)
@@ -69,7 +69,18 @@
 
     static lldb::ABISP
     FindPlugin (const ArchSpec &arch);
-    
+
+    // Generic trampoline size, in bytes
+    virtual size_t
+    TrampolineSize() = 0;
+
+    // Caller is responsible for ensuring there is enough space for the trampoline
+    virtual bool
+    MakeTrampoline (lldb_private::Process *process,
+                    lldb::addr_t addr,
+                    lldb_private::ModuleList *modules,
+                    lldb::addr_t destination) = 0;
+
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ABI can see and modify these
