Initial checkin of lldb code from internal Apple repo.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@105619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp b/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp
new file mode 100644
index 0000000..58a7ac0
--- /dev/null
+++ b/source/Plugins/Process/Utility/MacOSXLibunwindCallbacks.cpp
@@ -0,0 +1,306 @@
+//===-- MacOSXLibunwindCallbacks.cpp ----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_MacOSXLibunwindCallbacks_cpp_
+#define liblldb_MacOSXLibunwindCallbacks_cpp_
+#if defined(__cplusplus)
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/FileSpec.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+
+#include "lldb-enumerations.h"
+#include "libunwind.h"
+#include "llvm-c/EnhancedDisassembly.h"
+
+using namespace lldb;
+
+namespace lldb_private {
+
+/* Don't implement (libunwind does not use)
+      find_proc_info
+      put_unwind_info
+      get_dyn_info_list_addr
+      access_mem
+      resume
+*/
+/*
+  Should implement (not needed yet)
+      access_fpreg
+      access_vecreg
+      proc_is_sigtramp
+      proc_is_inferior_function_call
+      access_reg_inf_func_call
+*/
+  
+static int 
+access_reg (lldb_private::unw_addr_space_t as, lldb_private::unw_regnum_t regnum, lldb_private::unw_word_t *valp, int write, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    /* FIXME Only support reading for now.  */
+    if (write == 1)
+        return -1;
+    if (th->GetRegisterContext()->GetRegisterInfoAtIndex(regnum) == NULL)
+        return -1;
+    DataExtractor de;
+    if (!th->GetRegisterContext()->ReadRegisterBytes (regnum, de))
+        return -1;
+    memcpy (valp, de.GetDataStart(), de.GetByteSize());
+    return UNW_ESUCCESS;
+}
+
+static int 
+get_proc_name (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t ip, char *bufp, size_t buf_len, lldb_private::unw_word_t *offp, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    Address addr;
+    if (!th->GetProcess().ResolveLoadAddress(ip, addr))
+        return -1;
+    
+    SymbolContext sc;
+    if (!th->GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextFunction, sc))
+        return -1;
+    if (!sc.symbol)
+        return -1;
+    strlcpy (bufp, sc.symbol->GetMangled().GetMangledName().AsCString(""), buf_len);
+    if (offp)
+        *offp = addr.GetLoadAddress(&th->GetProcess()) - sc.symbol->GetValue().GetLoadAddress(&th->GetProcess());
+    return UNW_ESUCCESS;
+}
+
+static int 
+find_image_info (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t load_addr, lldb_private::unw_word_t *mh, 
+                 lldb_private::unw_word_t *text_start, lldb_private::unw_word_t *text_end, 
+                 lldb_private::unw_word_t *eh_frame, lldb_private::unw_word_t *eh_frame_len, 
+                 lldb_private::unw_word_t *compact_unwind_start, lldb_private::unw_word_t *compact_unwind_len, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    Address addr;
+    if (!th->GetProcess().ResolveLoadAddress(load_addr, addr))
+        return -1;
+    
+    SymbolContext sc;
+    if (!th->GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextModule, sc))
+        return -1;
+    
+    SectionList *sl = sc.module_sp->GetObjectFile()->GetSectionList();
+    static ConstString g_segment_name_TEXT("__TEXT");
+    SectionSP text_segment_sp(sl->FindSectionByName(g_segment_name_TEXT));
+    if (!text_segment_sp)
+        return -1;
+    
+    *mh = text_segment_sp->GetLoadBaseAddress (&th->GetProcess());
+    *text_start = text_segment_sp->GetLoadBaseAddress (&th->GetProcess());
+    *text_end = *text_start + text_segment_sp->GetByteSize();
+    
+    static ConstString g_section_name_eh_frame ("__eh_frame");
+    SectionSP eh_frame_section_sp = text_segment_sp->GetChildren().FindSectionByName(g_section_name_eh_frame);
+    if (eh_frame_section_sp.get()) {
+        *eh_frame = eh_frame_section_sp->GetLoadBaseAddress (&th->GetProcess());
+        *eh_frame_len = eh_frame_section_sp->GetByteSize();
+    } else {
+        *eh_frame = 0;
+        *eh_frame_len = 0;
+    }
+    
+    static ConstString g_section_name_unwind_info ("__unwind_info");
+    SectionSP unwind_info_section_sp = text_segment_sp->GetChildren().FindSectionByName(g_section_name_unwind_info);
+    if (unwind_info_section_sp.get()) {
+        *compact_unwind_start = unwind_info_section_sp->GetLoadBaseAddress (&th->GetProcess());
+        *compact_unwind_len = unwind_info_section_sp->GetByteSize();
+    } else {
+        *compact_unwind_start = 0;
+        *compact_unwind_len = 0;
+    }
+    return UNW_ESUCCESS;
+}
+
+static int 
+get_proc_bounds (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t ip, lldb_private::unw_word_t *low, lldb_private::unw_word_t *high, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    Address addr;
+    if (!th->GetProcess().ResolveLoadAddress(ip, addr))
+        return -1;
+    SymbolContext sc;
+    if (!th->GetProcess().GetTarget().GetImages().ResolveSymbolContextForAddress (addr, eSymbolContextFunction | eSymbolContextSymbol, sc))
+        return -1;
+    if (sc.function)
+    {
+        lldb::addr_t start, len;
+        start = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(&th->GetProcess());
+        len = sc.function->GetAddressRange().GetByteSize();
+        if (start == LLDB_INVALID_ADDRESS || len == LLDB_INVALID_ADDRESS)
+            return -1;
+        *low = start;
+        *high = start + len;
+        return UNW_ESUCCESS;
+    }
+    if (sc.symbol)
+    {
+        lldb::addr_t start, len;
+        start = sc.symbol->GetAddressRangeRef().GetBaseAddress().GetLoadAddress(&th->GetProcess());
+        len = sc.symbol->GetAddressRangeRef().GetByteSize();
+        if (start == LLDB_INVALID_ADDRESS)
+            return -1;
+        *low = start;
+        if (len != LLDB_INVALID_ADDRESS)
+            *high = start + len;
+        else
+            *high = 0;
+        return UNW_ESUCCESS;
+    }
+    return -1;
+}
+
+static int 
+access_raw (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t addr, lldb_private::unw_word_t extent, uint8_t *valp, int write, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    /* FIXME Only support reading for now.  */
+    if (write == 1)
+        return -1;
+    
+    Error error;
+    if (th->GetProcess().ReadMemory (addr, valp, extent, error) != extent)
+        return -1;
+    return UNW_ESUCCESS;
+}
+
+
+static int 
+reg_info (lldb_private::unw_addr_space_t as, lldb_private::unw_regnum_t regnum, lldb_private::unw_regtype_t *type, char *buf, size_t buflen, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    RegisterContext *regc = th->GetRegisterContext();
+    if (regnum > regc->GetRegisterCount())
+    {
+        *type = UNW_NOT_A_REG;
+        return UNW_ESUCCESS;
+    }
+    
+    const char *name = regc->GetRegisterName (regnum);
+    if (name == NULL)
+    {
+        *type = UNW_NOT_A_REG;
+        return UNW_ESUCCESS;
+    }
+    strlcpy (buf, name, buflen);
+    
+    const lldb::RegisterInfo *reginfo = regc->GetRegisterInfoAtIndex (regnum);
+    if (reginfo == NULL || reginfo->encoding == eEncodingInvalid)
+    {
+        *type = UNW_NOT_A_REG;
+        return UNW_ESUCCESS;
+    }
+    if (reginfo->encoding == eEncodingUint || reginfo->encoding == eEncodingSint)
+        *type = UNW_INTEGER_REG;
+    if (reginfo->encoding == eEncodingIEEE754)
+        *type = UNW_FLOATING_POINT_REG;
+    if (reginfo->encoding == eEncodingVector)
+        *type = UNW_VECTOR_REG;
+    
+    return UNW_ESUCCESS;
+}
+
+
+static int
+read_byte_for_edis (uint8_t *buf, uint64_t addr, void *arg)
+{
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    DataBufferHeap onebyte(1, 0);
+    Error error;
+    if (th->GetProcess().ReadMemory (addr, onebyte.GetBytes(), onebyte.GetByteSize(), error) != 1)
+        return -1;
+    *buf = onebyte.GetBytes()[0];
+    return UNW_ESUCCESS;
+}
+
+static int 
+instruction_length (lldb_private::unw_addr_space_t as, lldb_private::unw_word_t addr, int *length, void *arg)
+{
+    EDDisassemblerRef disasm;
+    EDInstRef         cur_insn;
+    
+    if (arg == 0)
+        return -1;
+    Thread *th = (Thread *) arg;
+    const ArchSpec target_arch (th->GetProcess().GetTarget().GetArchitecture ());
+    
+    if (target_arch.GetCPUType() == CPU_TYPE_I386)
+    {
+        if (EDGetDisassembler (&disasm, "i386-apple-darwin", kEDAssemblySyntaxX86ATT) != 0)
+            return -1;
+    }
+    else if (target_arch.GetCPUType() == CPU_TYPE_X86_64)
+    {
+        if (EDGetDisassembler (&disasm, "x86_64-apple-darwin", kEDAssemblySyntaxX86ATT) != 0)
+            return -1;
+    }
+    else
+    {
+        return -1;
+    }
+    
+    if (EDCreateInsts (&cur_insn, 1, disasm, read_byte_for_edis, addr, arg) != 1)
+        return -1;
+    *length = EDInstByteSize (cur_insn);
+    EDReleaseInst (cur_insn);
+    return UNW_ESUCCESS;
+}
+
+lldb_private::unw_accessors_t 
+get_macosx_libunwind_callbacks () {
+  lldb_private::unw_accessors_t ap;
+  bzero (&ap, sizeof (lldb_private::unw_accessors_t));
+  ap.find_proc_info = NULL;
+  ap.put_unwind_info = NULL;
+  ap.get_dyn_info_list_addr = NULL;
+  ap.find_image_info = find_image_info;
+  ap.access_mem = NULL;
+  ap.access_reg = access_reg;
+  ap.access_fpreg = NULL;
+  ap.access_vecreg = NULL;
+  ap.resume = NULL;
+  ap.get_proc_name = get_proc_name;
+  ap.get_proc_bounds = get_proc_bounds;
+  ap.access_raw = access_raw;
+  ap.reg_info = reg_info;
+  ap.proc_is_sigtramp = NULL;
+  ap.proc_is_inferior_function_call = NULL;
+  ap.access_reg_inf_func_call = NULL;
+  ap.instruction_length = instruction_length;
+  return ap;
+}
+
+
+} // namespace lldb_private
+
+#endif  // #if defined(__cplusplus)
+#endif // #ifndef liblldb_MacOSXLibunwindCallbacks_cpp_