aboutsummaryrefslogtreecommitdiff
path: root/source/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'source/Utility')
-rw-r--r--source/Utility/ARM_DWARF_Registers.cpp435
-rw-r--r--source/Utility/ARM_DWARF_Registers.h217
-rw-r--r--source/Utility/ARM_GCC_Registers.h146
-rw-r--r--source/Utility/KQueue.cpp87
-rw-r--r--source/Utility/KQueue.h72
-rw-r--r--source/Utility/PseudoTerminal.cpp339
-rw-r--r--source/Utility/Range.cpp103
-rw-r--r--source/Utility/RefCounter.cpp25
-rw-r--r--source/Utility/SharingPtr.cpp158
-rw-r--r--source/Utility/StringExtractor.cpp397
-rw-r--r--source/Utility/StringExtractor.h141
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp182
-rw-r--r--source/Utility/StringExtractorGDBRemote.h103
-rw-r--r--source/Utility/TimeSpecTimeout.cpp48
-rw-r--r--source/Utility/TimeSpecTimeout.h90
-rw-r--r--source/Utility/UuidCompatibility.h18
16 files changed, 2561 insertions, 0 deletions
diff --git a/source/Utility/ARM_DWARF_Registers.cpp b/source/Utility/ARM_DWARF_Registers.cpp
new file mode 100644
index 000000000000..491ba040863e
--- /dev/null
+++ b/source/Utility/ARM_DWARF_Registers.cpp
@@ -0,0 +1,435 @@
+//===-- ARM_DWARF_Registers.c -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM_DWARF_Registers.h"
+#include <string.h>
+
+#include <string.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *
+GetARMDWARFRegisterName (unsigned reg_num)
+{
+ switch (reg_num)
+ {
+ case dwarf_r0: return "r0";
+ case dwarf_r1: return "r1";
+ case dwarf_r2: return "r2";
+ case dwarf_r3: return "r3";
+ case dwarf_r4: return "r4";
+ case dwarf_r5: return "r5";
+ case dwarf_r6: return "r6";
+ case dwarf_r7: return "r7";
+ case dwarf_r8: return "r8";
+ case dwarf_r9: return "r9";
+ case dwarf_r10: return "r10";
+ case dwarf_r11: return "r11";
+ case dwarf_r12: return "r12";
+ case dwarf_sp: return "sp";
+ case dwarf_lr: return "lr";
+ case dwarf_pc: return "pc";
+ case dwarf_cpsr:return "cpsr";
+
+ case dwarf_s0: return "s0";
+ case dwarf_s1: return "s1";
+ case dwarf_s2: return "s2";
+ case dwarf_s3: return "s3";
+ case dwarf_s4: return "s4";
+ case dwarf_s5: return "s5";
+ case dwarf_s6: return "s6";
+ case dwarf_s7: return "s7";
+ case dwarf_s8: return "s8";
+ case dwarf_s9: return "s9";
+ case dwarf_s10: return "s10";
+ case dwarf_s11: return "s11";
+ case dwarf_s12: return "s12";
+ case dwarf_s13: return "s13";
+ case dwarf_s14: return "s14";
+ case dwarf_s15: return "s15";
+ case dwarf_s16: return "s16";
+ case dwarf_s17: return "s17";
+ case dwarf_s18: return "s18";
+ case dwarf_s19: return "s19";
+ case dwarf_s20: return "s20";
+ case dwarf_s21: return "s21";
+ case dwarf_s22: return "s22";
+ case dwarf_s23: return "s23";
+ case dwarf_s24: return "s24";
+ case dwarf_s25: return "s25";
+ case dwarf_s26: return "s26";
+ case dwarf_s27: return "s27";
+ case dwarf_s28: return "s28";
+ case dwarf_s29: return "s29";
+ case dwarf_s30: return "s30";
+ case dwarf_s31: return "s31";
+
+ // FPA Registers 0-7
+ case dwarf_f0: return "f0";
+ case dwarf_f1: return "f1";
+ case dwarf_f2: return "f2";
+ case dwarf_f3: return "f3";
+ case dwarf_f4: return "f4";
+ case dwarf_f5: return "f5";
+ case dwarf_f6: return "f6";
+ case dwarf_f7: return "f7";
+
+ // Intel wireless MMX general purpose registers 0 - 7
+ // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
+ case dwarf_wCGR0: return "wCGR0/ACC0";
+ case dwarf_wCGR1: return "wCGR1/ACC1";
+ case dwarf_wCGR2: return "wCGR2/ACC2";
+ case dwarf_wCGR3: return "wCGR3/ACC3";
+ case dwarf_wCGR4: return "wCGR4/ACC4";
+ case dwarf_wCGR5: return "wCGR5/ACC5";
+ case dwarf_wCGR6: return "wCGR6/ACC6";
+ case dwarf_wCGR7: return "wCGR7/ACC7";
+
+ // Intel wireless MMX data registers 0 - 15
+ case dwarf_wR0: return "wR0";
+ case dwarf_wR1: return "wR1";
+ case dwarf_wR2: return "wR2";
+ case dwarf_wR3: return "wR3";
+ case dwarf_wR4: return "wR4";
+ case dwarf_wR5: return "wR5";
+ case dwarf_wR6: return "wR6";
+ case dwarf_wR7: return "wR7";
+ case dwarf_wR8: return "wR8";
+ case dwarf_wR9: return "wR9";
+ case dwarf_wR10: return "wR10";
+ case dwarf_wR11: return "wR11";
+ case dwarf_wR12: return "wR12";
+ case dwarf_wR13: return "wR13";
+ case dwarf_wR14: return "wR14";
+ case dwarf_wR15: return "wR15";
+
+ case dwarf_spsr: return "spsr";
+ case dwarf_spsr_fiq: return "spsr_fiq";
+ case dwarf_spsr_irq: return "spsr_irq";
+ case dwarf_spsr_abt: return "spsr_abt";
+ case dwarf_spsr_und: return "spsr_und";
+ case dwarf_spsr_svc: return "spsr_svc";
+
+ case dwarf_r8_usr: return "r8_usr";
+ case dwarf_r9_usr: return "r9_usr";
+ case dwarf_r10_usr: return "r10_usr";
+ case dwarf_r11_usr: return "r11_usr";
+ case dwarf_r12_usr: return "r12_usr";
+ case dwarf_r13_usr: return "r13_usr";
+ case dwarf_r14_usr: return "r14_usr";
+ case dwarf_r8_fiq: return "r8_fiq";
+ case dwarf_r9_fiq: return "r9_fiq";
+ case dwarf_r10_fiq: return "r10_fiq";
+ case dwarf_r11_fiq: return "r11_fiq";
+ case dwarf_r12_fiq: return "r12_fiq";
+ case dwarf_r13_fiq: return "r13_fiq";
+ case dwarf_r14_fiq: return "r14_fiq";
+ case dwarf_r13_irq: return "r13_irq";
+ case dwarf_r14_irq: return "r14_irq";
+ case dwarf_r13_abt: return "r13_abt";
+ case dwarf_r14_abt: return "r14_abt";
+ case dwarf_r13_und: return "r13_und";
+ case dwarf_r14_und: return "r14_und";
+ case dwarf_r13_svc: return "r13_svc";
+ case dwarf_r14_svc: return "r14_svc";
+
+ // Intel wireless MMX control register in co-processor 0 - 7
+ case dwarf_wC0: return "wC0";
+ case dwarf_wC1: return "wC1";
+ case dwarf_wC2: return "wC2";
+ case dwarf_wC3: return "wC3";
+ case dwarf_wC4: return "wC4";
+ case dwarf_wC5: return "wC5";
+ case dwarf_wC6: return "wC6";
+ case dwarf_wC7: return "wC7";
+
+ // VFP-v3/Neon
+ case dwarf_d0: return "d0";
+ case dwarf_d1: return "d1";
+ case dwarf_d2: return "d2";
+ case dwarf_d3: return "d3";
+ case dwarf_d4: return "d4";
+ case dwarf_d5: return "d5";
+ case dwarf_d6: return "d6";
+ case dwarf_d7: return "d7";
+ case dwarf_d8: return "d8";
+ case dwarf_d9: return "d9";
+ case dwarf_d10: return "d10";
+ case dwarf_d11: return "d11";
+ case dwarf_d12: return "d12";
+ case dwarf_d13: return "d13";
+ case dwarf_d14: return "d14";
+ case dwarf_d15: return "d15";
+ case dwarf_d16: return "d16";
+ case dwarf_d17: return "d17";
+ case dwarf_d18: return "d18";
+ case dwarf_d19: return "d19";
+ case dwarf_d20: return "d20";
+ case dwarf_d21: return "d21";
+ case dwarf_d22: return "d22";
+ case dwarf_d23: return "d23";
+ case dwarf_d24: return "d24";
+ case dwarf_d25: return "d25";
+ case dwarf_d26: return "d26";
+ case dwarf_d27: return "d27";
+ case dwarf_d28: return "d28";
+ case dwarf_d29: return "d29";
+ case dwarf_d30: return "d30";
+ case dwarf_d31: return "d31";
+
+ // NEON 128-bit vector registers (overlays the d registers)
+ case dwarf_q0: return "q0";
+ case dwarf_q1: return "q1";
+ case dwarf_q2: return "q2";
+ case dwarf_q3: return "q3";
+ case dwarf_q4: return "q4";
+ case dwarf_q5: return "q5";
+ case dwarf_q6: return "q6";
+ case dwarf_q7: return "q7";
+ case dwarf_q8: return "q8";
+ case dwarf_q9: return "q9";
+ case dwarf_q10: return "q10";
+ case dwarf_q11: return "q11";
+ case dwarf_q12: return "q12";
+ case dwarf_q13: return "q13";
+ case dwarf_q14: return "q14";
+ case dwarf_q15: return "q15";
+ }
+ return 0;
+}
+
+bool
+GetARMDWARFRegisterInfo (unsigned reg_num, RegisterInfo &reg_info)
+{
+ ::memset (&reg_info, 0, sizeof(RegisterInfo));
+ ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
+
+ if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15)
+ {
+ reg_info.byte_size = 16;
+ reg_info.format = eFormatVectorOfUInt8;
+ reg_info.encoding = eEncodingVector;
+ }
+
+ if (reg_num >= dwarf_d0 && reg_num <= dwarf_d31)
+ {
+ reg_info.byte_size = 8;
+ reg_info.format = eFormatFloat;
+ reg_info.encoding = eEncodingIEEE754;
+ }
+ else if (reg_num >= dwarf_s0 && reg_num <= dwarf_s31)
+ {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatFloat;
+ reg_info.encoding = eEncodingIEEE754;
+ }
+ else if (reg_num >= dwarf_f0 && reg_num <= dwarf_f7)
+ {
+ reg_info.byte_size = 12;
+ reg_info.format = eFormatFloat;
+ reg_info.encoding = eEncodingIEEE754;
+ }
+ else
+ {
+ reg_info.byte_size = 4;
+ reg_info.format = eFormatHex;
+ reg_info.encoding = eEncodingUint;
+ }
+
+ reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
+ switch (reg_num)
+ {
+ case dwarf_r0: reg_info.name = "r0"; break;
+ case dwarf_r1: reg_info.name = "r1"; break;
+ case dwarf_r2: reg_info.name = "r2"; break;
+ case dwarf_r3: reg_info.name = "r3"; break;
+ case dwarf_r4: reg_info.name = "r4"; break;
+ case dwarf_r5: reg_info.name = "r5"; break;
+ case dwarf_r6: reg_info.name = "r6"; break;
+ case dwarf_r7: reg_info.name = "r7"; reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
+ case dwarf_r8: reg_info.name = "r8"; break;
+ case dwarf_r9: reg_info.name = "r9"; break;
+ case dwarf_r10: reg_info.name = "r10"; break;
+ case dwarf_r11: reg_info.name = "r11"; break;
+ case dwarf_r12: reg_info.name = "r12"; break;
+ case dwarf_sp: reg_info.name = "sp"; reg_info.alt_name = "r13"; reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
+ case dwarf_lr: reg_info.name = "lr"; reg_info.alt_name = "r14"; reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
+ case dwarf_pc: reg_info.name = "pc"; reg_info.alt_name = "r15"; reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
+ case dwarf_cpsr:reg_info.name = "cpsr"; reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
+
+ case dwarf_s0: reg_info.name = "s0"; break;
+ case dwarf_s1: reg_info.name = "s1"; break;
+ case dwarf_s2: reg_info.name = "s2"; break;
+ case dwarf_s3: reg_info.name = "s3"; break;
+ case dwarf_s4: reg_info.name = "s4"; break;
+ case dwarf_s5: reg_info.name = "s5"; break;
+ case dwarf_s6: reg_info.name = "s6"; break;
+ case dwarf_s7: reg_info.name = "s7"; break;
+ case dwarf_s8: reg_info.name = "s8"; break;
+ case dwarf_s9: reg_info.name = "s9"; break;
+ case dwarf_s10: reg_info.name = "s10"; break;
+ case dwarf_s11: reg_info.name = "s11"; break;
+ case dwarf_s12: reg_info.name = "s12"; break;
+ case dwarf_s13: reg_info.name = "s13"; break;
+ case dwarf_s14: reg_info.name = "s14"; break;
+ case dwarf_s15: reg_info.name = "s15"; break;
+ case dwarf_s16: reg_info.name = "s16"; break;
+ case dwarf_s17: reg_info.name = "s17"; break;
+ case dwarf_s18: reg_info.name = "s18"; break;
+ case dwarf_s19: reg_info.name = "s19"; break;
+ case dwarf_s20: reg_info.name = "s20"; break;
+ case dwarf_s21: reg_info.name = "s21"; break;
+ case dwarf_s22: reg_info.name = "s22"; break;
+ case dwarf_s23: reg_info.name = "s23"; break;
+ case dwarf_s24: reg_info.name = "s24"; break;
+ case dwarf_s25: reg_info.name = "s25"; break;
+ case dwarf_s26: reg_info.name = "s26"; break;
+ case dwarf_s27: reg_info.name = "s27"; break;
+ case dwarf_s28: reg_info.name = "s28"; break;
+ case dwarf_s29: reg_info.name = "s29"; break;
+ case dwarf_s30: reg_info.name = "s30"; break;
+ case dwarf_s31: reg_info.name = "s31"; break;
+
+ // FPA Registers 0-7
+ case dwarf_f0: reg_info.name = "f0"; break;
+ case dwarf_f1: reg_info.name = "f1"; break;
+ case dwarf_f2: reg_info.name = "f2"; break;
+ case dwarf_f3: reg_info.name = "f3"; break;
+ case dwarf_f4: reg_info.name = "f4"; break;
+ case dwarf_f5: reg_info.name = "f5"; break;
+ case dwarf_f6: reg_info.name = "f6"; break;
+ case dwarf_f7: reg_info.name = "f7"; break;
+
+ // Intel wireless MMX general purpose registers 0 - 7
+ // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
+ case dwarf_wCGR0: reg_info.name = "wCGR0/ACC0"; break;
+ case dwarf_wCGR1: reg_info.name = "wCGR1/ACC1"; break;
+ case dwarf_wCGR2: reg_info.name = "wCGR2/ACC2"; break;
+ case dwarf_wCGR3: reg_info.name = "wCGR3/ACC3"; break;
+ case dwarf_wCGR4: reg_info.name = "wCGR4/ACC4"; break;
+ case dwarf_wCGR5: reg_info.name = "wCGR5/ACC5"; break;
+ case dwarf_wCGR6: reg_info.name = "wCGR6/ACC6"; break;
+ case dwarf_wCGR7: reg_info.name = "wCGR7/ACC7"; break;
+
+ // Intel wireless MMX data registers 0 - 15
+ case dwarf_wR0: reg_info.name = "wR0"; break;
+ case dwarf_wR1: reg_info.name = "wR1"; break;
+ case dwarf_wR2: reg_info.name = "wR2"; break;
+ case dwarf_wR3: reg_info.name = "wR3"; break;
+ case dwarf_wR4: reg_info.name = "wR4"; break;
+ case dwarf_wR5: reg_info.name = "wR5"; break;
+ case dwarf_wR6: reg_info.name = "wR6"; break;
+ case dwarf_wR7: reg_info.name = "wR7"; break;
+ case dwarf_wR8: reg_info.name = "wR8"; break;
+ case dwarf_wR9: reg_info.name = "wR9"; break;
+ case dwarf_wR10: reg_info.name = "wR10"; break;
+ case dwarf_wR11: reg_info.name = "wR11"; break;
+ case dwarf_wR12: reg_info.name = "wR12"; break;
+ case dwarf_wR13: reg_info.name = "wR13"; break;
+ case dwarf_wR14: reg_info.name = "wR14"; break;
+ case dwarf_wR15: reg_info.name = "wR15"; break;
+
+ case dwarf_spsr: reg_info.name = "spsr"; break;
+ case dwarf_spsr_fiq: reg_info.name = "spsr_fiq"; break;
+ case dwarf_spsr_irq: reg_info.name = "spsr_irq"; break;
+ case dwarf_spsr_abt: reg_info.name = "spsr_abt"; break;
+ case dwarf_spsr_und: reg_info.name = "spsr_und"; break;
+ case dwarf_spsr_svc: reg_info.name = "spsr_svc"; break;
+
+ case dwarf_r8_usr: reg_info.name = "r8_usr"; break;
+ case dwarf_r9_usr: reg_info.name = "r9_usr"; break;
+ case dwarf_r10_usr: reg_info.name = "r10_usr"; break;
+ case dwarf_r11_usr: reg_info.name = "r11_usr"; break;
+ case dwarf_r12_usr: reg_info.name = "r12_usr"; break;
+ case dwarf_r13_usr: reg_info.name = "r13_usr"; break;
+ case dwarf_r14_usr: reg_info.name = "r14_usr"; break;
+ case dwarf_r8_fiq: reg_info.name = "r8_fiq"; break;
+ case dwarf_r9_fiq: reg_info.name = "r9_fiq"; break;
+ case dwarf_r10_fiq: reg_info.name = "r10_fiq"; break;
+ case dwarf_r11_fiq: reg_info.name = "r11_fiq"; break;
+ case dwarf_r12_fiq: reg_info.name = "r12_fiq"; break;
+ case dwarf_r13_fiq: reg_info.name = "r13_fiq"; break;
+ case dwarf_r14_fiq: reg_info.name = "r14_fiq"; break;
+ case dwarf_r13_irq: reg_info.name = "r13_irq"; break;
+ case dwarf_r14_irq: reg_info.name = "r14_irq"; break;
+ case dwarf_r13_abt: reg_info.name = "r13_abt"; break;
+ case dwarf_r14_abt: reg_info.name = "r14_abt"; break;
+ case dwarf_r13_und: reg_info.name = "r13_und"; break;
+ case dwarf_r14_und: reg_info.name = "r14_und"; break;
+ case dwarf_r13_svc: reg_info.name = "r13_svc"; break;
+ case dwarf_r14_svc: reg_info.name = "r14_svc"; break;
+
+ // Intel wireless MMX control register in co-processor 0 - 7
+ case dwarf_wC0: reg_info.name = "wC0"; break;
+ case dwarf_wC1: reg_info.name = "wC1"; break;
+ case dwarf_wC2: reg_info.name = "wC2"; break;
+ case dwarf_wC3: reg_info.name = "wC3"; break;
+ case dwarf_wC4: reg_info.name = "wC4"; break;
+ case dwarf_wC5: reg_info.name = "wC5"; break;
+ case dwarf_wC6: reg_info.name = "wC6"; break;
+ case dwarf_wC7: reg_info.name = "wC7"; break;
+
+ // VFP-v3/Neon
+ case dwarf_d0: reg_info.name = "d0"; break;
+ case dwarf_d1: reg_info.name = "d1"; break;
+ case dwarf_d2: reg_info.name = "d2"; break;
+ case dwarf_d3: reg_info.name = "d3"; break;
+ case dwarf_d4: reg_info.name = "d4"; break;
+ case dwarf_d5: reg_info.name = "d5"; break;
+ case dwarf_d6: reg_info.name = "d6"; break;
+ case dwarf_d7: reg_info.name = "d7"; break;
+ case dwarf_d8: reg_info.name = "d8"; break;
+ case dwarf_d9: reg_info.name = "d9"; break;
+ case dwarf_d10: reg_info.name = "d10"; break;
+ case dwarf_d11: reg_info.name = "d11"; break;
+ case dwarf_d12: reg_info.name = "d12"; break;
+ case dwarf_d13: reg_info.name = "d13"; break;
+ case dwarf_d14: reg_info.name = "d14"; break;
+ case dwarf_d15: reg_info.name = "d15"; break;
+ case dwarf_d16: reg_info.name = "d16"; break;
+ case dwarf_d17: reg_info.name = "d17"; break;
+ case dwarf_d18: reg_info.name = "d18"; break;
+ case dwarf_d19: reg_info.name = "d19"; break;
+ case dwarf_d20: reg_info.name = "d20"; break;
+ case dwarf_d21: reg_info.name = "d21"; break;
+ case dwarf_d22: reg_info.name = "d22"; break;
+ case dwarf_d23: reg_info.name = "d23"; break;
+ case dwarf_d24: reg_info.name = "d24"; break;
+ case dwarf_d25: reg_info.name = "d25"; break;
+ case dwarf_d26: reg_info.name = "d26"; break;
+ case dwarf_d27: reg_info.name = "d27"; break;
+ case dwarf_d28: reg_info.name = "d28"; break;
+ case dwarf_d29: reg_info.name = "d29"; break;
+ case dwarf_d30: reg_info.name = "d30"; break;
+ case dwarf_d31: reg_info.name = "d31"; break;
+
+ // NEON 128-bit vector registers (overlays the d registers)
+ case dwarf_q0: reg_info.name = "q0"; break;
+ case dwarf_q1: reg_info.name = "q1"; break;
+ case dwarf_q2: reg_info.name = "q2"; break;
+ case dwarf_q3: reg_info.name = "q3"; break;
+ case dwarf_q4: reg_info.name = "q4"; break;
+ case dwarf_q5: reg_info.name = "q5"; break;
+ case dwarf_q6: reg_info.name = "q6"; break;
+ case dwarf_q7: reg_info.name = "q7"; break;
+ case dwarf_q8: reg_info.name = "q8"; break;
+ case dwarf_q9: reg_info.name = "q9"; break;
+ case dwarf_q10: reg_info.name = "q10"; break;
+ case dwarf_q11: reg_info.name = "q11"; break;
+ case dwarf_q12: reg_info.name = "q12"; break;
+ case dwarf_q13: reg_info.name = "q13"; break;
+ case dwarf_q14: reg_info.name = "q14"; break;
+ case dwarf_q15: reg_info.name = "q15"; break;
+
+ default: return false;
+ }
+ return true;
+}
diff --git a/source/Utility/ARM_DWARF_Registers.h b/source/Utility/ARM_DWARF_Registers.h
new file mode 100644
index 000000000000..6850d3e80f11
--- /dev/null
+++ b/source/Utility/ARM_DWARF_Registers.h
@@ -0,0 +1,217 @@
+//===-- ARM_DWARF_Registers.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM_DWARF_Registers_h_
+#define utility_ARM_DWARF_Registers_h_
+
+#include "lldb/lldb-private.h"
+
+enum
+{
+ dwarf_r0 = 0,
+ dwarf_r1,
+ dwarf_r2,
+ dwarf_r3,
+ dwarf_r4,
+ dwarf_r5,
+ dwarf_r6,
+ dwarf_r7,
+ dwarf_r8,
+ dwarf_r9,
+ dwarf_r10,
+ dwarf_r11,
+ dwarf_r12,
+ dwarf_sp,
+ dwarf_lr,
+ dwarf_pc,
+ dwarf_cpsr,
+
+ dwarf_s0 = 64,
+ dwarf_s1,
+ dwarf_s2,
+ dwarf_s3,
+ dwarf_s4,
+ dwarf_s5,
+ dwarf_s6,
+ dwarf_s7,
+ dwarf_s8,
+ dwarf_s9,
+ dwarf_s10,
+ dwarf_s11,
+ dwarf_s12,
+ dwarf_s13,
+ dwarf_s14,
+ dwarf_s15,
+ dwarf_s16,
+ dwarf_s17,
+ dwarf_s18,
+ dwarf_s19,
+ dwarf_s20,
+ dwarf_s21,
+ dwarf_s22,
+ dwarf_s23,
+ dwarf_s24,
+ dwarf_s25,
+ dwarf_s26,
+ dwarf_s27,
+ dwarf_s28,
+ dwarf_s29,
+ dwarf_s30,
+ dwarf_s31,
+
+ // FPA Registers 0-7
+ dwarf_f0 = 96,
+ dwarf_f1,
+ dwarf_f2,
+ dwarf_f3,
+ dwarf_f4,
+ dwarf_f5,
+ dwarf_f6,
+ dwarf_f7,
+
+ // Intel wireless MMX general purpose registers 0 - 7
+ dwarf_wCGR0 = 104,
+ dwarf_wCGR1,
+ dwarf_wCGR2,
+ dwarf_wCGR3,
+ dwarf_wCGR4,
+ dwarf_wCGR5,
+ dwarf_wCGR6,
+ dwarf_wCGR7,
+
+ // XScale accumulator register 0 - 7 (they do overlap with wCGR0 - wCGR7)
+ dwarf_ACC0 = 104,
+ dwarf_ACC1,
+ dwarf_ACC2,
+ dwarf_ACC3,
+ dwarf_ACC4,
+ dwarf_ACC5,
+ dwarf_ACC6,
+ dwarf_ACC7,
+
+ // Intel wireless MMX data registers 0 - 15
+ dwarf_wR0 = 112,
+ dwarf_wR1,
+ dwarf_wR2,
+ dwarf_wR3,
+ dwarf_wR4,
+ dwarf_wR5,
+ dwarf_wR6,
+ dwarf_wR7,
+ dwarf_wR8,
+ dwarf_wR9,
+ dwarf_wR10,
+ dwarf_wR11,
+ dwarf_wR12,
+ dwarf_wR13,
+ dwarf_wR14,
+ dwarf_wR15,
+
+ dwarf_spsr = 128,
+ dwarf_spsr_fiq,
+ dwarf_spsr_irq,
+ dwarf_spsr_abt,
+ dwarf_spsr_und,
+ dwarf_spsr_svc,
+
+ dwarf_r8_usr = 144,
+ dwarf_r9_usr,
+ dwarf_r10_usr,
+ dwarf_r11_usr,
+ dwarf_r12_usr,
+ dwarf_r13_usr,
+ dwarf_r14_usr,
+ dwarf_r8_fiq,
+ dwarf_r9_fiq,
+ dwarf_r10_fiq,
+ dwarf_r11_fiq,
+ dwarf_r12_fiq,
+ dwarf_r13_fiq,
+ dwarf_r14_fiq,
+ dwarf_r13_irq,
+ dwarf_r14_irq,
+ dwarf_r13_abt,
+ dwarf_r14_abt,
+ dwarf_r13_und,
+ dwarf_r14_und,
+ dwarf_r13_svc,
+ dwarf_r14_svc,
+
+ // Intel wireless MMX control register in co-processor 0 - 7
+ dwarf_wC0 = 192,
+ dwarf_wC1,
+ dwarf_wC2,
+ dwarf_wC3,
+ dwarf_wC4,
+ dwarf_wC5,
+ dwarf_wC6,
+ dwarf_wC7,
+
+ // VFP-v3/Neon
+ dwarf_d0 = 256,
+ dwarf_d1,
+ dwarf_d2,
+ dwarf_d3,
+ dwarf_d4,
+ dwarf_d5,
+ dwarf_d6,
+ dwarf_d7,
+ dwarf_d8,
+ dwarf_d9,
+ dwarf_d10,
+ dwarf_d11,
+ dwarf_d12,
+ dwarf_d13,
+ dwarf_d14,
+ dwarf_d15,
+ dwarf_d16,
+ dwarf_d17,
+ dwarf_d18,
+ dwarf_d19,
+ dwarf_d20,
+ dwarf_d21,
+ dwarf_d22,
+ dwarf_d23,
+ dwarf_d24,
+ dwarf_d25,
+ dwarf_d26,
+ dwarf_d27,
+ dwarf_d28,
+ dwarf_d29,
+ dwarf_d30,
+ dwarf_d31,
+
+ // Neon quadword registers
+ dwarf_q0 = 288,
+ dwarf_q1,
+ dwarf_q2,
+ dwarf_q3,
+ dwarf_q4,
+ dwarf_q5,
+ dwarf_q6,
+ dwarf_q7,
+ dwarf_q8,
+ dwarf_q9,
+ dwarf_q10,
+ dwarf_q11,
+ dwarf_q12,
+ dwarf_q13,
+ dwarf_q14,
+ dwarf_q15
+};
+
+const char *
+GetARMDWARFRegisterName (unsigned reg_num);
+
+bool
+GetARMDWARFRegisterInfo (unsigned reg_num,
+ lldb_private::RegisterInfo &reg_info);
+
+#endif // utility_ARM_DWARF_Registers_h_
+
diff --git a/source/Utility/ARM_GCC_Registers.h b/source/Utility/ARM_GCC_Registers.h
new file mode 100644
index 000000000000..974d01bfc78a
--- /dev/null
+++ b/source/Utility/ARM_GCC_Registers.h
@@ -0,0 +1,146 @@
+//===-- ARM_GCC_Registers.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_ARM_GCC_Registers_h_
+#define utility_ARM_GCC_Registers_h_
+
+enum
+{
+ gcc_r0 = 0,
+ gcc_r1,
+ gcc_r2,
+ gcc_r3,
+ gcc_r4,
+ gcc_r5,
+ gcc_r6,
+ gcc_r7,
+ gcc_r8,
+ gcc_r9,
+ gcc_r10,
+ gcc_r11,
+ gcc_r12,
+ gcc_sp,
+ gcc_lr,
+ gcc_pc,
+ gcc_cpsr
+};
+
+enum
+{
+// Name Nr Rel Offset Size Type Raw value
+ gdb_arm_r0 = 0, // 0 0 4 int32_t
+ gdb_arm_r1 = 1, // 1 4 4 int32_t
+ gdb_arm_r2 = 2, // 2 8 4 int32_t
+ gdb_arm_r3 = 3, // 3 12 4 int32_t
+ gdb_arm_r4 = 4, // 4 16 4 int32_t
+ gdb_arm_r5 = 5, // 5 20 4 int32_t
+ gdb_arm_r6 = 6, // 6 24 4 int32_t
+ gdb_arm_r7 = 7, // 7 28 4 int32_t
+ gdb_arm_r8 = 8, // 8 32 4 int32_t
+ gdb_arm_r9 = 9, // 9 36 4 int32_t
+ gdb_arm_r10 = 10, // 10 40 4 int32_t
+ gdb_arm_r11 = 11, // 11 44 4 int32_t
+ gdb_arm_r12 = 12, // 12 48 4 int32_t
+ gdb_arm_sp = 13, // 13 52 4 int32_t
+ gdb_arm_lr = 14, // 14 56 4 int32_t
+ gdb_arm_pc = 15, // 15 60 4 int32_t
+ gdb_arm_f0 = 16, // 16 64 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f1 = 17, // 17 76 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f2 = 18, // 18 88 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f3 = 19, // 19 100 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f4 = 20, // 20 112 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f5 = 21, // 21 124 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f6 = 22, // 22 136 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f7 = 23, // 23 148 12 _arm_ext_littlebyte_bigword
+ gdb_arm_f8 = 24, // 24 160 12 _arm_ext_littlebyte_bigword
+ gdb_arm_cpsr = 25, // 25 172 4 int32_t
+ gdb_arm_s0 = 26, // 26 176 4 _ieee_single_little
+ gdb_arm_s1 = 27, // 27 180 4 _ieee_single_little
+ gdb_arm_s2 = 28, // 28 184 4 _ieee_single_little
+ gdb_arm_s3 = 29, // 29 188 4 _ieee_single_little
+ gdb_arm_s4 = 30, // 30 192 4 _ieee_single_little
+ gdb_arm_s5 = 31, // 31 196 4 _ieee_single_little
+ gdb_arm_s6 = 32, // 32 200 4 _ieee_single_little
+ gdb_arm_s7 = 33, // 33 204 4 _ieee_single_little
+ gdb_arm_s8 = 34, // 34 208 4 _ieee_single_little
+ gdb_arm_s9 = 35, // 35 212 4 _ieee_single_little
+ gdb_arm_s10 = 36, // 36 216 4 _ieee_single_little
+ gdb_arm_s11 = 37, // 37 220 4 _ieee_single_little
+ gdb_arm_s12 = 38, // 38 224 4 _ieee_single_little
+ gdb_arm_s13 = 39, // 39 228 4 _ieee_single_little
+ gdb_arm_s14 = 40, // 40 232 4 _ieee_single_little
+ gdb_arm_s15 = 41, // 41 236 4 _ieee_single_little
+ gdb_arm_s16 = 42, // 42 240 4 _ieee_single_little
+ gdb_arm_s17 = 43, // 43 244 4 _ieee_single_little
+ gdb_arm_s18 = 44, // 44 248 4 _ieee_single_little
+ gdb_arm_s19 = 45, // 45 252 4 _ieee_single_little
+ gdb_arm_s20 = 46, // 46 256 4 _ieee_single_little
+ gdb_arm_s21 = 47, // 47 260 4 _ieee_single_little
+ gdb_arm_s22 = 48, // 48 264 4 _ieee_single_little
+ gdb_arm_s23 = 49, // 49 268 4 _ieee_single_little
+ gdb_arm_s24 = 50, // 50 272 4 _ieee_single_little
+ gdb_arm_s25 = 51, // 51 276 4 _ieee_single_little
+ gdb_arm_s26 = 52, // 52 280 4 _ieee_single_little
+ gdb_arm_s27 = 53, // 53 284 4 _ieee_single_little
+ gdb_arm_s28 = 54, // 54 288 4 _ieee_single_little
+ gdb_arm_s29 = 55, // 55 292 4 _ieee_single_little
+ gdb_arm_s30 = 56, // 56 296 4 _ieee_single_little
+ gdb_arm_s31 = 57, // 57 300 4 _ieee_single_little
+ gdb_arm_fpscr = 58, // 58 304 4 int32_t
+ gdb_arm_d16 = 59, // 59 308 8 _ieee_double_little
+ gdb_arm_d17 = 60, // 60 316 8 _ieee_double_little
+ gdb_arm_d18 = 61, // 61 324 8 _ieee_double_little
+ gdb_arm_d19 = 62, // 62 332 8 _ieee_double_little
+ gdb_arm_d20 = 63, // 63 340 8 _ieee_double_little
+ gdb_arm_d21 = 64, // 64 348 8 _ieee_double_little
+ gdb_arm_d22 = 65, // 65 356 8 _ieee_double_little
+ gdb_arm_d23 = 66, // 66 364 8 _ieee_double_little
+ gdb_arm_d24 = 67, // 67 372 8 _ieee_double_little
+ gdb_arm_d25 = 68, // 68 380 8 _ieee_double_little
+ gdb_arm_d26 = 69, // 69 388 8 _ieee_double_little
+ gdb_arm_d27 = 70, // 70 396 8 _ieee_double_little
+ gdb_arm_d28 = 71, // 71 404 8 _ieee_double_little
+ gdb_arm_d29 = 72, // 72 412 8 _ieee_double_little
+ gdb_arm_d30 = 73, // 73 420 8 _ieee_double_little
+ gdb_arm_d31 = 74, // 74 428 8 _ieee_double_little
+ gdb_arm_d0 = 75, // 0 436 8 _ieee_double_little
+ gdb_arm_d1 = 76, // 1 444 8 _ieee_double_little
+ gdb_arm_d2 = 77, // 2 452 8 _ieee_double_little
+ gdb_arm_d3 = 78, // 3 460 8 _ieee_double_little
+ gdb_arm_d4 = 79, // 4 468 8 _ieee_double_little
+ gdb_arm_d5 = 80, // 5 476 8 _ieee_double_little
+ gdb_arm_d6 = 81, // 6 484 8 _ieee_double_little
+ gdb_arm_d7 = 82, // 7 492 8 _ieee_double_little
+ gdb_arm_d8 = 83, // 8 500 8 _ieee_double_little
+ gdb_arm_d9 = 84, // 9 508 8 _ieee_double_little
+ gdb_arm_d10 = 85, // 10 516 8 _ieee_double_little
+ gdb_arm_d11 = 86, // 11 524 8 _ieee_double_little
+ gdb_arm_d12 = 87, // 12 532 8 _ieee_double_little
+ gdb_arm_d13 = 88, // 13 540 8 _ieee_double_little
+ gdb_arm_d14 = 89, // 14 548 8 _ieee_double_little
+ gdb_arm_d15 = 90, // 15 556 8 _ieee_double_little
+ gdb_arm_q0 = 91, // 16 564 16 _vec128
+ gdb_arm_q1 = 92, // 17 580 16 _vec128
+ gdb_arm_q2 = 93, // 18 596 16 _vec128
+ gdb_arm_q3 = 94, // 19 612 16 _vec128
+ gdb_arm_q4 = 95, // 20 628 16 _vec128
+ gdb_arm_q5 = 96, // 21 644 16 _vec128
+ gdb_arm_q6 = 97, // 22 660 16 _vec128
+ gdb_arm_q7 = 98, // 23 676 16 _vec128
+ gdb_arm_q8 = 99, // 24 692 16 _vec128
+ gdb_arm_q9 = 100, // 25 708 16 _vec128
+ gdb_arm_q10 = 101, // 26 724 16 _vec128
+ gdb_arm_q11 = 102, // 27 740 16 _vec128
+ gdb_arm_q12 = 103, // 28 756 16 _vec128
+ gdb_arm_q13 = 104, // 29 772 16 _vec128
+ gdb_arm_q14 = 105, // 30 788 16 _vec128
+ gdb_arm_q15 = 106 // 31 804 16 _vec128
+};
+#endif // utility_ARM_GCC_Registers_h_
+
diff --git a/source/Utility/KQueue.cpp b/source/Utility/KQueue.cpp
new file mode 100644
index 000000000000..c0aace448951
--- /dev/null
+++ b/source/Utility/KQueue.cpp
@@ -0,0 +1,87 @@
+//===--------------------- KQueue.cpp ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "KQueue.h"
+
+#ifdef LLDB_USE_KQUEUES
+
+#include "lldb/Core/Error.h"
+
+#include "Utility/TimeSpecTimeout.h"
+
+using namespace lldb_private;
+
+int
+KQueue::GetFD (bool can_create)
+{
+ if (!IsValid () && can_create)
+ m_fd = kqueue();
+ return m_fd;
+}
+
+int
+KQueue::Close ()
+{
+ const int fd = m_fd;
+ if (fd >= 0)
+ {
+ m_fd = -1;
+ return close(fd);
+ }
+ return 0;
+}
+
+int
+KQueue::WaitForEvents (struct kevent *events, int num_events, Error &error, uint32_t timeout_usec)
+{
+ const int fd_kqueue = GetFD(false);
+ if (fd_kqueue >= 0)
+ {
+ TimeSpecTimeout timeout;
+ const struct timespec *timeout_ptr = timeout.SetRelativeTimeoutMircoSeconds32 (timeout_usec);
+ int result = ::kevent(fd_kqueue, NULL, 0, events, num_events, timeout_ptr);
+ if (result == -1)
+ error.SetErrorToErrno();
+ else
+ error.Clear();
+ return result;
+ }
+ else
+ {
+ error.SetErrorString("invalid kqueue fd");
+ }
+ return 0;
+}
+
+bool
+KQueue::AddFDEvent (int fd, bool read, bool write, bool vnode)
+{
+ const int fd_kqueue = GetFD(true);
+ if (fd_kqueue >= 0)
+ {
+ struct kevent event;
+ event.ident = fd;
+ event.filter = 0;
+ if (read)
+ event.filter |= EVFILT_READ;
+ if (write)
+ event.filter |= EVFILT_WRITE;
+ if (vnode)
+ event.filter |= EVFILT_VNODE;
+ event.flags = EV_ADD | EV_CLEAR;
+ event.fflags = 0;
+ event.data = 0;
+ event.udata = NULL;
+ int err = ::kevent(fd_kqueue, &event, 1, NULL, 0, NULL);
+ return err == 0;
+ }
+ return false;
+}
+
+#endif
diff --git a/source/Utility/KQueue.h b/source/Utility/KQueue.h
new file mode 100644
index 000000000000..c5680aaa6314
--- /dev/null
+++ b/source/Utility/KQueue.h
@@ -0,0 +1,72 @@
+//===--------------------- KQueue.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_KQueue_h_
+#define utility_KQueue_h_
+
+#if defined(__APPLE__)
+#define LLDB_USE_KQUEUES
+#endif
+
+#ifdef LLDB_USE_KQUEUES
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+
+#include "lldb/lldb-defines.h"
+
+namespace lldb_private {
+
+class KQueue
+{
+public:
+ KQueue() :
+ m_fd(-1)
+ {
+ }
+
+ ~KQueue()
+ {
+ Close();
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_fd >= 0;
+ }
+
+ int
+ GetFD (bool can_create);
+
+ int
+ Close ();
+
+ bool
+ AddFDEvent (int fd,
+ bool read,
+ bool write,
+ bool vnode);
+
+ int
+ WaitForEvents (struct kevent *events,
+ int num_events,
+ Error &error,
+ uint32_t timeout_usec = UINT32_MAX); // UINT32_MAX means infinite timeout
+
+protected:
+ int m_fd; // The kqueue fd
+};
+
+} // namespace lldb_private
+
+#endif // #ifdef LLDB_USE_KQUEUES
+
+#endif // #ifndef utility_KQueue_h_
diff --git a/source/Utility/PseudoTerminal.cpp b/source/Utility/PseudoTerminal.cpp
new file mode 100644
index 000000000000..e4b444c36873
--- /dev/null
+++ b/source/Utility/PseudoTerminal.cpp
@@ -0,0 +1,339 @@
+//===-- PseudoTerminal.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/PseudoTerminal.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#if defined(TIOCSCTTY)
+#include <sys/ioctl.h>
+#endif
+
+using namespace lldb_utility;
+
+//----------------------------------------------------------------------
+// PseudoTerminal constructor
+//----------------------------------------------------------------------
+PseudoTerminal::PseudoTerminal () :
+ m_master_fd(invalid_fd),
+ m_slave_fd(invalid_fd)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//
+// The destructor will close the master and slave file descriptors
+// if they are valid and ownwership has not been released using the
+// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
+// member functions.
+//----------------------------------------------------------------------
+PseudoTerminal::~PseudoTerminal ()
+{
+ CloseMasterFileDescriptor();
+ CloseSlaveFileDescriptor();
+}
+
+//----------------------------------------------------------------------
+// Close the master file descriptor if it is valid.
+//----------------------------------------------------------------------
+void
+PseudoTerminal::CloseMasterFileDescriptor ()
+{
+ if (m_master_fd >= 0)
+ {
+ ::close (m_master_fd);
+ m_master_fd = invalid_fd;
+ }
+}
+
+//----------------------------------------------------------------------
+// Close the slave file descriptor if it is valid.
+//----------------------------------------------------------------------
+void
+PseudoTerminal::CloseSlaveFileDescriptor ()
+{
+ if (m_slave_fd >= 0)
+ {
+ ::close (m_slave_fd);
+ m_slave_fd = invalid_fd;
+ }
+}
+
+//----------------------------------------------------------------------
+// Open the first available pseudo terminal with OFLAG as the
+// permissions. The file descriptor is stored in this object and can
+// be accessed with the MasterFileDescriptor() accessor. The
+// ownership of the master file descriptor can be released using
+// the ReleaseMasterFileDescriptor() accessor. If this object has
+// a valid master files descriptor when its destructor is called, it
+// will close the master file descriptor, therefore clients must
+// call ReleaseMasterFileDescriptor() if they wish to use the master
+// file descriptor after this object is out of scope or destroyed.
+//
+// RETURNS:
+// Zero when successful, non-zero indicating an error occurred.
+//----------------------------------------------------------------------
+bool
+PseudoTerminal::OpenFirstAvailableMaster (int oflag, char *error_str, size_t error_len)
+{
+ if (error_str)
+ error_str[0] = '\0';
+
+ // Open the master side of a pseudo terminal
+ m_master_fd = ::posix_openpt (oflag);
+ if (m_master_fd < 0)
+ {
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ return false;
+ }
+
+ // Grant access to the slave pseudo terminal
+ if (::grantpt (m_master_fd) < 0)
+ {
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ CloseMasterFileDescriptor ();
+ return false;
+ }
+
+ // Clear the lock flag on the slave pseudo terminal
+ if (::unlockpt (m_master_fd) < 0)
+ {
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ CloseMasterFileDescriptor ();
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+// Open the slave pseudo terminal for the current master pseudo
+// terminal. A master pseudo terminal should already be valid prior to
+// calling this function (see OpenFirstAvailableMaster()).
+// The file descriptor is stored this object's member variables and can
+// be accessed via the GetSlaveFileDescriptor(), or released using the
+// ReleaseSlaveFileDescriptor() member function.
+//
+// RETURNS:
+// Zero when successful, non-zero indicating an error occurred.
+//----------------------------------------------------------------------
+bool
+PseudoTerminal::OpenSlave (int oflag, char *error_str, size_t error_len)
+{
+ if (error_str)
+ error_str[0] = '\0';
+
+ CloseSlaveFileDescriptor();
+
+ // Open the master side of a pseudo terminal
+ const char *slave_name = GetSlaveName (error_str, error_len);
+
+ if (slave_name == NULL)
+ return false;
+
+ m_slave_fd = ::open (slave_name, oflag);
+
+ if (m_slave_fd < 0)
+ {
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ return false;
+ }
+
+ return true;
+}
+
+
+
+//----------------------------------------------------------------------
+// Get the name of the slave pseudo terminal. A master pseudo terminal
+// should already be valid prior to calling this function (see
+// OpenFirstAvailableMaster()).
+//
+// RETURNS:
+// NULL if no valid master pseudo terminal or if ptsname() fails.
+// The name of the slave pseudo terminal as a NULL terminated C string
+// that comes from static memory, so a copy of the string should be
+// made as subsequent calls can change this value.
+//----------------------------------------------------------------------
+const char*
+PseudoTerminal::GetSlaveName (char *error_str, size_t error_len) const
+{
+ if (error_str)
+ error_str[0] = '\0';
+
+ if (m_master_fd < 0)
+ {
+ if (error_str)
+ ::snprintf (error_str, error_len, "%s", "master file descriptor is invalid");
+ return NULL;
+ }
+ const char *slave_name = ::ptsname (m_master_fd);
+
+ if (error_str && slave_name == NULL)
+ ::strerror_r (errno, error_str, error_len);
+
+ return slave_name;
+}
+
+
+//----------------------------------------------------------------------
+// Fork a child process and have its stdio routed to a pseudo terminal.
+//
+// In the parent process when a valid pid is returned, the master file
+// descriptor can be used as a read/write access to stdio of the
+// child process.
+//
+// In the child process the stdin/stdout/stderr will already be routed
+// to the slave pseudo terminal and the master file descriptor will be
+// closed as it is no longer needed by the child process.
+//
+// This class will close the file descriptors for the master/slave
+// when the destructor is called, so be sure to call
+// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
+// file descriptors are going to be used past the lifespan of this
+// object.
+//
+// RETURNS:
+// in the parent process: the pid of the child, or -1 if fork fails
+// in the child process: zero
+//----------------------------------------------------------------------
+lldb::pid_t
+PseudoTerminal::Fork (char *error_str, size_t error_len)
+{
+ if (error_str)
+ error_str[0] = '\0';
+
+ pid_t pid = LLDB_INVALID_PROCESS_ID;
+ if (OpenFirstAvailableMaster (O_RDWR, error_str, error_len))
+ {
+ // Successfully opened our master pseudo terminal
+
+ pid = ::fork ();
+ if (pid < 0)
+ {
+ // Fork failed
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ }
+ else if (pid == 0)
+ {
+ // Child Process
+ ::setsid();
+
+ if (OpenSlave (O_RDWR, error_str, error_len))
+ {
+ // Successfully opened slave
+ // We are done with the master in the child process so lets close it
+ CloseMasterFileDescriptor ();
+
+#if defined(TIOCSCTTY)
+ // Acquire the controlling terminal
+ if (::ioctl (m_slave_fd, TIOCSCTTY, (char *)0) < 0)
+ {
+ if (error_str)
+ ::strerror_r (errno, error_str, error_len);
+ }
+#endif
+ // Duplicate all stdio file descriptors to the slave pseudo terminal
+ if (::dup2 (m_slave_fd, STDIN_FILENO) != STDIN_FILENO)
+ {
+ if (error_str && !error_str[0])
+ ::strerror_r (errno, error_str, error_len);
+ }
+
+ if (::dup2 (m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO)
+ {
+ if (error_str && !error_str[0])
+ ::strerror_r (errno, error_str, error_len);
+ }
+
+ if (::dup2 (m_slave_fd, STDERR_FILENO) != STDERR_FILENO)
+ {
+ if (error_str && !error_str[0])
+ ::strerror_r (errno, error_str, error_len);
+ }
+ }
+ }
+ else
+ {
+ // Parent Process
+ // Do nothing and let the pid get returned!
+ }
+ }
+ return pid;
+}
+
+//----------------------------------------------------------------------
+// The master file descriptor accessor. This object retains ownership
+// of the master file descriptor when this accessor is used. Use
+// ReleaseMasterFileDescriptor() if you wish this object to release
+// ownership of the master file descriptor.
+//
+// Returns the master file descriptor, or -1 if the master file
+// descriptor is not currently valid.
+//----------------------------------------------------------------------
+int
+PseudoTerminal::GetMasterFileDescriptor () const
+{
+ return m_master_fd;
+}
+
+//----------------------------------------------------------------------
+// The slave file descriptor accessor.
+//
+// Returns the slave file descriptor, or -1 if the slave file
+// descriptor is not currently valid.
+//----------------------------------------------------------------------
+int
+PseudoTerminal::GetSlaveFileDescriptor () const
+{
+ return m_slave_fd;
+}
+
+//----------------------------------------------------------------------
+// Release ownership of the master pseudo terminal file descriptor
+// without closing it. The destructor for this class will close the
+// master file descriptor if the ownership isn't released using this
+// call and the master file descriptor has been opened.
+//----------------------------------------------------------------------
+int
+PseudoTerminal::ReleaseMasterFileDescriptor ()
+{
+ // Release ownership of the master pseudo terminal file
+ // descriptor without closing it. (the destructor for this
+ // class will close it otherwise!)
+ int fd = m_master_fd;
+ m_master_fd = invalid_fd;
+ return fd;
+}
+
+//----------------------------------------------------------------------
+// Release ownership of the slave pseudo terminal file descriptor
+// without closing it. The destructor for this class will close the
+// slave file descriptor if the ownership isn't released using this
+// call and the slave file descriptor has been opened.
+//----------------------------------------------------------------------
+int
+PseudoTerminal::ReleaseSlaveFileDescriptor ()
+{
+ // Release ownership of the slave pseudo terminal file
+ // descriptor without closing it (the destructor for this
+ // class will close it otherwise!)
+ int fd = m_slave_fd;
+ m_slave_fd = invalid_fd;
+ return fd;
+}
+
diff --git a/source/Utility/Range.cpp b/source/Utility/Range.cpp
new file mode 100644
index 000000000000..158d1e729d48
--- /dev/null
+++ b/source/Utility/Range.cpp
@@ -0,0 +1,103 @@
+//===--------------------- Range.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Range.h"
+
+using namespace lldb_utility;
+
+Range::Range (const Range& rng) :
+m_low(rng.m_low),
+m_high(rng.m_high)
+{
+ InitRange();
+}
+
+Range::Range (Range::ValueType low,
+ Range::ValueType high) :
+m_low(low),
+m_high(high)
+{
+ InitRange();
+}
+
+void
+Range::InitRange ()
+{
+ if (m_low == OPEN_END)
+ {
+ if (m_high == OPEN_END)
+ m_low = 0;
+ else
+ {
+ // make an empty range
+ m_low = 1;
+ m_high = 0;
+ }
+ }
+}
+
+Range&
+Range::operator = (const Range& rhs)
+{
+ if (&rhs != this)
+ {
+ this->m_low = rhs.m_low;
+ this->m_high = rhs.m_high;
+ }
+ return *this;
+}
+
+void
+Range::Flip ()
+{
+ std::swap(m_high, m_low);
+}
+
+void
+Range::Intersection (const Range& other)
+{
+ m_low = std::max(m_low,other.m_low);
+ m_high = std::min(m_high,other.m_high);
+}
+
+void
+Range::Union (const Range& other)
+{
+ m_low = std::min(m_low,other.m_low);
+ m_high = std::max(m_high,other.m_high);
+}
+
+void
+Range::Iterate (RangeCallback callback)
+{
+ ValueType counter = m_low;
+ while (counter <= m_high)
+ {
+ bool should_continue = callback(counter);
+ if (!should_continue)
+ return;
+ counter++;
+ }
+}
+
+bool
+Range::IsEmpty ()
+{
+ return (m_low > m_high);
+}
+
+Range::ValueType
+Range::GetSize ()
+{
+ if (m_high == OPEN_END)
+ return OPEN_END;
+ if (m_high >= m_low)
+ return m_high - m_low + 1;
+ return 0;
+}
diff --git a/source/Utility/RefCounter.cpp b/source/Utility/RefCounter.cpp
new file mode 100644
index 000000000000..c3acedd2f056
--- /dev/null
+++ b/source/Utility/RefCounter.cpp
@@ -0,0 +1,25 @@
+//===---------------------RefCounter.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/RefCounter.h"
+
+namespace lldb_utility {
+
+RefCounter::RefCounter(RefCounter::value_type* ctr):
+m_counter(ctr)
+{
+ increment(m_counter);
+}
+
+RefCounter::~RefCounter()
+{
+ decrement(m_counter);
+}
+
+} // namespace lldb_utility
diff --git a/source/Utility/SharingPtr.cpp b/source/Utility/SharingPtr.cpp
new file mode 100644
index 000000000000..f64d7e3995b8
--- /dev/null
+++ b/source/Utility/SharingPtr.cpp
@@ -0,0 +1,158 @@
+//===---------------------SharingPtr.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/SharingPtr.h"
+
+#if defined (ENABLE_SP_LOGGING)
+
+// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignements
+// and allow them to be queried using a pointer by a call to:
+#include <execinfo.h>
+#include <map>
+#include <assert.h>
+#include "lldb/Host/Mutex.h"
+
+#include <vector>
+
+class Backtrace
+{
+public:
+ Backtrace ();
+
+ ~Backtrace ();
+
+ void
+ GetFrames ();
+
+ void
+ Dump () const;
+
+private:
+ void *m_sp_this;
+ std::vector<void *> m_frames;
+};
+
+
+Backtrace::Backtrace () : m_frames()
+{
+}
+
+Backtrace::~Backtrace ()
+{
+}
+
+void
+Backtrace::GetFrames ()
+{
+ void *frames[1024];
+ const int count = ::backtrace (frames, sizeof(frames)/sizeof(void*));
+ if (count > 2)
+ m_frames.assign (frames + 2, frames + (count - 2));
+}
+
+void
+Backtrace::Dump () const
+{
+ if (!m_frames.empty())
+ ::backtrace_symbols_fd (m_frames.data(), m_frames.size(), STDOUT_FILENO);
+ write (STDOUT_FILENO, "\n\n", 2);
+}
+
+extern "C" void track_sp (void *sp_this, void *ptr, long use_count)
+{
+ typedef std::pair<void *, Backtrace> PtrBacktracePair;
+ typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap;
+ static lldb_private::Mutex g_mutex(lldb_private::Mutex::eMutexTypeNormal);
+ lldb_private::Mutex::Locker locker (g_mutex);
+ static PtrToBacktraceMap g_map;
+
+ if (sp_this)
+ {
+ printf ("sp(%p) -> %p %lu\n", sp_this, ptr, use_count);
+
+ if (ptr)
+ {
+ Backtrace bt;
+ bt.GetFrames();
+ g_map[sp_this] = std::make_pair(ptr, bt);
+ }
+ else
+ {
+ g_map.erase (sp_this);
+ }
+ }
+ else
+ {
+ if (ptr)
+ printf ("Searching for shared pointers that are tracking %p: ", ptr);
+ else
+ printf ("Dump all live shared pointres: ");
+
+ uint32_t matches = 0;
+ PtrToBacktraceMap::iterator pos, end = g_map.end();
+ for (pos = g_map.begin(); pos != end; ++pos)
+ {
+ if (ptr == NULL || pos->second.first == ptr)
+ {
+ ++matches;
+ printf ("\nsp(%p): %p\n", pos->first, pos->second.first);
+ pos->second.second.Dump();
+ }
+ }
+ if (matches == 0)
+ {
+ printf ("none.\n");
+ }
+ }
+}
+// Put dump_sp_refs in the lldb namespace to it gets through our exports lists filter in the LLDB.framework or lldb.so
+namespace lldb {
+
+ void dump_sp_refs (void *ptr)
+ {
+ // Use a specially crafted call to "track_sp" which will
+ // dump info on all live shared pointers that reference "ptr"
+ track_sp (NULL, ptr, 0);
+ }
+
+}
+
+#endif
+
+namespace lldb_private {
+
+namespace imp
+{
+
+
+ shared_count::~shared_count()
+ {
+ }
+
+ void
+ shared_count::add_shared()
+ {
+ increment(shared_owners_);
+ }
+
+ void
+ shared_count::release_shared()
+ {
+ if (decrement(shared_owners_) == -1)
+ {
+ on_zero_shared();
+ delete this;
+ }
+ }
+
+} // imp
+
+
+} // namespace lldb
+
diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp
new file mode 100644
index 000000000000..2f4bcecda8f3
--- /dev/null
+++ b/source/Utility/StringExtractor.cpp
@@ -0,0 +1,397 @@
+//===-- StringExtractor.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Utility/StringExtractor.h"
+
+// C Includes
+#include <stdlib.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+static const uint8_t
+g_hex_ascii_to_hex_integer[256] = {
+
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+ 0x8, 0x9, 255, 255, 255, 255, 255, 255,
+ 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+};
+
+static inline int
+xdigit_to_sint (char ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return 10 + ch - 'a';
+ if (ch >= 'A' && ch <= 'F')
+ return 10 + ch - 'A';
+ return ch - '0';
+}
+
+static inline unsigned int
+xdigit_to_uint (uint8_t ch)
+{
+ if (ch >= 'a' && ch <= 'f')
+ return 10u + ch - 'a';
+ if (ch >= 'A' && ch <= 'F')
+ return 10u + ch - 'A';
+ return ch - '0';
+}
+
+//----------------------------------------------------------------------
+// StringExtractor constructor
+//----------------------------------------------------------------------
+StringExtractor::StringExtractor() :
+ m_packet(),
+ m_index (0)
+{
+}
+
+
+StringExtractor::StringExtractor(const char *packet_cstr) :
+ m_packet(),
+ m_index (0)
+{
+ if (packet_cstr)
+ m_packet.assign (packet_cstr);
+}
+
+
+//----------------------------------------------------------------------
+// StringExtractor copy constructor
+//----------------------------------------------------------------------
+StringExtractor::StringExtractor(const StringExtractor& rhs) :
+ m_packet (rhs.m_packet),
+ m_index (rhs.m_index)
+{
+
+}
+
+//----------------------------------------------------------------------
+// StringExtractor assignment operator
+//----------------------------------------------------------------------
+const StringExtractor&
+StringExtractor::operator=(const StringExtractor& rhs)
+{
+ if (this != &rhs)
+ {
+ m_packet = rhs.m_packet;
+ m_index = rhs.m_index;
+
+ }
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+StringExtractor::~StringExtractor()
+{
+}
+
+
+char
+StringExtractor::GetChar (char fail_value)
+{
+ if (m_index < m_packet.size())
+ {
+ char ch = m_packet[m_index];
+ ++m_index;
+ return ch;
+ }
+ m_index = UINT64_MAX;
+ return fail_value;
+}
+
+//----------------------------------------------------------------------
+// Extract an unsigned character from two hex ASCII chars in the packet
+// string
+//----------------------------------------------------------------------
+uint8_t
+StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail)
+{
+ uint32_t i = m_index;
+ if ((i + 2) <= m_packet.size())
+ {
+ const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i])];
+ const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i+1])];
+ if (hi_nibble < 16 && lo_nibble < 16)
+ {
+ m_index += 2;
+ return (hi_nibble << 4) + lo_nibble;
+ }
+ }
+ if (set_eof_on_fail || m_index >= m_packet.size())
+ m_index = UINT64_MAX;
+ return fail_value;
+}
+
+uint32_t
+StringExtractor::GetU32 (uint32_t fail_value, int base)
+{
+ if (m_index < m_packet.size())
+ {
+ char *end = NULL;
+ const char *start = m_packet.c_str();
+ const char *uint_cstr = start + m_index;
+ uint32_t result = ::strtoul (uint_cstr, &end, base);
+
+ if (end && end != uint_cstr)
+ {
+ m_index = end - start;
+ return result;
+ }
+ }
+ return fail_value;
+}
+
+
+uint32_t
+StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value)
+{
+ uint32_t result = 0;
+ uint32_t nibble_count = 0;
+
+ if (little_endian)
+ {
+ uint32_t shift_amount = 0;
+ while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ // Make sure we don't exceed the size of a uint32_t...
+ if (nibble_count >= (sizeof(uint32_t) * 2))
+ {
+ m_index = UINT64_MAX;
+ return fail_value;
+ }
+
+ uint8_t nibble_lo;
+ uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
+ ++m_index;
+ if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ nibble_lo = xdigit_to_sint (m_packet[m_index]);
+ ++m_index;
+ result |= ((uint32_t)nibble_hi << (shift_amount + 4));
+ result |= ((uint32_t)nibble_lo << shift_amount);
+ nibble_count += 2;
+ shift_amount += 8;
+ }
+ else
+ {
+ result |= ((uint32_t)nibble_hi << shift_amount);
+ nibble_count += 1;
+ shift_amount += 4;
+ }
+
+ }
+ }
+ else
+ {
+ while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ // Make sure we don't exceed the size of a uint32_t...
+ if (nibble_count >= (sizeof(uint32_t) * 2))
+ {
+ m_index = UINT64_MAX;
+ return fail_value;
+ }
+
+ uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
+ // Big Endian
+ result <<= 4;
+ result |= nibble;
+
+ ++m_index;
+ ++nibble_count;
+ }
+ }
+ return result;
+}
+
+uint64_t
+StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value)
+{
+ uint64_t result = 0;
+ uint32_t nibble_count = 0;
+
+ if (little_endian)
+ {
+ uint32_t shift_amount = 0;
+ while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ // Make sure we don't exceed the size of a uint64_t...
+ if (nibble_count >= (sizeof(uint64_t) * 2))
+ {
+ m_index = UINT64_MAX;
+ return fail_value;
+ }
+
+ uint8_t nibble_lo;
+ uint8_t nibble_hi = xdigit_to_sint (m_packet[m_index]);
+ ++m_index;
+ if (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ nibble_lo = xdigit_to_sint (m_packet[m_index]);
+ ++m_index;
+ result |= ((uint64_t)nibble_hi << (shift_amount + 4));
+ result |= ((uint64_t)nibble_lo << shift_amount);
+ nibble_count += 2;
+ shift_amount += 8;
+ }
+ else
+ {
+ result |= ((uint64_t)nibble_hi << shift_amount);
+ nibble_count += 1;
+ shift_amount += 4;
+ }
+
+ }
+ }
+ else
+ {
+ while (m_index < m_packet.size() && ::isxdigit (m_packet[m_index]))
+ {
+ // Make sure we don't exceed the size of a uint64_t...
+ if (nibble_count >= (sizeof(uint64_t) * 2))
+ {
+ m_index = UINT64_MAX;
+ return fail_value;
+ }
+
+ uint8_t nibble = xdigit_to_sint (m_packet[m_index]);
+ // Big Endian
+ result <<= 4;
+ result |= nibble;
+
+ ++m_index;
+ ++nibble_count;
+ }
+ }
+ return result;
+}
+
+size_t
+StringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_value)
+{
+ uint8_t *dst = (uint8_t*)dst_void;
+ size_t bytes_extracted = 0;
+ while (bytes_extracted < dst_len && GetBytesLeft ())
+ {
+ dst[bytes_extracted] = GetHexU8 (fail_fill_value);
+ if (IsGood())
+ ++bytes_extracted;
+ else
+ break;
+ }
+
+ for (size_t i = bytes_extracted; i < dst_len; ++i)
+ dst[i] = fail_fill_value;
+
+ return bytes_extracted;
+}
+
+
+// Consume ASCII hex nibble character pairs until we have decoded byte_size
+// bytes of data.
+
+uint64_t
+StringExtractor::GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value)
+{
+ if (byte_size <= 8 && GetBytesLeft() >= byte_size * 2)
+ {
+ uint64_t result = 0;
+ uint32_t i;
+ if (little_endian)
+ {
+ // Little Endian
+ uint32_t shift_amount;
+ for (i = 0, shift_amount = 0;
+ i < byte_size && IsGood();
+ ++i, shift_amount += 8)
+ {
+ result |= ((uint64_t)GetHexU8() << shift_amount);
+ }
+ }
+ else
+ {
+ // Big Endian
+ for (i = 0; i < byte_size && IsGood(); ++i)
+ {
+ result <<= 8;
+ result |= GetHexU8();
+ }
+ }
+ }
+ m_index = UINT64_MAX;
+ return fail_value;
+}
+
+size_t
+StringExtractor::GetHexByteString (std::string &str)
+{
+ str.clear();
+ char ch;
+ while ((ch = GetHexU8()) != '\0')
+ str.append(1, ch);
+ return str.size();
+}
+
+bool
+StringExtractor::GetNameColonValue (std::string &name, std::string &value)
+{
+ // Read something in the form of NNNN:VVVV; where NNNN is any character
+ // that is not a colon, followed by a ':' character, then a value (one or
+ // more ';' chars), followed by a ';'
+ if (m_index < m_packet.size())
+ {
+ const size_t colon_idx = m_packet.find (':', m_index);
+ if (colon_idx != std::string::npos)
+ {
+ const size_t semicolon_idx = m_packet.find (';', colon_idx);
+ if (semicolon_idx != std::string::npos)
+ {
+ name.assign (m_packet, m_index, colon_idx - m_index);
+ value.assign (m_packet, colon_idx + 1, semicolon_idx - (colon_idx + 1));
+ m_index = semicolon_idx + 1;
+ return true;
+ }
+ }
+ }
+ m_index = UINT64_MAX;
+ return false;
+}
diff --git a/source/Utility/StringExtractor.h b/source/Utility/StringExtractor.h
new file mode 100644
index 000000000000..0ded3101fcca
--- /dev/null
+++ b/source/Utility/StringExtractor.h
@@ -0,0 +1,141 @@
+//===-- StringExtractor.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_StringExtractor_h_
+#define utility_StringExtractor_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <stdint.h>
+
+// Other libraries and framework includes
+// Project includes
+
+class StringExtractor
+{
+public:
+
+ enum {
+ BigEndian = 0,
+ LittleEndian = 1
+ };
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ StringExtractor();
+ StringExtractor(const char *packet_cstr);
+ StringExtractor(const StringExtractor& rhs);
+ virtual ~StringExtractor();
+
+ //------------------------------------------------------------------
+ // Operators
+ //------------------------------------------------------------------
+ const StringExtractor&
+ operator=(const StringExtractor& rhs);
+
+ // Returns true if the file position is still valid for the data
+ // contained in this string extractor object.
+ bool
+ IsGood() const
+ {
+ return m_index != UINT64_MAX;
+ }
+
+ uint64_t
+ GetFilePos () const
+ {
+ return m_index;
+ }
+
+ void
+ SetFilePos (uint32_t idx)
+ {
+ m_index = idx;
+ }
+
+ void
+ Clear ()
+ {
+ m_packet.clear();
+ m_index = 0;
+ }
+
+ std::string &
+ GetStringRef ()
+ {
+ return m_packet;
+ }
+
+ const std::string &
+ GetStringRef () const
+ {
+ return m_packet;
+ }
+
+ bool
+ Empty()
+ {
+ return m_packet.empty();
+ }
+
+ size_t
+ GetBytesLeft ()
+ {
+ if (m_index < m_packet.size())
+ return m_packet.size() - m_index;
+ return 0;
+ }
+ char
+ GetChar (char fail_value = '\0');
+
+ uint8_t
+ GetHexU8 (uint8_t fail_value = 0, bool set_eof_on_fail = true);
+
+ bool
+ GetNameColonValue (std::string &name, std::string &value);
+
+ uint32_t
+ GetU32 (uint32_t fail_value, int base = 0);
+
+ uint32_t
+ GetHexMaxU32 (bool little_endian, uint32_t fail_value);
+
+ uint64_t
+ GetHexMaxU64 (bool little_endian, uint64_t fail_value);
+
+ size_t
+ GetHexBytes (void *dst, size_t dst_len, uint8_t fail_fill_value);
+
+ uint64_t
+ GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value);
+
+ size_t
+ GetHexByteString (std::string &str);
+
+ const char *
+ Peek ()
+ {
+ if (m_index < m_packet.size())
+ return m_packet.c_str() + m_index;
+ return NULL;
+ }
+
+protected:
+ //------------------------------------------------------------------
+ // For StringExtractor only
+ //------------------------------------------------------------------
+ std::string m_packet; // The string in which to extract data.
+ uint64_t m_index; // When extracting data from a packet, this index
+ // will march along as things get extracted. If set
+ // to UINT64_MAX the end of the packet data was
+ // reached when decoding information
+};
+
+#endif // utility_StringExtractor_h_
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
new file mode 100644
index 000000000000..7e06a0f59bc9
--- /dev/null
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -0,0 +1,182 @@
+//===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <string.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "Utility/StringExtractorGDBRemote.h"
+
+
+
+StringExtractorGDBRemote::ResponseType
+StringExtractorGDBRemote::GetResponseType () const
+{
+ if (m_packet.empty())
+ return eUnsupported;
+
+ switch (m_packet[0])
+ {
+ case 'E':
+ if (m_packet.size() == 3 &&
+ isxdigit(m_packet[1]) &&
+ isxdigit(m_packet[2]))
+ return eError;
+ break;
+
+ case 'O':
+ if (m_packet.size() == 2 && m_packet[1] == 'K')
+ return eOK;
+ break;
+
+ case '+':
+ if (m_packet.size() == 1)
+ return eAck;
+ break;
+
+ case '-':
+ if (m_packet.size() == 1)
+ return eNack;
+ break;
+ }
+ return eResponse;
+}
+
+StringExtractorGDBRemote::ServerPacketType
+StringExtractorGDBRemote::GetServerPacketType () const
+{
+#define PACKET_MATCHES(s) ((packet_size == (sizeof(s)-1)) && (strcmp((packet_cstr),(s)) == 0))
+#define PACKET_STARTS_WITH(s) ((packet_size >= (sizeof(s)-1)) && ::strncmp(packet_cstr, s, (sizeof(s)-1))==0)
+
+ // Empty is not a supported packet...
+ if (m_packet.empty())
+ return eServerPacketType_invalid;
+
+ const size_t packet_size = m_packet.size();
+ const char *packet_cstr = m_packet.c_str();
+ switch (m_packet[0])
+ {
+ case '\x03':
+ if (packet_size == 1) return eServerPacketType_interrupt;
+ break;
+
+ case '-':
+ if (packet_size == 1) return eServerPacketType_nack;
+ break;
+
+ case '+':
+ if (packet_size == 1) return eServerPacketType_ack;
+ break;
+
+ case 'A':
+ return eServerPacketType_A;
+
+ case 'Q':
+ switch (packet_cstr[1])
+ {
+ case 'E':
+ if (PACKET_STARTS_WITH ("QEnvironment:")) return eServerPacketType_QEnvironment;
+ break;
+
+ case 'S':
+ if (PACKET_MATCHES ("QStartNoAckMode")) return eServerPacketType_QStartNoAckMode;
+ else if (PACKET_STARTS_WITH ("QSetDisableASLR:")) return eServerPacketType_QSetDisableASLR;
+ else if (PACKET_STARTS_WITH ("QSetSTDIN:")) return eServerPacketType_QSetSTDIN;
+ else if (PACKET_STARTS_WITH ("QSetSTDOUT:")) return eServerPacketType_QSetSTDOUT;
+ else if (PACKET_STARTS_WITH ("QSetSTDERR:")) return eServerPacketType_QSetSTDERR;
+ else if (PACKET_STARTS_WITH ("QSetWorkingDir:")) return eServerPacketType_QSetWorkingDir;
+ break;
+ }
+ break;
+
+ case 'q':
+ switch (packet_cstr[1])
+ {
+ case 's':
+ if (PACKET_MATCHES ("qsProcessInfo")) return eServerPacketType_qsProcessInfo;
+ break;
+
+ case 'f':
+ if (PACKET_STARTS_WITH ("qfProcessInfo")) return eServerPacketType_qfProcessInfo;
+ break;
+
+ case 'C':
+ if (packet_size == 2) return eServerPacketType_qC;
+ break;
+
+ case 'G':
+ if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName;
+ break;
+
+ case 'H':
+ if (PACKET_MATCHES ("qHostInfo")) return eServerPacketType_qHostInfo;
+ break;
+
+ case 'L':
+ if (PACKET_MATCHES ("qLaunchGDBServer")) return eServerPacketType_qLaunchGDBServer;
+ if (PACKET_MATCHES ("qLaunchSuccess")) return eServerPacketType_qLaunchSuccess;
+ break;
+
+ case 'P':
+ if (PACKET_STARTS_WITH ("qProcessInfoPID:")) return eServerPacketType_qProcessInfoPID;
+ break;
+
+ case 'S':
+ if (PACKET_STARTS_WITH ("qSpeedTest:")) return eServerPacketType_qSpeedTest;
+ break;
+
+ case 'U':
+ if (PACKET_STARTS_WITH ("qUserName:")) return eServerPacketType_qUserName;
+ break;
+ }
+ break;
+ }
+ return eServerPacketType_unimplemented;
+}
+
+bool
+StringExtractorGDBRemote::IsOKResponse() const
+{
+ return GetResponseType () == eOK;
+}
+
+
+bool
+StringExtractorGDBRemote::IsUnsupportedResponse() const
+{
+ return GetResponseType () == eUnsupported;
+}
+
+bool
+StringExtractorGDBRemote::IsNormalResponse() const
+{
+ return GetResponseType () == eResponse;
+}
+
+bool
+StringExtractorGDBRemote::IsErrorResponse() const
+{
+ return GetResponseType () == eError &&
+ m_packet.size() == 3 &&
+ isxdigit(m_packet[1]) &&
+ isxdigit(m_packet[2]);
+}
+
+uint8_t
+StringExtractorGDBRemote::GetError ()
+{
+ if (GetResponseType() == eError)
+ {
+ SetFilePos(1);
+ return GetHexU8(255);
+ }
+ return 0;
+}
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
new file mode 100644
index 000000000000..5a24d894b105
--- /dev/null
+++ b/source/Utility/StringExtractorGDBRemote.h
@@ -0,0 +1,103 @@
+//===-- StringExtractorGDBRemote.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_StringExtractorGDBRemote_h_
+#define utility_StringExtractorGDBRemote_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+// Other libraries and framework includes
+// Project includes
+#include "Utility/StringExtractor.h"
+
+class StringExtractorGDBRemote : public StringExtractor
+{
+public:
+
+ StringExtractorGDBRemote() :
+ StringExtractor ()
+ {
+ }
+
+ StringExtractorGDBRemote(const char *cstr) :
+ StringExtractor (cstr)
+ {
+ }
+ StringExtractorGDBRemote(const StringExtractorGDBRemote& rhs) :
+ StringExtractor (rhs)
+ {
+ }
+
+ virtual ~StringExtractorGDBRemote()
+ {
+ }
+
+ enum ServerPacketType
+ {
+ eServerPacketType_nack = 0,
+ eServerPacketType_ack,
+ eServerPacketType_invalid,
+ eServerPacketType_unimplemented,
+ eServerPacketType_interrupt, // CTRL+c packet or "\x03"
+ eServerPacketType_A, // Program arguments packet
+ eServerPacketType_qfProcessInfo,
+ eServerPacketType_qsProcessInfo,
+ eServerPacketType_qC,
+ eServerPacketType_qGroupName,
+ eServerPacketType_qHostInfo,
+ eServerPacketType_qLaunchGDBServer,
+ eServerPacketType_qLaunchSuccess,
+ eServerPacketType_qProcessInfoPID,
+ eServerPacketType_qSpeedTest,
+ eServerPacketType_qUserName,
+ eServerPacketType_QEnvironment,
+ eServerPacketType_QSetDisableASLR,
+ eServerPacketType_QSetSTDIN,
+ eServerPacketType_QSetSTDOUT,
+ eServerPacketType_QSetSTDERR,
+ eServerPacketType_QSetWorkingDir,
+ eServerPacketType_QStartNoAckMode
+ };
+
+ ServerPacketType
+ GetServerPacketType () const;
+
+ enum ResponseType
+ {
+ eUnsupported = 0,
+ eAck,
+ eNack,
+ eError,
+ eOK,
+ eResponse
+ };
+
+ ResponseType
+ GetResponseType () const;
+
+ bool
+ IsOKResponse() const;
+
+ bool
+ IsUnsupportedResponse() const;
+
+ bool
+ IsNormalResponse () const;
+
+ bool
+ IsErrorResponse() const;
+
+ // Returns zero if the packet isn't a EXX packet where XX are two hex
+ // digits. Otherwise the error encoded in XX is returned.
+ uint8_t
+ GetError();
+};
+
+#endif // utility_StringExtractorGDBRemote_h_
diff --git a/source/Utility/TimeSpecTimeout.cpp b/source/Utility/TimeSpecTimeout.cpp
new file mode 100644
index 000000000000..33b3b4e6c391
--- /dev/null
+++ b/source/Utility/TimeSpecTimeout.cpp
@@ -0,0 +1,48 @@
+//===--------------------- TimeSpecTimeout.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TimeSpecTimeout.h"
+
+using namespace lldb_private;
+
+const struct timespec *
+TimeSpecTimeout::SetAbsoluteTimeoutMircoSeconds32 (uint32_t timeout_usec)
+{
+ if (timeout_usec == UINT32_MAX)
+ {
+ m_infinite = true;
+ }
+ else
+ {
+ m_infinite = false;
+ TimeValue time_value(TimeValue::Now());
+ time_value.OffsetWithMicroSeconds(timeout_usec);
+ m_timespec = time_value.GetAsTimeSpec();
+ }
+ return GetTimeSpecPtr ();
+}
+
+const struct timespec *
+TimeSpecTimeout::SetRelativeTimeoutMircoSeconds32 (uint32_t timeout_usec)
+{
+ if (timeout_usec == UINT32_MAX)
+ {
+ m_infinite = true;
+ }
+ else
+ {
+ m_infinite = false;
+ TimeValue time_value;
+ time_value.OffsetWithMicroSeconds(timeout_usec);
+ m_timespec = time_value.GetAsTimeSpec();
+ }
+ return GetTimeSpecPtr ();
+}
+
+
diff --git a/source/Utility/TimeSpecTimeout.h b/source/Utility/TimeSpecTimeout.h
new file mode 100644
index 000000000000..32cdd067658c
--- /dev/null
+++ b/source/Utility/TimeSpecTimeout.h
@@ -0,0 +1,90 @@
+//===--------------------- TimeSpecTimeout.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_TimeSpecTimeout_h_
+#define utility_TimeSpecTimeout_h_
+
+#include "lldb/Host/TimeValue.h"
+
+namespace lldb_private {
+
+class TimeSpecTimeout
+{
+public:
+ TimeSpecTimeout() :
+ m_infinite (false)
+ {
+ m_timespec.tv_sec = 0;
+ m_timespec.tv_nsec = 0;
+ }
+ ~TimeSpecTimeout()
+ {
+ }
+
+ //----------------------------------------------------------------------
+ /// Sets the timespec pointer correctly given a timeout relative to the
+ /// current time. This function should be called immediately prior to
+ /// calling the function you will use this timeout with since time can
+ /// elapse between when this function is called and when the timeout is
+ /// used.
+ ///
+ /// @param[in] timeout_usec
+ /// The timeout in micro seconds. If timeout_usec is UINT32_MAX, the
+ /// timeout should be set to INFINITE. Otherwise the current time is
+ /// filled into the timespec and \a timeout_usec is added to the
+ /// current time.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ SetAbsoluteTimeoutMircoSeconds32 (uint32_t timeout_usec);
+
+ //----------------------------------------------------------------------
+ /// Sets the timespec pointer correctly given a relative time in micro
+ /// seconds.
+ ///
+ /// @param[in] timeout_usec
+ /// The timeout in micro seconds. If timeout_usec is UINT32_MAX, the
+ /// timeout should be set to INFINITE. Otherwise \a timeout_usec
+ /// is correctly placed into the timespec.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ SetRelativeTimeoutMircoSeconds32 (uint32_t timeout_usec);
+
+ //----------------------------------------------------------------------
+ /// Gets the timespec pointer that is appropriate for the timeout
+ /// specified. This function should only be used after a call to
+ /// SetRelativeTimeoutXXX() functions.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ GetTimeSpecPtr () const
+ {
+ if (m_infinite)
+ return NULL;
+ return &m_timespec;
+ }
+
+protected:
+ struct timespec m_timespec;
+ bool m_infinite;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef utility_TimeSpecTimeout_h_
diff --git a/source/Utility/UuidCompatibility.h b/source/Utility/UuidCompatibility.h
new file mode 100644
index 000000000000..df26f77ab52d
--- /dev/null
+++ b/source/Utility/UuidCompatibility.h
@@ -0,0 +1,18 @@
+//===-- UuidCompatibility.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Include this header if your system does not have a definition of uuid_t
+
+#ifndef utility_UUID_COMPATIBILITY_H
+#define utility_UUID_COMPATIBILITY_H
+
+// uuid_t is guaranteed to always be a 16-byte array
+typedef unsigned char uuid_t[16];
+
+#endif // utility_UUID_COMPATIBILITY_H