diff options
Diffstat (limited to 'tools')
43 files changed, 1329 insertions, 989 deletions
diff --git a/tools/Makefile b/tools/Makefile deleted file mode 100644 index 2588d87dc98a..000000000000 --- a/tools/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -##===- source/Makefile -------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := .. -include $(LLDB_LEVEL)/../../Makefile.config - -DIRS := - -# enable lldb-gdbserver for supported platforms -ifneq (,$(strip $(filter $(HOST_OS), FreeBSD Linux NetBSD GNU/kFreeBSD))) -DIRS += lldb-server -endif - -ifeq ($(HOST_OS),Darwin) -DIRS += debugserver -endif - -ifeq ($(ENABLE_WERROR),0) -DIRS += lldb-mi -endif - -DIRS += driver - -include $(LLDB_LEVEL)/Makefile diff --git a/tools/compact-unwind/compact-unwind-dumper.c b/tools/compact-unwind/compact-unwind-dumper.c index d6bd72d93027..f70f602326bf 100644 --- a/tools/compact-unwind/compact-unwind-dumper.c +++ b/tools/compact-unwind/compact-unwind-dumper.c @@ -14,6 +14,50 @@ #include <stdio.h> #include <mach-o/nlist.h> + +enum { + UNWIND_ARM64_MODE_MASK = 0x0F000000, + UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, + UNWIND_ARM64_MODE_DWARF = 0x03000000, + UNWIND_ARM64_MODE_FRAME = 0x04000000, + + UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, + UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, + UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, + UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, + UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, + UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, + UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, + UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, + UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, + + UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, + UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; + +enum { + UNWIND_ARM_MODE_MASK = 0x0F000000, + UNWIND_ARM_MODE_FRAME = 0x01000000, + UNWIND_ARM_MODE_FRAME_D = 0x02000000, + UNWIND_ARM_MODE_DWARF = 0x04000000, + + UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000, + + UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001, + UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002, + UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004, + + UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008, + UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010, + UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020, + UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040, + UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080, + + UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700, + + UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF, +}; + #define EXTRACT_BITS(value, mask) \ ( (value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask)))-1) ) @@ -196,12 +240,14 @@ scan_macho_load_commands (struct baton *baton) if (is_64bit) { struct section_64 sect; + memset (§, 0, sizeof (struct section_64)); memcpy (§, offset, sizeof (struct section_64)); baton->compact_unwind_start = baton->mach_header_start + sect.offset; } else { struct section sect; + memset (§, 0, sizeof (struct section)); memcpy (§, offset, sizeof (struct section)); baton->compact_unwind_start = baton->mach_header_start + sect.offset; } @@ -211,12 +257,14 @@ scan_macho_load_commands (struct baton *baton) if (is_64bit) { struct section_64 sect; + memset (§, 0, sizeof (struct section_64)); memcpy (§, offset, sizeof (struct section_64)); baton->eh_section_file_address = sect.addr; } else { struct section sect; + memset (§, 0, sizeof (struct section)); memcpy (§, offset, sizeof (struct section)); baton->eh_section_file_address = sect.addr; } @@ -226,6 +274,7 @@ scan_macho_load_commands (struct baton *baton) if (is_64bit) { struct section_64 sect; + memset (§, 0, sizeof (struct section_64)); memcpy (§, offset, sizeof (struct section_64)); baton->text_section_vmaddr = sect.addr; baton->text_section_file_offset = sect.offset; @@ -233,6 +282,7 @@ scan_macho_load_commands (struct baton *baton) else { struct section sect; + memset (§, 0, sizeof (struct section)); memcpy (§, offset, sizeof (struct section)); baton->text_section_vmaddr = sect.addr; } @@ -283,6 +333,7 @@ scan_macho_load_commands (struct baton *baton) for (int i = 0; i < local_syms_count; i++) { struct nlist_64 nlist; + memset (&nlist, 0, sizeof (struct nlist_64)); if (is_64bit) { memcpy (&nlist, local_syms + (i * nlist_size), sizeof (struct nlist_64)); @@ -290,6 +341,7 @@ scan_macho_load_commands (struct baton *baton) else { struct nlist nlist_32; + memset (&nlist_32, 0, sizeof (struct nlist)); memcpy (&nlist_32, local_syms + (i * nlist_size), sizeof (struct nlist)); nlist.n_un.n_strx = nlist_32.n_un.n_strx; nlist.n_type = nlist_32.n_type; @@ -304,6 +356,8 @@ scan_macho_load_commands (struct baton *baton) && nlist.n_value != baton->text_segment_vmaddr) { baton->symbols[baton->symbols_count].file_address = nlist.n_value; + if (baton->cputype == CPU_TYPE_ARM) + baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1; baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx; baton->symbols_count++; } @@ -312,6 +366,7 @@ scan_macho_load_commands (struct baton *baton) for (int i = 0; i < exported_syms_count; i++) { struct nlist_64 nlist; + memset (&nlist, 0, sizeof (struct nlist_64)); if (is_64bit) { memcpy (&nlist, exported_syms + (i * nlist_size), sizeof (struct nlist_64)); @@ -333,6 +388,8 @@ scan_macho_load_commands (struct baton *baton) && nlist.n_value != baton->text_segment_vmaddr) { baton->symbols[baton->symbols_count].file_address = nlist.n_value; + if (baton->cputype == CPU_TYPE_ARM) + baton->symbols[baton->symbols_count].file_address = baton->symbols[baton->symbols_count].file_address & ~1; baton->symbols[baton->symbols_count].name = string_table + nlist.n_un.n_strx; baton->symbols_count++; } @@ -388,6 +445,8 @@ scan_macho_load_commands (struct baton *baton) { struct symbol search_key; search_key.file_address = baton->function_start_addresses[i]; + if (baton->cputype == CPU_TYPE_ARM) + search_key.file_address = search_key.file_address & ~1; struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare); if (sym == NULL) unnamed_functions_to_add++; @@ -401,6 +460,8 @@ scan_macho_load_commands (struct baton *baton) { struct symbol search_key; search_key.file_address = baton->function_start_addresses[i]; + if (baton->cputype == CPU_TYPE_ARM) + search_key.file_address = search_key.file_address & ~1; struct symbol *sym = bsearch (&search_key, baton->symbols, baton->symbols_count, sizeof (struct symbol), symbol_compare); if (sym == NULL) { @@ -901,6 +962,282 @@ print_encoding_i386 (struct baton baton, uint8_t *function_start, uint32_t encod } } +void +print_encoding_arm64 (struct baton baton, uint8_t *function_start, uint32_t encoding) +{ + const int wordsize = 8; + int mode = encoding & UNWIND_ARM64_MODE_MASK; + switch (mode) + { + case UNWIND_ARM64_MODE_FRAME: + { + printf ("frame func: CFA is fp+%d ", 16); + printf (" pc=[CFA-8] fp=[CFA-16]"); + int reg_pairs_saved_count = 1; + uint32_t saved_register_bits = encoding & 0xfff; + if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" x19=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" x20=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" x21=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" x22=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" x23=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" x24=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" x25=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" x26=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" x27=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" x28=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" d8=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" d9=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" d10=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" d11=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" d12=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" d13=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) + { + int cfa_offset = reg_pairs_saved_count * -2 * wordsize; + cfa_offset -= wordsize; + printf (" d14=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" d15=[CFA%d]", cfa_offset); + reg_pairs_saved_count++; + } + + } + break; + + case UNWIND_ARM64_MODE_FRAMELESS: + { + uint32_t stack_size = encoding & UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK; + printf ("frameless function: stack size %d ", stack_size * 16); + + } + break; + + case UNWIND_ARM64_MODE_DWARF: + { + uint32_t dwarf_offset = encoding & UNWIND_ARM64_DWARF_SECTION_OFFSET; + printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")", + dwarf_offset, dwarf_offset + baton.eh_section_file_address); + } + break; + + case 0: + { + printf (" no unwind information"); + } + break; + } +} + +void +print_encoding_armv7 (struct baton baton, uint8_t *function_start, uint32_t encoding) +{ + const int wordsize = 4; + int mode = encoding & UNWIND_ARM_MODE_MASK; + switch (mode) + { + case UNWIND_ARM_MODE_FRAME_D: + case UNWIND_ARM_MODE_FRAME: + { + int stack_adjust = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_STACK_ADJUST_MASK) * wordsize; + + printf ("frame func: CFA is fp+%d ", (2 * wordsize) + stack_adjust); + int cfa_offset = -stack_adjust; + + cfa_offset -= wordsize; + printf (" pc=[CFA%d]", cfa_offset); + cfa_offset -= wordsize; + printf (" fp=[CFA%d]", cfa_offset); + + uint32_t saved_register_bits = encoding & 0xff; + if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) + { + cfa_offset -= wordsize; + printf (" r6=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) + { + cfa_offset -= wordsize; + printf (" r5=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) + { + cfa_offset -= wordsize; + printf (" r4=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) + { + cfa_offset -= wordsize; + printf (" r12=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) + { + cfa_offset -= wordsize; + printf (" r11=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) + { + cfa_offset -= wordsize; + printf (" r10=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) + { + cfa_offset -= wordsize; + printf (" r9=[CFA%d]", cfa_offset); + } + if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) + { + cfa_offset -= wordsize; + printf (" r8=[CFA%d]", cfa_offset); + } + + if (mode == UNWIND_ARM_MODE_FRAME_D) + { + uint32_t d_reg_bits = EXTRACT_BITS (encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK); + switch (d_reg_bits) + { + case 0: + // vpush {d8} + cfa_offset -= 8; + printf (" d8=[CFA%d]", cfa_offset); + break; + case 1: + // vpush {d10} + // vpush {d8} + cfa_offset -= 8; + printf (" d10=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d8=[CFA%d]", cfa_offset); + break; + case 2: + // vpush {d12} + // vpush {d10} + // vpush {d8} + cfa_offset -= 8; + printf (" d12=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d10=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d8=[CFA%d]", cfa_offset); + break; + case 3: + // vpush {d14} + // vpush {d12} + // vpush {d10} + // vpush {d8} + cfa_offset -= 8; + printf (" d14=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d12=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d10=[CFA%d]", cfa_offset); + cfa_offset -= 8; + printf (" d8=[CFA%d]", cfa_offset); + break; + case 4: + // vpush {d14} + // vpush {d12} + // sp = (sp - 24) & (-16); + // vst {d8, d9, d10} + printf (" d14, d12, d10, d9, d8"); + break; + case 5: + // vpush {d14} + // sp = (sp - 40) & (-16); + // vst {d8, d9, d10, d11} + // vst {d12} + printf (" d14, d11, d10, d9, d8, d12"); + break; + case 6: + // sp = (sp - 56) & (-16); + // vst {d8, d9, d10, d11} + // vst {d12, d13, d14} + printf (" d11, d10, d9, d8, d14, d13, d12"); + break; + case 7: + // sp = (sp - 64) & (-16); + // vst {d8, d9, d10, d11} + // vst {d12, d13, d14, d15} + printf (" d11, d10, d9, d8, d15, d14, d13, d12"); + break; + } + } + } + break; + + case UNWIND_ARM_MODE_DWARF: + { + uint32_t dwarf_offset = encoding & UNWIND_ARM_DWARF_SECTION_OFFSET; + printf ("DWARF unwind instructions: FDE at offset %d (file address 0x%" PRIx64 ")", + dwarf_offset, dwarf_offset + baton.eh_section_file_address); + } + break; + + case 0: + { + printf (" no unwind information"); + } + break; + } +} + + + void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encoding) { @@ -913,6 +1250,14 @@ void print_encoding (struct baton baton, uint8_t *function_start, uint32_t encod { print_encoding_i386 (baton, function_start, encoding); } + else if (baton.cputype == CPU_TYPE_ARM64) + { + print_encoding_arm64 (baton, function_start, encoding); + } + else if (baton.cputype == CPU_TYPE_ARM) + { + print_encoding_armv7 (baton, function_start, encoding); + } else { printf (" -- unsupported encoding arch -- "); @@ -935,6 +1280,9 @@ print_function_encoding (struct baton baton, uint32_t idx, uint32_t encoding, ui uint64_t file_address = baton.first_level_index_entry.functionOffset + entry_func_offset + baton.text_segment_vmaddr; + if (baton.cputype == CPU_TYPE_ARM) + file_address = file_address & ~1; + printf (" func [%d] offset %d (file addr 0x%" PRIx64 ")%s, encoding is 0x%x", idx, entry_func_offset, file_address, diff --git a/tools/debugserver/Makefile b/tools/debugserver/Makefile deleted file mode 100644 index 0284ea42f407..000000000000 --- a/tools/debugserver/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- tools/debugserver/Makefile --------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../.. - -DIRS := source - -include $(LLDB_LEVEL)/Makefile diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj index 2f7a557bf0b9..295a2bf4fa17 100644 --- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -163,7 +163,7 @@ 26CF99A21142EB7400011AAB /* DNBArchImplX86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArchImplX86_64.cpp; sourceTree = "<group>"; }; 26CF99A31142EB7400011AAB /* DNBArchImplX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNBArchImplX86_64.h; sourceTree = "<group>"; }; 26E6B9DA0D1329010037ECDD /* RNBDefs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBDefs.h; sourceTree = "<group>"; }; - 456F67721AD46CE9002850C2 /* debugserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = debugserver; sourceTree = BUILT_PRODUCTS_DIR; }; + 456F67721AD46CE9002850C2 /* debugserver-nonui */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "debugserver-nonui"; sourceTree = BUILT_PRODUCTS_DIR; }; 4971AE7013D10F4F00649E37 /* HasAVX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasAVX.h; sourceTree = "<group>"; }; 4971AE7113D10F4F00649E37 /* HasAVX.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = HasAVX.s; sourceTree = "<group>"; }; 49F530111331519C008956F6 /* MachRegisterStatesI386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachRegisterStatesI386.h; sourceTree = "<group>"; }; @@ -216,7 +216,7 @@ isa = PBXGroup; children = ( 26CE0594115C31C20022F371 /* debugserver */, - 456F67721AD46CE9002850C2 /* debugserver */, + 456F67721AD46CE9002850C2 /* debugserver-nonui */, ); name = Products; sourceTree = "<group>"; @@ -438,7 +438,7 @@ ); name = "debugserver-mini"; productName = "lldb-debugserver"; - productReference = 456F67721AD46CE9002850C2 /* debugserver */; + productReference = 456F67721AD46CE9002850C2 /* debugserver-nonui */; productType = "com.apple.product-type.tool"; }; /* End PBXNativeTarget section */ @@ -594,7 +594,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -634,7 +634,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -673,7 +673,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -708,7 +708,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -809,7 +809,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -909,7 +909,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -920,7 +920,6 @@ GCC_C_LANGUAGE_STANDARD = c99; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; INSTALL_PATH = /usr/bin; LLDB_COMPRESSION_CFLAGS = ""; "LLDB_COMPRESSION_CFLAGS[sdk=appletvos*]" = "-DHAVE_LIBCOMPRESSION=1"; @@ -1018,7 +1017,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -1037,7 +1036,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - INSTALL_PATH = /usr/bin; + INSTALL_PATH = /usr/local/bin; LLDB_COMPRESSION_CFLAGS = ""; "LLDB_COMPRESSION_CFLAGS[sdk=macosx10.11]" = "-DHAVE_LIBCOMPRESSION=1"; LLDB_COMPRESSION_LDFLAGS = ""; @@ -1055,6 +1054,7 @@ "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -1070,7 +1070,7 @@ "$(LLDB_ENERGY_LFLAGS)", ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; - PRODUCT_NAME = debugserver; + PRODUCT_NAME = "debugserver-nonui"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SDKROOT = macosx.internal; @@ -1097,7 +1097,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -1109,7 +1109,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INSTALL_PATH = /usr/bin; + INSTALL_PATH = /usr/local/bin; LLDB_DEBUGSERVER = 1; LLDB_ENERGY_CFLAGS = ""; "LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY"; @@ -1123,6 +1123,7 @@ "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -1141,7 +1142,7 @@ "$(LLDB_ZLIB_LDFLAGS)", ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; - PRODUCT_NAME = debugserver; + PRODUCT_NAME = "debugserver-nonui"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SDKROOT = macosx.internal; @@ -1165,7 +1166,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -1177,7 +1178,7 @@ GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_PATH = /usr/bin; + INSTALL_PATH = /usr/local/bin; LLDB_DEBUGSERVER = 1; LLDB_ENERGY_CFLAGS = ""; "LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY"; @@ -1187,10 +1188,12 @@ OTHER_CFLAGS = ( "$(LLDB_COMPRESSION_CFLAGS)", "$(LLDB_ZLIB_CFLAGS)", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)"; OTHER_LDFLAGS = ""; @@ -1210,7 +1213,7 @@ "$(LLDB_ZLIB_LDFLAGS)", ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; - PRODUCT_NAME = debugserver; + PRODUCT_NAME = "debugserver-nonui"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SDKROOT = macosx.internal; @@ -1233,7 +1236,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( @@ -1245,8 +1248,8 @@ GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_BUILDANDINTEGRATION; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; HEADER_SEARCH_PATHS = /System/Library/Frameworks/System.framework/PrivateHeaders; - INSTALL_PATH = /usr/bin; - "INSTALL_PATH[sdk=iphoneos*]" = /Developer/usr/bin/; + INSTALL_PATH = /usr/local/bin; + "INSTALL_PATH[sdk=iphoneos*]" = /usr/local/bin; LLDB_DEBUGSERVER = 1; LLDB_ENERGY_CFLAGS = ""; "LLDB_ENERGY_CFLAGS[sdk=macosx*]" = "-DLLDB_ENERGY"; @@ -1256,10 +1259,12 @@ OTHER_CFLAGS = ( "-Wparentheses", "$(LLDB_ENERGY_CFLAGS)", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CFLAGS[sdk=iphoneos*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)"; "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( @@ -1274,7 +1279,7 @@ "$(LLDB_ENERGY_LFLAGS)", ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; - PRODUCT_NAME = debugserver; + PRODUCT_NAME = "debugserver-nonui"; SDKROOT = macosx.internal; SKIP_INSTALL = YES; "SKIP_INSTALL[sdk=iphoneos*]" = NO; @@ -1302,7 +1307,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -1334,7 +1339,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -1440,7 +1445,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -1472,7 +1477,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -1570,7 +1575,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -1582,7 +1587,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INSTALL_PATH = /usr/bin; + INSTALL_PATH = /usr/local/bin; LLDB_DEBUGSERVER = 1; LLDB_ENERGY_CFLAGS = ""; "LLDB_ENERGY_CFLAGS[sdk=macosx.internal]" = "-DLLDB_ENERGY"; @@ -1592,10 +1597,12 @@ OTHER_CFLAGS = ( "-Wparentheses", "$(LLDB_ENERGY_CFLAGS)", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = ( "-Wparentheses", "-DOS_OBJECT_USE_OBJC=0", + "-DDEBUGSERVER_PROGRAM_SYMBOL=debugserver_nonui", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)"; "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = ( @@ -1610,7 +1617,7 @@ "$(LLDB_ENERGY_LFLAGS)", ); OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)"; - PRODUCT_NAME = debugserver; + PRODUCT_NAME = "debugserver-nonui"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; "PROVISIONING_PROFILE[sdk=macosx*]" = ""; SDKROOT = macosx.internal; @@ -1626,14 +1633,14 @@ 94BA9B361B1A7C5700035A23 /* CustomSwift-Debug */ = { isa = XCBuildConfiguration; buildSettings = { - PRODUCT_NAME = "lldb-debugserver"; + PRODUCT_NAME = "lldb-debugserver-nonui"; }; name = "CustomSwift-Debug"; }; 94BA9B371B1A7C5700035A23 /* CustomSwift-Release */ = { isa = XCBuildConfiguration; buildSettings = { - PRODUCT_NAME = "lldb-debugserver"; + PRODUCT_NAME = "lldb-debugserver-nonui"; }; name = "CustomSwift-Release"; }; @@ -1655,7 +1662,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -1687,7 +1694,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( "$(SDKROOT)/System/Library/PrivateFrameworks", @@ -1782,7 +1789,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEAD_CODE_STRIPPING = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -1816,7 +1823,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 350.99.0; + CURRENT_PROJECT_VERSION = 360.99.0; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks; "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = ( diff --git a/tools/debugserver/source/DNB.cpp b/tools/debugserver/source/DNB.cpp index 03c85df441de..bb3603649199 100644 --- a/tools/debugserver/source/DNB.cpp +++ b/tools/debugserver/source/DNB.cpp @@ -360,21 +360,13 @@ DNBProcessLaunch (const char *path, char *err_str, size_t err_len) { - DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = %llu) called...", - __FUNCTION__, - path, - argv, - envp, - working_directory, - stdin_path, - stdout_path, - stderr_path, - no_stdio, - launch_flavor, - disable_aslr, - err_str, - (uint64_t)err_len); - + DNBLogThreadedIf(LOG_PROCESS, "%s ( path='%s', argv = %p, envp = %p, working_dir=%s, stdin=%s, stdout=%s, " + "stderr=%s, no-stdio=%i, launch_flavor = %u, disable_aslr = %d, err = %p, err_len = " + "%llu) called...", + __FUNCTION__, path, static_cast<void *>(argv), static_cast<void *>(envp), working_directory, + stdin_path, stdout_path, stderr_path, no_stdio, launch_flavor, disable_aslr, + static_cast<void *>(err_str), static_cast<uint64_t>(err_len)); + if (err_str && err_len > 0) err_str[0] = '\0'; struct stat path_stat; @@ -548,7 +540,6 @@ DNBProcessAttach (nub_process_t attach_pid, struct timespec *timeout, char *err_ switch (pid_state) { - default: case eStateInvalid: case eStateUnloaded: case eStateAttaching: @@ -1092,6 +1083,39 @@ DNBGetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_addr return JSONGenerator::ObjectSP(); } +JSONGenerator::ObjectSP +DNBGetAllLoadedLibrariesInfos (nub_process_t pid) +{ + MachProcessSP procSP; + if (GetProcessSP (pid, procSP)) + { + return procSP->GetAllLoadedLibrariesInfos (pid); + } + return JSONGenerator::ObjectSP(); +} + +JSONGenerator::ObjectSP +DNBGetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses) +{ + MachProcessSP procSP; + if (GetProcessSP (pid, procSP)) + { + return procSP->GetLibrariesInfoForAddresses (pid, macho_addresses); + } + return JSONGenerator::ObjectSP(); +} + +JSONGenerator::ObjectSP +DNBGetSharedCacheInfo (nub_process_t pid) +{ + MachProcessSP procSP; + if (GetProcessSP (pid, procSP)) + { + return procSP->GetSharedCacheInfo (pid); + } + return JSONGenerator::ObjectSP(); +} + const char * diff --git a/tools/debugserver/source/DNB.h b/tools/debugserver/source/DNB.h index 7b186d38b32a..fbaf5e348133 100644 --- a/tools/debugserver/source/DNB.h +++ b/tools/debugserver/source/DNB.h @@ -144,6 +144,10 @@ nub_addr_t DNBGetPThreadT (nub_process_t pid, nub_thread_t nub_addr_t DNBGetDispatchQueueT (nub_process_t pid, nub_thread_t tid); nub_addr_t DNBGetTSDAddressForThread (nub_process_t pid, nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size); JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count); +JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos (nub_process_t pid); +JSONGenerator::ObjectSP DNBGetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses); +JSONGenerator::ObjectSP DNBGetSharedCacheInfo (nub_process_t pid); + // //---------------------------------------------------------------------- // Breakpoint functions diff --git a/tools/debugserver/source/DNBDataRef.cpp b/tools/debugserver/source/DNBDataRef.cpp index 53e9881dfb94..d52f28ee2fb9 100644 --- a/tools/debugserver/source/DNBDataRef.cpp +++ b/tools/debugserver/source/DNBDataRef.cpp @@ -250,7 +250,7 @@ DNBDataRef::Get_ULEB128 (offset_t *offset_ptr) const { bytecount++; byte = *src++; - result |= (byte & 0x7f) << shift; + result |= (uint64_t)(byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) break; @@ -283,7 +283,7 @@ DNBDataRef::Get_SLEB128 (offset_t *offset_ptr) const { bytecount++; byte = *src++; - result |= (byte & 0x7f) << shift; + result |= (int64_t)(byte & 0x7f) << shift; shift += 7; if ((byte & 0x80) == 0) break; @@ -362,7 +362,6 @@ DNBDataRef::Dump // the snprintf call each time through this loop switch (type) { - default: case TypeUInt8: str_offset += snprintf(str + str_offset, sizeof(str) - str_offset, format ? format : " %2.2x", Get8(&offset)); break; case TypeChar: { diff --git a/tools/debugserver/source/MacOSX/CMakeLists.txt b/tools/debugserver/source/MacOSX/CMakeLists.txt index d319cb7b0bab..96cff0a22fc4 100644 --- a/tools/debugserver/source/MacOSX/CMakeLists.txt +++ b/tools/debugserver/source/MacOSX/CMakeLists.txt @@ -59,29 +59,31 @@ set_source_files_properties( target_link_libraries(debugserver ${DEBUGSERVER_USED_LIBS}) -# Sign the debugserver binary -set (CODESIGN_IDENTITY lldb_codesign) -execute_process( - COMMAND xcrun -f codesign_allocate - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE CODESIGN_ALLOCATE - ) -# Older cmake versions don't support "-E env". -if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.2) - add_custom_command(TARGET debugserver - POST_BUILD - # Note: --entitlements option removed, as it causes errors when debugging. - # was: COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/../debugserver-entitlements.plist --force --sign ${CODESIGN_IDENTITY} debugserver - COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${CODESIGN_IDENTITY} debugserver - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) -else() - add_custom_command(TARGET debugserver - POST_BUILD - # Note: --entitlements option removed (see comment above). - COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${CODESIGN_IDENTITY} debugserver - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin - ) +set(LLDB_CODESIGN_IDENTITY "lldb_codesign" + CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.") +if (NOT ("${LLDB_CODESIGN_IDENTITY}" STREQUAL "")) + execute_process( + COMMAND xcrun -f codesign_allocate + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE CODESIGN_ALLOCATE + ) + # Older cmake versions don't support "-E env". + if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.2) + add_custom_command(TARGET debugserver + POST_BUILD + # Note: --entitlements option removed, as it causes errors when debugging. + # was: COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --entitlements ${CMAKE_CURRENT_SOURCE_DIR}/../debugserver-entitlements.plist --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver + COMMAND CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) + else() + add_custom_command(TARGET debugserver + POST_BUILD + # Note: --entitlements option removed (see comment above). + COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} codesign --force --sign ${LLDB_CODESIGN_IDENTITY} debugserver + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin + ) + endif() endif() install(TARGETS debugserver diff --git a/tools/debugserver/source/MacOSX/MachException.cpp b/tools/debugserver/source/MacOSX/MachException.cpp index b7245796ae4c..0b5459e3a189 100644 --- a/tools/debugserver/source/MacOSX/MachException.cpp +++ b/tools/debugserver/source/MacOSX/MachException.cpp @@ -436,7 +436,6 @@ MachException::Message::Reply(MachProcess *process, int signal) if (state.task_port == process->Task().TaskPort()) { DNBLogThreaded("error: mach_msg() returned an error when replying to a mach exception: error = %u", err.Error()); - abort (); } else { diff --git a/tools/debugserver/source/MacOSX/MachProcess.h b/tools/debugserver/source/MacOSX/MachProcess.h index 3be0b2dbabb3..094c13b8f0a8 100644 --- a/tools/debugserver/source/MacOSX/MachProcess.h +++ b/tools/debugserver/source/MacOSX/MachProcess.h @@ -15,8 +15,10 @@ #define __MachProcess_h__ #include <mach/mach.h> +#include <mach-o/loader.h> #include <sys/signal.h> #include <pthread.h> +#include <uuid/uuid.h> #include <vector> #include <CoreFoundation/CoreFoundation.h> @@ -46,6 +48,45 @@ public: MachProcess (); ~MachProcess (); + // A structure that can hold everything debugserver needs to know from + // a binary's Mach-O header / load commands. + + struct mach_o_segment + { + std::string name; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint64_t maxprot; + uint64_t initprot; + uint64_t nsects; + uint64_t flags; + }; + + struct mach_o_information + { + struct mach_header_64 mach_header; + std::vector<struct mach_o_segment> segments; + uuid_t uuid; + std::string min_version_os_name; + std::string min_version_os_version; + }; + + struct binary_image_information + { + std::string filename; + uint64_t load_address; + uint64_t mod_date; // may not be available - 0 if so + struct mach_o_information macho_info; + + binary_image_information () : + filename (), + load_address (INVALID_NUB_ADDRESS), + mod_date (0) + { } + }; + //---------------------------------------------------------------------- // Child process control //---------------------------------------------------------------------- @@ -193,7 +234,15 @@ public: nub_addr_t GetPThreadT (nub_thread_t tid); nub_addr_t GetDispatchQueueT (nub_thread_t tid); nub_addr_t GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_base_address_offset, uint64_t plo_pthread_tsd_base_offset, uint64_t plo_pthread_tsd_entry_size); + + + bool GetMachOInformationFromMemory (nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf); + JSONGenerator::ObjectSP FormatDynamicLibrariesIntoJSON (const std::vector<struct binary_image_information> &image_infos); + void GetAllLoadedBinariesViaDYLDSPI (std::vector<struct binary_image_information> &image_infos); JSONGenerator::ObjectSP GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count); + JSONGenerator::ObjectSP GetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses); + JSONGenerator::ObjectSP GetAllLoadedLibrariesInfos (nub_process_t pid); + JSONGenerator::ObjectSP GetSharedCacheInfo (nub_process_t pid); nub_size_t GetNumThreads () const; nub_thread_t GetThreadAtIndex (nub_size_t thread_idx) const; @@ -358,6 +407,11 @@ private: // as the sole reason for the process being stopped, we can auto resume // the process. bool m_did_exec; + + void * (*m_dyld_process_info_create) (task_t task, uint64_t timestamp, kern_return_t* kernelError); + void (*m_dyld_process_info_for_each_image) (void* info, void (^callback)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path)); + void (*m_dyld_process_info_release) (void* info); + void (*m_dyld_process_info_get_cache) (void* info, void* cacheInfo); }; diff --git a/tools/debugserver/source/MacOSX/MachProcess.mm b/tools/debugserver/source/MacOSX/MachProcess.mm index b9e06307a4aa..ab0039edd88f 100644 --- a/tools/debugserver/source/MacOSX/MachProcess.mm +++ b/tools/debugserver/source/MacOSX/MachProcess.mm @@ -12,8 +12,10 @@ //===----------------------------------------------------------------------===// #include "DNB.h" +#include <dlfcn.h> #include <inttypes.h> #include <mach/mach.h> +#include <mach/task.h> #include <signal.h> #include <spawn.h> #include <sys/fcntl.h> @@ -417,8 +419,17 @@ MachProcess::MachProcess() : m_image_infos_baton(NULL), m_sent_interrupt_signo (0), m_auto_resume_signo (0), - m_did_exec (false) + m_did_exec (false), + m_dyld_process_info_create (nullptr), + m_dyld_process_info_for_each_image (nullptr), + m_dyld_process_info_release (nullptr), + m_dyld_process_info_get_cache (nullptr) { + m_dyld_process_info_create = (void * (*) (task_t task, uint64_t timestamp, kern_return_t* kernelError)) dlsym (RTLD_DEFAULT, "_dyld_process_info_create"); + m_dyld_process_info_for_each_image = (void (*)(void *info, void (^)(uint64_t machHeaderAddress, const uuid_t uuid, const char* path))) dlsym (RTLD_DEFAULT, "_dyld_process_info_for_each_image"); + m_dyld_process_info_release = (void (*) (void* info)) dlsym (RTLD_DEFAULT, "_dyld_process_info_release"); + m_dyld_process_info_get_cache = (void (*) (void* info, void* cacheInfo)) dlsym (RTLD_DEFAULT, "_dyld_process_info_get_cache"); + DNBLogThreadedIf(LOG_PROCESS | LOG_VERBOSE, "%s", __PRETTY_FUNCTION__); } @@ -520,8 +531,232 @@ MachProcess::GetTSDAddressForThread (nub_thread_t tid, uint64_t plo_pthread_tsd_ return m_thread_list.GetTSDAddressForThread (tid, plo_pthread_tsd_base_address_offset, plo_pthread_tsd_base_offset, plo_pthread_tsd_entry_size); } +// Given an address, read the mach-o header and load commands out of memory to fill in +// the mach_o_information "inf" object. +// +// Returns false if there was an error in reading this mach-o file header/load commands. + +bool +MachProcess::GetMachOInformationFromMemory (nub_addr_t mach_o_header_addr, int wordsize, struct mach_o_information &inf) +{ + uint64_t load_cmds_p; + if (wordsize == 4) + { + struct mach_header header; + if (ReadMemory (mach_o_header_addr, sizeof (struct mach_header), &header) != sizeof (struct mach_header)) + { + return false; + } + load_cmds_p = mach_o_header_addr + sizeof (struct mach_header); + inf.mach_header.magic = header.magic; + inf.mach_header.cputype = header.cputype; + // high byte of cpusubtype is used for "capability bits", v. CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h + inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff; + inf.mach_header.filetype = header.filetype; + inf.mach_header.ncmds = header.ncmds; + inf.mach_header.sizeofcmds = header.sizeofcmds; + inf.mach_header.flags = header.flags; + } + else + { + struct mach_header_64 header; + if (ReadMemory (mach_o_header_addr, sizeof (struct mach_header_64), &header) != sizeof (struct mach_header_64)) + { + return false; + } + load_cmds_p = mach_o_header_addr + sizeof (struct mach_header_64); + inf.mach_header.magic = header.magic; + inf.mach_header.cputype = header.cputype; + // high byte of cpusubtype is used for "capability bits", v. CPU_SUBTYPE_MASK, CPU_SUBTYPE_LIB64 in machine.h + inf.mach_header.cpusubtype = header.cpusubtype & 0x00ffffff; + inf.mach_header.filetype = header.filetype; + inf.mach_header.ncmds = header.ncmds; + inf.mach_header.sizeofcmds = header.sizeofcmds; + inf.mach_header.flags = header.flags; + } + for (uint32_t j = 0; j < inf.mach_header.ncmds; j++) + { + struct load_command lc; + if (ReadMemory (load_cmds_p, sizeof (struct load_command), &lc) != sizeof (struct load_command)) + { + return false; + } + if (lc.cmd == LC_SEGMENT) + { + struct segment_command seg; + if (ReadMemory (load_cmds_p, sizeof (struct segment_command), &seg) != sizeof (struct segment_command)) + { + return false; + } + struct mach_o_segment this_seg; + char name[17]; + ::memset (name, 0, sizeof (name)); + memcpy (name, seg.segname, sizeof (seg.segname)); + this_seg.name = name; + this_seg.vmaddr = seg.vmaddr; + this_seg.vmsize = seg.vmsize; + this_seg.fileoff = seg.fileoff; + this_seg.filesize = seg.filesize; + this_seg.maxprot = seg.maxprot; + this_seg.initprot = seg.initprot; + this_seg.nsects = seg.nsects; + this_seg.flags = seg.flags; + inf.segments.push_back(this_seg); + } + if (lc.cmd == LC_SEGMENT_64) + { + struct segment_command_64 seg; + if (ReadMemory (load_cmds_p, sizeof (struct segment_command_64), &seg) != sizeof (struct segment_command_64)) + { + return false; + } + struct mach_o_segment this_seg; + char name[17]; + ::memset (name, 0, sizeof (name)); + memcpy (name, seg.segname, sizeof (seg.segname)); + this_seg.name = name; + this_seg.vmaddr = seg.vmaddr; + this_seg.vmsize = seg.vmsize; + this_seg.fileoff = seg.fileoff; + this_seg.filesize = seg.filesize; + this_seg.maxprot = seg.maxprot; + this_seg.initprot = seg.initprot; + this_seg.nsects = seg.nsects; + this_seg.flags = seg.flags; + inf.segments.push_back(this_seg); + } + if (lc.cmd == LC_UUID) + { + struct uuid_command uuidcmd; + if (ReadMemory (load_cmds_p, sizeof (struct uuid_command), &uuidcmd) == sizeof (struct uuid_command)) + uuid_copy (inf.uuid, uuidcmd.uuid); + } + bool lc_cmd_known = lc.cmd == LC_VERSION_MIN_IPHONEOS || lc.cmd == LC_VERSION_MIN_MACOSX; +#if defined(LC_VERSION_MIN_TVOS) + lc_cmd_known |= lc.cmd == LC_VERSION_MIN_TVOS; +#endif +#if defined(LC_VERSION_MIN_WATCHOS) + lc_cmd_known |= lc.cmd == LC_VERSION_MIN_WATCHOS; +#endif + if (lc_cmd_known) + { + struct version_min_command vers_cmd; + if (ReadMemory (load_cmds_p, sizeof (struct version_min_command), &vers_cmd) != sizeof (struct version_min_command)) + { + return false; + } + switch (lc.cmd) + { + case LC_VERSION_MIN_IPHONEOS: + inf.min_version_os_name = "iphoneos"; + break; + case LC_VERSION_MIN_MACOSX: + inf.min_version_os_name = "macosx"; + break; +#if defined(LC_VERSION_MIN_TVOS) + case LC_VERSION_MIN_TVOS: + inf.min_version_os_name = "tvos"; + break; +#endif +#if defined(LC_VERSION_MIN_WATCHOS) + case LC_VERSION_MIN_WATCHOS: + inf.min_version_os_name = "watchos"; + break; +#endif + default: + return false; + } + uint32_t xxxx = vers_cmd.sdk >> 16; + uint32_t yy = (vers_cmd.sdk >> 8) & 0xffu; + uint32_t zz = vers_cmd.sdk & 0xffu; + inf.min_version_os_version = ""; + inf.min_version_os_version += std::to_string(xxxx); + inf.min_version_os_version += "."; + inf.min_version_os_version += std::to_string(yy); + if (zz != 0) + { + inf.min_version_os_version += "."; + inf.min_version_os_version += std::to_string(zz); + } + } + load_cmds_p += lc.cmdsize; + } + return true; +} + +// Given completely filled in array of binary_image_information structures, create a JSONGenerator object +// with all the details we want to send to lldb. +JSONGenerator::ObjectSP +MachProcess::FormatDynamicLibrariesIntoJSON (const std::vector<struct binary_image_information> &image_infos) +{ + + JSONGenerator::ArraySP image_infos_array_sp (new JSONGenerator::Array()); + + const size_t image_count = image_infos.size(); + + for (size_t i = 0; i < image_count; i++) + { + JSONGenerator::DictionarySP image_info_dict_sp (new JSONGenerator::Dictionary()); + image_info_dict_sp->AddIntegerItem ("load_address", image_infos[i].load_address); + image_info_dict_sp->AddIntegerItem ("mod_date", image_infos[i].mod_date); + image_info_dict_sp->AddStringItem ("pathname", image_infos[i].filename); + + uuid_string_t uuidstr; + uuid_unparse_upper (image_infos[i].macho_info.uuid, uuidstr); + image_info_dict_sp->AddStringItem ("uuid", uuidstr); + + if (image_infos[i].macho_info.min_version_os_name.empty() == false + && image_infos[i].macho_info.min_version_os_version.empty() == false) + { + image_info_dict_sp->AddStringItem ("min_version_os_name", image_infos[i].macho_info.min_version_os_name); + image_info_dict_sp->AddStringItem ("min_version_os_sdk", image_infos[i].macho_info.min_version_os_version); + } + + JSONGenerator::DictionarySP mach_header_dict_sp (new JSONGenerator::Dictionary()); + mach_header_dict_sp->AddIntegerItem ("magic", image_infos[i].macho_info.mach_header.magic); + mach_header_dict_sp->AddIntegerItem ("cputype", (uint32_t) image_infos[i].macho_info.mach_header.cputype); + mach_header_dict_sp->AddIntegerItem ("cpusubtype", (uint32_t) image_infos[i].macho_info.mach_header.cpusubtype); + mach_header_dict_sp->AddIntegerItem ("filetype", image_infos[i].macho_info.mach_header.filetype); + +// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them. +// mach_header_dict_sp->AddIntegerItem ("ncmds", image_infos[i].macho_info.mach_header.ncmds); +// mach_header_dict_sp->AddIntegerItem ("sizeofcmds", image_infos[i].macho_info.mach_header.sizeofcmds); +// mach_header_dict_sp->AddIntegerItem ("flags", image_infos[i].macho_info.mach_header.flags); + image_info_dict_sp->AddItem ("mach_header", mach_header_dict_sp); + + JSONGenerator::ArraySP segments_sp (new JSONGenerator::Array()); + for (size_t j = 0; j < image_infos[i].macho_info.segments.size(); j++) + { + JSONGenerator::DictionarySP segment_sp (new JSONGenerator::Dictionary()); + segment_sp->AddStringItem ("name", image_infos[i].macho_info.segments[j].name); + segment_sp->AddIntegerItem ("vmaddr", image_infos[i].macho_info.segments[j].vmaddr); + segment_sp->AddIntegerItem ("vmsize", image_infos[i].macho_info.segments[j].vmsize); + segment_sp->AddIntegerItem ("fileoff", image_infos[i].macho_info.segments[j].fileoff); + segment_sp->AddIntegerItem ("filesize", image_infos[i].macho_info.segments[j].filesize); + segment_sp->AddIntegerItem ("maxprot", image_infos[i].macho_info.segments[j].maxprot); + +// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them. +// segment_sp->AddIntegerItem ("initprot", image_infos[i].macho_info.segments[j].initprot); +// segment_sp->AddIntegerItem ("nsects", image_infos[i].macho_info.segments[j].nsects); +// segment_sp->AddIntegerItem ("flags", image_infos[i].macho_info.segments[j].flags); + segments_sp->AddItem (segment_sp); + } + image_info_dict_sp->AddItem ("segments", segments_sp); + + image_infos_array_sp->AddItem (image_info_dict_sp); + } + JSONGenerator::DictionarySP reply_sp (new JSONGenerator::Dictionary());; + reply_sp->AddItem ("images", image_infos_array_sp); + return reply_sp; +} + +// Get the shared library information using the old (pre-macOS 10.12, pre-iOS 10, pre-tvOS 10, pre-watchOS 3) +// code path. We'll be given the address of an array of structures in the form +// {void* load_addr, void* mod_date, void* pathname} +// +// In macOS 10.12 etc and newer, we'll use SPI calls into dyld to gather this information. JSONGenerator::ObjectSP MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count) { @@ -536,29 +771,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image if (processInfo.kp_proc.p_flag & P_LP64) pointer_size = 8; - struct segment - { - std::string name; - uint64_t vmaddr; - uint64_t vmsize; - uint64_t fileoff; - uint64_t filesize; - uint64_t maxprot; - uint64_t initprot; - uint64_t nsects; - uint64_t flags; - }; - - struct image_info - { - uint64_t load_address; - std::string pathname; - uint64_t mod_date; - struct mach_header_64 mach_header; - std::vector<struct segment> segments; - uuid_t uuid; - }; - std::vector<image_info> image_infos; + std::vector<struct binary_image_information> image_infos; size_t image_infos_size = image_count * 3 * pointer_size; uint8_t *image_info_buf = (uint8_t *) malloc (image_infos_size); @@ -577,7 +790,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image for (size_t i = 0; i < image_count; i++) { - struct image_info info; + struct binary_image_information info; nub_addr_t pathname_address; if (pointer_size == 4) { @@ -604,13 +817,13 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image pathname_address = pathname_address_64; } char strbuf[17]; - info.pathname = ""; + info.filename = ""; uint64_t pathname_ptr = pathname_address; bool still_reading = true; while (still_reading && ReadMemory (pathname_ptr, sizeof (strbuf) - 1, strbuf) == sizeof (strbuf) - 1) { strbuf[sizeof(strbuf) - 1] = '\0'; - info.pathname += strbuf; + info.filename += strbuf; pathname_ptr += sizeof (strbuf) - 1; // Stop if we found nul byte indicating the end of the string for (size_t i = 0; i < sizeof(strbuf) - 1; i++) @@ -622,7 +835,7 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image } } } - uuid_clear (info.uuid); + uuid_clear (info.macho_info.uuid); image_infos.push_back (info); } if (image_infos.size() == 0) @@ -630,157 +843,161 @@ MachProcess::GetLoadedDynamicLibrariesInfos (nub_process_t pid, nub_addr_t image return reply_sp; } + free (image_info_buf); //// Second, read the mach header / load commands for all the dylibs - for (size_t i = 0; i < image_count; i++) { - uint64_t load_cmds_p; - if (pointer_size == 4) - { - struct mach_header header; - if (ReadMemory (image_infos[i].load_address, sizeof (struct mach_header), &header) != sizeof (struct mach_header)) - { - return reply_sp; - } - load_cmds_p = image_infos[i].load_address + sizeof (struct mach_header); - image_infos[i].mach_header.magic = header.magic; - image_infos[i].mach_header.cputype = header.cputype; - image_infos[i].mach_header.cpusubtype = header.cpusubtype; - image_infos[i].mach_header.filetype = header.filetype; - image_infos[i].mach_header.ncmds = header.ncmds; - image_infos[i].mach_header.sizeofcmds = header.sizeofcmds; - image_infos[i].mach_header.flags = header.flags; - } - else - { - struct mach_header_64 header; - if (ReadMemory (image_infos[i].load_address, sizeof (struct mach_header_64), &header) != sizeof (struct mach_header_64)) - { - return reply_sp; - } - load_cmds_p = image_infos[i].load_address + sizeof (struct mach_header_64); - image_infos[i].mach_header.magic = header.magic; - image_infos[i].mach_header.cputype = header.cputype; - image_infos[i].mach_header.cpusubtype = header.cpusubtype; - image_infos[i].mach_header.filetype = header.filetype; - image_infos[i].mach_header.ncmds = header.ncmds; - image_infos[i].mach_header.sizeofcmds = header.sizeofcmds; - image_infos[i].mach_header.flags = header.flags; - } - for (uint32_t j = 0; j < image_infos[i].mach_header.ncmds; j++) + if (!GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info)) { - struct load_command lc; - if (ReadMemory (load_cmds_p, sizeof (struct load_command), &lc) != sizeof (struct load_command)) - { - return reply_sp; - } - if (lc.cmd == LC_SEGMENT) - { - struct segment_command seg; - if (ReadMemory (load_cmds_p, sizeof (struct segment_command), &seg) != sizeof (struct segment_command)) - { - return reply_sp; - } - struct segment this_seg; - char name[17]; - ::memset (name, 0, sizeof (name)); - memcpy (name, seg.segname, sizeof (seg.segname)); - this_seg.name = name; - this_seg.vmaddr = seg.vmaddr; - this_seg.vmsize = seg.vmsize; - this_seg.fileoff = seg.fileoff; - this_seg.filesize = seg.filesize; - this_seg.maxprot = seg.maxprot; - this_seg.initprot = seg.initprot; - this_seg.nsects = seg.nsects; - this_seg.flags = seg.flags; - image_infos[i].segments.push_back(this_seg); - } - if (lc.cmd == LC_SEGMENT_64) - { - struct segment_command_64 seg; - if (ReadMemory (load_cmds_p, sizeof (struct segment_command_64), &seg) != sizeof (struct segment_command_64)) - { - return reply_sp; - } - struct segment this_seg; - char name[17]; - ::memset (name, 0, sizeof (name)); - memcpy (name, seg.segname, sizeof (seg.segname)); - this_seg.name = name; - this_seg.vmaddr = seg.vmaddr; - this_seg.vmsize = seg.vmsize; - this_seg.fileoff = seg.fileoff; - this_seg.filesize = seg.filesize; - this_seg.maxprot = seg.maxprot; - this_seg.initprot = seg.initprot; - this_seg.nsects = seg.nsects; - this_seg.flags = seg.flags; - image_infos[i].segments.push_back(this_seg); - } - if (lc.cmd == LC_UUID) - { - struct uuid_command uuidcmd; - if (ReadMemory (load_cmds_p, sizeof (struct uuid_command), &uuidcmd) == sizeof (struct uuid_command)) - uuid_copy (image_infos[i].uuid, uuidcmd.uuid); - } - load_cmds_p += lc.cmdsize; + return reply_sp; } } - //// Thrid, format all of the above in the JSONGenerator object. + //// Third, format all of the above in the JSONGenerator object. - JSONGenerator::ArraySP image_infos_array_sp (new JSONGenerator::Array()); + return FormatDynamicLibrariesIntoJSON (image_infos); + } + + return reply_sp; +} + +// From dyld SPI header dyld_process_info.h +typedef void* dyld_process_info; +struct dyld_process_cache_info +{ + uuid_t cacheUUID; // UUID of cache used by process + uint64_t cacheBaseAddress; // load address of dyld shared cache + bool noCache; // process is running without a dyld cache + bool privateCache; // process is using a private copy of its dyld cache +}; + + +// Use the dyld SPI present in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer to get +// the load address, uuid, and filenames of all the libraries. +// This only fills in those three fields in the 'struct binary_image_information' - call +// GetMachOInformationFromMemory to fill in the mach-o header/load command details. +void +MachProcess::GetAllLoadedBinariesViaDYLDSPI (std::vector<struct binary_image_information> &image_infos) +{ + kern_return_t kern_ret; + if (m_dyld_process_info_create) + { + dyld_process_info info = m_dyld_process_info_create (m_task.TaskPort(), 0, &kern_ret); + if (info) + { + m_dyld_process_info_for_each_image (info, ^(uint64_t mach_header_addr, const uuid_t uuid, const char *path) { + struct binary_image_information image; + image.filename = path; + uuid_copy (image.macho_info.uuid, uuid); + image.load_address = mach_header_addr; + image_infos.push_back (image); + }); + m_dyld_process_info_release (info); + } + } +} + +// Fetch information about all shared libraries using the dyld SPIs that exist in +// macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer. +JSONGenerator::ObjectSP +MachProcess::GetAllLoadedLibrariesInfos (nub_process_t pid) +{ + JSONGenerator::DictionarySP reply_sp; + + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0) + { + uint32_t pointer_size = 4; + if (processInfo.kp_proc.p_flag & P_LP64) + pointer_size = 8; + + std::vector<struct binary_image_information> image_infos; + GetAllLoadedBinariesViaDYLDSPI (image_infos); + const size_t image_count = image_infos.size(); for (size_t i = 0; i < image_count; i++) { - JSONGenerator::DictionarySP image_info_dict_sp (new JSONGenerator::Dictionary()); - image_info_dict_sp->AddIntegerItem ("load_address", image_infos[i].load_address); - image_info_dict_sp->AddIntegerItem ("mod_date", image_infos[i].mod_date); - image_info_dict_sp->AddStringItem ("pathname", image_infos[i].pathname); + GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info); + } + return FormatDynamicLibrariesIntoJSON (image_infos); + } + return reply_sp; +} - uuid_string_t uuidstr; - uuid_unparse_upper (image_infos[i].uuid, uuidstr); - image_info_dict_sp->AddStringItem ("uuid", uuidstr); +// Fetch information about the shared libraries at the given load addresses using the +// dyld SPIs that exist in macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer. +JSONGenerator::ObjectSP +MachProcess::GetLibrariesInfoForAddresses (nub_process_t pid, std::vector<uint64_t> &macho_addresses) +{ + JSONGenerator::DictionarySP reply_sp; - JSONGenerator::DictionarySP mach_header_dict_sp (new JSONGenerator::Dictionary()); - mach_header_dict_sp->AddIntegerItem ("magic", image_infos[i].mach_header.magic); - mach_header_dict_sp->AddIntegerItem ("cputype", image_infos[i].mach_header.cputype); - mach_header_dict_sp->AddIntegerItem ("cpusubtype", image_infos[i].mach_header.cpusubtype); - mach_header_dict_sp->AddIntegerItem ("filetype", image_infos[i].mach_header.filetype); + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; + struct kinfo_proc processInfo; + size_t bufsize = sizeof(processInfo); + if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, 0) == 0 && bufsize > 0) + { + uint32_t pointer_size = 4; + if (processInfo.kp_proc.p_flag & P_LP64) + pointer_size = 8; -// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them. -// mach_header_dict_sp->AddIntegerItem ("ncmds", image_infos[i].mach_header.ncmds); -// mach_header_dict_sp->AddIntegerItem ("sizeofcmds", image_infos[i].mach_header.sizeofcmds); -// mach_header_dict_sp->AddIntegerItem ("flags", image_infos[i].mach_header.flags); - image_info_dict_sp->AddItem ("mach_header", mach_header_dict_sp); + std::vector<struct binary_image_information> all_image_infos; + GetAllLoadedBinariesViaDYLDSPI (all_image_infos); - JSONGenerator::ArraySP segments_sp (new JSONGenerator::Array()); - for (size_t j = 0; j < image_infos[i].segments.size(); j++) + std::vector<struct binary_image_information> image_infos; + const size_t macho_addresses_count = macho_addresses.size(); + const size_t all_image_infos_count = all_image_infos.size(); + for (size_t i = 0; i < macho_addresses_count; i++) + { + for (size_t j = 0; j < all_image_infos_count; j++) { - JSONGenerator::DictionarySP segment_sp (new JSONGenerator::Dictionary()); - segment_sp->AddStringItem ("name", image_infos[i].segments[j].name); - segment_sp->AddIntegerItem ("vmaddr", image_infos[i].segments[j].vmaddr); - segment_sp->AddIntegerItem ("vmsize", image_infos[i].segments[j].vmsize); - segment_sp->AddIntegerItem ("fileoff", image_infos[i].segments[j].fileoff); - segment_sp->AddIntegerItem ("filesize", image_infos[i].segments[j].filesize); - segment_sp->AddIntegerItem ("maxprot", image_infos[i].segments[j].maxprot); - -// DynamicLoaderMacOSX doesn't currently need these fields, so don't send them. -// segment_sp->AddIntegerItem ("initprot", image_infos[i].segments[j].initprot); -// segment_sp->AddIntegerItem ("nsects", image_infos[i].segments[j].nsects); -// segment_sp->AddIntegerItem ("flags", image_infos[i].segments[j].flags); - segments_sp->AddItem (segment_sp); + if (all_image_infos[j].load_address == macho_addresses[i]) + { + image_infos.push_back (all_image_infos[j]); + } } - image_info_dict_sp->AddItem ("segments", segments_sp); + } - image_infos_array_sp->AddItem (image_info_dict_sp); + const size_t image_infos_count = image_infos.size(); + for (size_t i = 0; i < image_infos_count; i++) + { + GetMachOInformationFromMemory (image_infos[i].load_address, pointer_size, image_infos[i].macho_info); + } + return FormatDynamicLibrariesIntoJSON (image_infos); + } + return reply_sp; +} + +// From dyld's internal podyld_process_info.h: + +JSONGenerator::ObjectSP +MachProcess::GetSharedCacheInfo (nub_process_t pid) +{ + JSONGenerator::DictionarySP reply_sp (new JSONGenerator::Dictionary());; + kern_return_t kern_ret; + if (m_dyld_process_info_create && m_dyld_process_info_get_cache) + { + dyld_process_info info = m_dyld_process_info_create (m_task.TaskPort(), 0, &kern_ret); + if (info) + { + struct dyld_process_cache_info shared_cache_info; + m_dyld_process_info_get_cache (info, &shared_cache_info); + + reply_sp->AddIntegerItem ("shared_cache_base_address", shared_cache_info.cacheBaseAddress); + + uuid_string_t uuidstr; + uuid_unparse_upper (shared_cache_info.cacheUUID, uuidstr); + reply_sp->AddStringItem ("shared_cache_uuid", uuidstr); + + reply_sp->AddBooleanItem ("no_shared_cache", shared_cache_info.noCache); + reply_sp->AddBooleanItem ("shared_cache_private_cache", shared_cache_info.privateCache); + + m_dyld_process_info_release (info); } - reply_sp.reset (new JSONGenerator::Dictionary()); - reply_sp->AddItem ("images", image_infos_array_sp); } return reply_sp; } @@ -1048,6 +1265,7 @@ MachProcess::Interrupt() if (Signal (m_sent_interrupt_signo)) { DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Interrupt() - sent %i signal to interrupt process", m_sent_interrupt_signo); + return true; } else { @@ -2274,9 +2492,9 @@ MachProcess::GetGenealogyImageInfo (size_t idx) bool MachProcess::GetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *patch) { - bool success = false; - -#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101000) +#if defined (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000) + return false; +#else NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSOperatingSystemVersion vers = [[NSProcessInfo processInfo] operatingSystemVersion]; @@ -2287,12 +2505,10 @@ MachProcess::GetOSVersionNumbers (uint64_t *major, uint64_t *minor, uint64_t *pa if (patch) *patch = vers.patchVersion; - success = true; - [pool drain]; + + return true; #endif - - return success; } // Do the process specific setup for attach. If this returns NULL, then there's no diff --git a/tools/debugserver/source/MacOSX/MachTask.h b/tools/debugserver/source/MacOSX/MachTask.h index 96b991478c78..d8021e8f7fe3 100644 --- a/tools/debugserver/source/MacOSX/MachTask.h +++ b/tools/debugserver/source/MacOSX/MachTask.h @@ -93,26 +93,6 @@ public: const MachProcess * Process () const { return m_process; } nub_size_t PageSize (); - - bool HasMallocLoggingEnabled (); - - // enumerate the malloc records for a given address (starting with Mac OS X 10.6 Snow Leopard it should include - // all allocations that *include* address, rather than just those *starting* at address) - bool EnumerateMallocRecords (mach_vm_address_t address, - MachMallocEvent *event_buffer, - uint32_t buffer_size, - uint32_t *count); - - // enumerate every malloc record generated by this task, no matter what the address - bool EnumerateMallocRecords (MachMallocEvent *event_buffer, - uint32_t buffer_size, - uint32_t *count); - - // given a malloc event, report every stack frame that led to this event - bool EnumerateMallocFrames (MachMallocEventId event_id, - mach_vm_address_t *function_addresses_buffer, - uint32_t buffer_size, - uint32_t *count); protected: MachProcess * m_process; // The mach process that owns this MachTask diff --git a/tools/debugserver/source/MacOSX/MachTask.mm b/tools/debugserver/source/MacOSX/MachTask.mm index 9c725663d559..cc1d6a38ec05 100644 --- a/tools/debugserver/source/MacOSX/MachTask.mm +++ b/tools/debugserver/source/MacOSX/MachTask.mm @@ -40,7 +40,6 @@ #include "DNBLog.h" #include "MachProcess.h" #include "DNBDataRef.h" -#include "stack_logging.h" #ifdef WITH_SPRINGBOARD @@ -1053,90 +1052,6 @@ MachTask::DeallocateMemory (nub_addr_t addr) return false; } -static void foundStackLog(mach_stack_logging_record_t record, void *context) { - *((bool*)context) = true; -} - -bool -MachTask::HasMallocLoggingEnabled () -{ - bool found = false; - - __mach_stack_logging_enumerate_records(m_task, 0x0, foundStackLog, &found); - return found; -} - -struct history_enumerator_impl_data -{ - MachMallocEvent *buffer; - uint32_t *position; - uint32_t count; -}; - -static void history_enumerator_impl(mach_stack_logging_record_t record, void* enum_obj) -{ - history_enumerator_impl_data *data = (history_enumerator_impl_data*)enum_obj; - - if (*data->position >= data->count) - return; - - data->buffer[*data->position].m_base_address = record.address; - data->buffer[*data->position].m_size = record.argument; - data->buffer[*data->position].m_event_id = record.stack_identifier; - data->buffer[*data->position].m_event_type = record.type_flags == stack_logging_type_alloc ? eMachMallocEventTypeAlloc : - record.type_flags == stack_logging_type_dealloc ? eMachMallocEventTypeDealloc : - eMachMallocEventTypeOther; - *data->position+=1; -} - -bool -MachTask::EnumerateMallocRecords (MachMallocEvent *event_buffer, - uint32_t buffer_size, - uint32_t *count) -{ - return EnumerateMallocRecords(0, - event_buffer, - buffer_size, - count); -} - -bool -MachTask::EnumerateMallocRecords (mach_vm_address_t address, - MachMallocEvent *event_buffer, - uint32_t buffer_size, - uint32_t *count) -{ - if (!event_buffer || !count) - return false; - - if (buffer_size == 0) - return false; - - *count = 0; - history_enumerator_impl_data data = { event_buffer, count, buffer_size }; - __mach_stack_logging_enumerate_records(m_task, address, history_enumerator_impl, &data); - return (*count > 0); -} - -bool -MachTask::EnumerateMallocFrames (MachMallocEventId event_id, - mach_vm_address_t *function_addresses_buffer, - uint32_t buffer_size, - uint32_t *count) -{ - if (!function_addresses_buffer || !count) - return false; - - if (buffer_size == 0) - return false; - - __mach_stack_logging_frames_for_uniqued_stack(m_task, event_id, &function_addresses_buffer[0], buffer_size, count); - *count -= 1; - if (function_addresses_buffer[*count-1] < PageSize()) - *count -= 1; - return (*count > 0); -} - nub_size_t MachTask::PageSize () { diff --git a/tools/debugserver/source/MacOSX/Makefile b/tools/debugserver/source/MacOSX/Makefile deleted file mode 100644 index d047444a9c81..000000000000 --- a/tools/debugserver/source/MacOSX/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -##===- tools/debugserver/source/MacOSX/Makefile ------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../../../.. - -DIRS := i386 x86_64 - -TOOLNAME = debugserver - -CODESIGN_TOOLS := 1 - -TOOL_CODESIGN_IDENTITY := lldb_codesign - -LLVMLibsOptions += -llldbDebugserverCommon -llldbUtility -llldbDebugserverMacOSX_I386 -llldbDebugserverMacOSX_X86_64 \ - -framework Foundation -framework CoreFoundation - -GENERATED_MACH_SOURCES = $(PROJ_OBJ_DIR)/mach_excServer.c $(PROJ_OBJ_DIR)/mach_excUser.c - -SOURCES := CFBundle.cpp \ - CFData.cpp \ - CFString.cpp \ - MachException.cpp \ - MachProcess.cpp \ - MachTask.cpp \ - MachThread.cpp \ - MachThreadList.cpp \ - MachVMMemory.cpp \ - MachVMRegion.cpp - -BUILT_SOURCES = $(GENERATED_MACH_SOURCES) $(PROJ_OBJ_DIR)/HasAVX.o - -CPP.Flags += -I$(PROJ_OBJ_DIR)/../.. -I$(PROJ_SRC_DIR)/.. - -LD.Flags += -Wl,-sectcreate,__TEXT,__info_plist,$(PROJ_SRC_DIR)/../../resources/lldb-debugserver-Info.plist - -include $(LLDB_LEVEL)/Makefile - -ObjectsO += $(PROJ_OBJ_DIR)/HasAVX.o - -$(PROJ_OBJ_DIR)/HasAVX.o: $(PROJ_SRC_DIR)/HasAVX.s - $(Echo) "Compiling HasAVX.s for $(BuildMode) build" $(PIC_FLAG) - $(CC) $(TargetCommonOpts) $(CompileCommonOpts) -c $< -o $@ - -ifeq ($(HOST_OS),Darwin) -LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/ -endif - -$(GENERATED_MACH_SOURCES): - mig -I$(PROJ_OBJ_DIR)/../.. $(PROJ_SRC_DIR)/dbgnub-mig.defs
\ No newline at end of file diff --git a/tools/debugserver/source/MacOSX/i386/Makefile b/tools/debugserver/source/MacOSX/i386/Makefile deleted file mode 100644 index f770b19834bb..000000000000 --- a/tools/debugserver/source/MacOSX/i386/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- tools/debugserver/source/MacOSX/i386/Makefile -------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../../.. - -LIBRARYNAME := lldbDebugserverMacOSX_I386 -BUILD_ARCHIVE = 1 - -SOURCES := DNBArchImplI386.cpp - -include $(LLDB_LEVEL)/Makefile - -CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../.. -I$(PROJ_OBJ_DIR)/../../..
\ No newline at end of file diff --git a/tools/debugserver/source/MacOSX/x86_64/Makefile b/tools/debugserver/source/MacOSX/x86_64/Makefile deleted file mode 100644 index bf488c859242..000000000000 --- a/tools/debugserver/source/MacOSX/x86_64/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -##===- tools/debugserver/source/MacOSX/i386/Makefile -------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../../.. - -LIBRARYNAME := lldbDebugserverMacOSX_X86_64 -BUILD_ARCHIVE = 1 - -SOURCES := DNBArchImplX86_64.cpp - -include $(LLDB_LEVEL)/Makefile - -CPP.Flags += -I$(PROJ_SRC_DIR)/.. -I$(PROJ_SRC_DIR)/../.. -I$(PROJ_OBJ_DIR)/../../..
\ No newline at end of file diff --git a/tools/debugserver/source/Makefile b/tools/debugserver/source/Makefile deleted file mode 100644 index 9eaeab4d3827..000000000000 --- a/tools/debugserver/source/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -##===- tools/debugserver/source/Makefile -------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../../.. - -LIBRARYNAME := lldbDebugserverCommon -BUILD_ARCHIVE = 1 - -SOURCES := debugserver.cpp \ - DNBArch.cpp \ - DNBBreakpoint.cpp \ - DNB.cpp \ - DNBDataRef.cpp \ - DNBError.cpp \ - DNBLog.cpp \ - DNBRegisterInfo.cpp \ - DNBThreadResumeActions.cpp \ - libdebugserver.cpp \ - PseudoTerminal.cpp \ - PThreadEvent.cpp \ - PThreadMutex.cpp \ - RNBContext.cpp \ - RNBRemote.cpp \ - RNBServices.cpp \ - RNBSocket.cpp \ - SysSignal.cpp \ - TTYState.cpp - -include $(LLDB_LEVEL)/Makefile - -ifeq ($(HOST_OS),Darwin) -DIRS := MacOSX/i386 MacOSX/x86_64 MacOSX -CPP.Flags += -I$(PROJ_SRC_DIR)/MacOSX -CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -BUILT_SOURCES = debugserver_vers.c -endif - -ifeq ($(HOST_OS),Darwin) -debugserver_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/../debugserver.xcodeproj/project.pbxproj - "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/../debugserver.xcodeproj/project.pbxproj" debugserver > debugserver_vers.c -endif diff --git a/tools/debugserver/source/RNBDefs.h b/tools/debugserver/source/RNBDefs.h index 984b91152415..cefa986f8ca7 100644 --- a/tools/debugserver/source/RNBDefs.h +++ b/tools/debugserver/source/RNBDefs.h @@ -17,16 +17,27 @@ #include "DNBDefs.h" #include <memory> -#define DEBUGSERVER_PROGRAM_NAME "debugserver" +#define CONCAT2(a,b) a ## b +#define CONCAT(a,b) CONCAT2(a,b) +#define STRINGIZE2(x) #x +#define STRINGIZE(x) STRINGIZE2(x) + +#if !defined (DEBUGSERVER_PROGRAM_SYMBOL) +#define DEBUGSERVER_PROGRAM_SYMBOL debugserver +#endif + +#if !defined (DEBUGSERVER_PROGRAM_NAME) +#define DEBUGSERVER_PROGRAM_NAME STRINGIZE(DEBUGSERVER_PROGRAM_SYMBOL) +#endif #ifndef DEBUGSERVER_VERSION_NUM -extern "C" const unsigned char debugserverVersionString[]; -#define DEBUGSERVER_VERSION_NUM debugserverVersionNumber +extern "C" const unsigned char CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionString)[]; +#define DEBUGSERVER_VERSION_NUM CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber) #endif #ifndef DEBUGSERVER_VERSION_STR -extern "C" const double debugserverVersionNumber; -#define DEBUGSERVER_VERSION_STR debugserverVersionString +extern "C" const double CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionNumber); +#define DEBUGSERVER_VERSION_STR CONCAT(DEBUGSERVER_PROGRAM_SYMBOL, VersionString) #endif #if defined (__i386__) diff --git a/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp index 6dddb046acc5..30b804316a1d 100644 --- a/tools/debugserver/source/RNBRemote.cpp +++ b/tools/debugserver/source/RNBRemote.cpp @@ -284,6 +284,7 @@ RNBRemote::CreatePacketTable () t.push_back (Packet (json_query_thread_extended_info,&RNBRemote::HandlePacket_jThreadExtendedInfo , NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information.")); t.push_back (Packet (json_query_get_loaded_dynamic_libraries_infos, &RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos, NULL, "jGetLoadedDynamicLibrariesInfos", "Replies with JSON data of all the shared libraries loaded in this process.")); t.push_back (Packet (json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads.")); + t.push_back (Packet (json_query_get_shared_cache_info, &RNBRemote::HandlePacket_jGetSharedCacheInfo, NULL, "jGetSharedCacheInfo", "Replies with JSON data about the location and uuid of the shared cache in the inferior process.")); t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets")); t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command")); t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix")); @@ -1026,7 +1027,6 @@ RNBRemote::ThreadFunctionReadRemoteData(void *arg) case rnb_success: break; - default: case rnb_err: DNBLogThreadedIf (LOG_RNB_REMOTE, "RNBSocket::GetCommData returned error %u", err); done = true; @@ -1228,7 +1228,9 @@ RNBRemote::InitializeRegisters (bool force) register_map_entry_t reg_entry = { regnum++, // register number starts at zero and goes up with no gaps reg_data_offset, // Offset into register context data, no gaps between registers - reg_sets[set].registers[reg] // DNBRegisterInfo + reg_sets[set].registers[reg], // DNBRegisterInfo + {}, + {}, }; name_to_regnum[reg_entry.nub_info.name] = reg_entry.debugserver_regnum; @@ -2571,13 +2573,13 @@ RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid, nub_addr_t pointer_to_label_address = dispatch_queue_t + dqo_label; nub_addr_t label_addr = DNBProcessMemoryReadPointer (pid, pointer_to_label_address); if (label_addr) - queue_name = std::move(DNBProcessMemoryReadCString (pid, label_addr)); + queue_name = DNBProcessMemoryReadCString(pid, label_addr); } else { // libdispatch versions 1-3, dispatch name is a fixed width char array // in the queue structure. - queue_name = std::move(DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size)); + queue_name = DNBProcessMemoryReadCStringFixed(pid, dispatch_queue_t + dqo_label, dqo_label_size); } } } @@ -3554,13 +3556,6 @@ RNBRemote::HandlePacket_v (const char *p) } else if (strstr (p, "vCont") == p) { - typedef struct - { - nub_thread_t tid; - char action; - int signal; - } vcont_action_t; - DNBThreadResumeActions thread_actions; char *c = (char *)(p += strlen("vCont")); char *c_end = c + strlen(c); @@ -4433,6 +4428,7 @@ RNBRemote::HandlePacket_stop_process (const char *p) { // If we failed to interrupt the process, then send a stop // reply packet as the process was probably already stopped + DNBLogThreaded ("RNBRemote::HandlePacket_stop_process() sending extra stop reply because DNBProcessInterrupt returned false"); HandlePacket_last_signal (NULL); } return rnb_success; @@ -4645,15 +4641,9 @@ RNBRemote::HandlePacket_qHostInfo (const char *p) uint64_t major, minor, patch; if (DNBGetOSVersionNumbers (&major, &minor, &patch)) { - strm << "osmajor:" << major << ";"; - strm << "osminor:" << minor << ";"; - strm << "ospatch:" << patch << ";"; - - strm << "version:" << major << "." << minor; - if (patch != 0) - { + strm << "os_version:" << major << "." << minor; + if (patch != UINT64_MAX) strm << "." << patch; - } strm << ";"; } @@ -5072,6 +5062,122 @@ get_integer_value_for_key_name_from_json (const char *key, const char *json_stri } +// A helper function that retrieves a boolean value from +// a one-level-deep JSON dictionary of key-value pairs. e.g. +// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true}] + +// Returns true if it was able to find the key name, and sets the 'value' +// argument to the value found. + +bool +get_boolean_value_for_key_name_from_json (const char *key, const char *json_string, bool &value) +{ + std::string key_with_quotes = "\""; + key_with_quotes += key; + key_with_quotes += "\""; + const char *c = strstr (json_string, key_with_quotes.c_str()); + if (c) + { + c += key_with_quotes.size(); + + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + + if (*c == ':') + { + c++; + + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + + if (strncmp (c, "true", 4) == 0) + { + value = true; + return true; + } else if (strncmp (c, "false", 5) == 0) + { + value = false; + return true; + } + } + } + return false; +} + +// A helper function that reads an array of uint64_t's from +// a one-level-deep JSON dictionary of key-value pairs. e.g. +// jGetLoadedDynamicLibrariesInfos:{"solib_addrs":[31345823,7768020384,7310483024]}] + +// Returns true if it was able to find the key name, false if it did not. +// "ints" will have all integers found in the array appended to it. + +bool +get_array_of_ints_value_for_key_name_from_json (const char *key, const char *json_string, std::vector<uint64_t> &ints) +{ + std::string key_with_quotes = "\""; + key_with_quotes += key; + key_with_quotes += "\""; + const char *c = strstr (json_string, key_with_quotes.c_str()); + if (c) + { + c += key_with_quotes.size(); + + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + + if (*c == ':') + { + c++; + + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + + if (*c == '[') + { + c++; + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + while (1) + { + if (!isdigit (*c)) + { + return true; + } + + errno = 0; + char *endptr; + uint64_t value = strtoul (c, &endptr, 10); + if (errno == 0) + { + ints.push_back (value); + } + else + { + break; + } + if (endptr == c || endptr == nullptr || *endptr == '\0') + { + break; + } + c = endptr; + + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + if (*c == ',') + c++; + while (*c != '\0' && (*c == ' ' || *c == '\t' || *c == '\n' || *c == '\r')) + c++; + if (*c == ']') + { + return true; + } + } + } + } + } + return false; +} + JSONGenerator::ObjectSP RNBRemote::GetJSONThreadsInfo(bool threads_with_valid_stop_info_only) { @@ -5499,6 +5605,20 @@ RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p) return SendPacket ("OK"); } +// This packet may be called in one of three ways: +// +// jGetLoadedDynamicLibrariesInfos:{"image_count":40,"image_list_address":4295244704} +// Look for an array of the old dyld_all_image_infos style of binary infos at the image_list_address. +// This an array of {void* load_addr, void* mod_date, void* pathname} +// +// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} +// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get a list of all the +// libraries loaded +// +// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} +// Use the new style (macOS 10.12, tvOS 10, iOS 10, watchOS 3) dyld SPI to get the information +// about the libraries loaded at these addresses. +// rnb_err_t RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) { @@ -5516,28 +5636,81 @@ RNBRemote::HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p) { p += strlen (get_loaded_dynamic_libraries_infos_str); - nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); - nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); + JSONGenerator::ObjectSP json_sp; + + std::vector<uint64_t> macho_addresses; + bool fetch_all_solibs = false; + if (get_boolean_value_for_key_name_from_json ("fetch_all_solibs", p, fetch_all_solibs) && fetch_all_solibs) + { + json_sp = DNBGetAllLoadedLibrariesInfos (pid); + } + else if (get_array_of_ints_value_for_key_name_from_json ("solib_addresses", p, macho_addresses)) + { + json_sp = DNBGetLibrariesInfoForAddresses (pid, macho_addresses); + } + else + { + nub_addr_t image_list_address = get_integer_value_for_key_name_from_json ("image_list_address", p); + nub_addr_t image_count = get_integer_value_for_key_name_from_json ("image_count", p); + + if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) + { + json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); + } + } - if (image_list_address != INVALID_NUB_ADDRESS && image_count != INVALID_NUB_ADDRESS) + if (json_sp.get()) { - JSONGenerator::ObjectSP json_sp; + std::ostringstream json_str; + json_sp->Dump (json_str); + if (json_str.str().size() > 0) + { + std::string json_str_quoted = binary_encode_string (json_str.str()); + return SendPacket (json_str_quoted.c_str()); + } + else + { + SendPacket ("E84"); + } + } + } + return SendPacket ("OK"); +} - json_sp = DNBGetLoadedDynamicLibrariesInfos (pid, image_list_address, image_count); +// This packet does not currently take any arguments. So the behavior is +// jGetSharedCacheInfo:{} +// send information about the inferior's shared cache +// jGetSharedCacheInfo: +// send "OK" to indicate that this packet is supported +rnb_err_t +RNBRemote::HandlePacket_jGetSharedCacheInfo (const char *p) +{ + nub_process_t pid; + // If we haven't run the process yet, return an error. + if (!m_ctx.HasValidProcessID()) + { + return SendPacket ("E85"); + } + + pid = m_ctx.ProcessID(); + + const char get_shared_cache_info_str[] = { "jGetSharedCacheInfo:{" }; + if (strncmp (p, get_shared_cache_info_str, sizeof (get_shared_cache_info_str) - 1) == 0) + { + JSONGenerator::ObjectSP json_sp = DNBGetSharedCacheInfo (pid); - if (json_sp.get()) + if (json_sp.get()) + { + std::ostringstream json_str; + json_sp->Dump (json_str); + if (json_str.str().size() > 0) { - std::ostringstream json_str; - json_sp->Dump (json_str); - if (json_str.str().size() > 0) - { - std::string json_str_quoted = binary_encode_string (json_str.str()); - return SendPacket (json_str_quoted.c_str()); - } - else - { - SendPacket ("E84"); - } + std::string json_str_quoted = binary_encode_string (json_str.str()); + return SendPacket (json_str_quoted.c_str()); + } + else + { + SendPacket ("E86"); } } } @@ -5693,7 +5866,7 @@ RNBRemote::HandlePacket_qSymbol (const char *command) if (*p) { // We have a symbol name - symbol_name = std::move(decode_hex_ascii_string(p)); + symbol_name = decode_hex_ascii_string(p); if (!symbol_value_str.empty()) { nub_addr_t symbol_value = decode_uint64(symbol_value_str.c_str(), 16); @@ -5863,7 +6036,7 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p) DNBLogThreadedIf (LOG_RNB_PROC, "LC_VERSION_MIN_MACOSX -> 'ostype:macosx;'"); break; -#if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 +#if defined (LC_VERSION_MIN_TVOS) case LC_VERSION_MIN_TVOS: os_handled = true; rep << "ostype:tvos;"; @@ -5871,7 +6044,7 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p) break; #endif -#if defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 +#if defined (LC_VERSION_MIN_WATCHOS) case LC_VERSION_MIN_WATCHOS: os_handled = true; rep << "ostype:watchos;"; diff --git a/tools/debugserver/source/RNBRemote.h b/tools/debugserver/source/RNBRemote.h index 68dd8c52ea38..1bf7535e141d 100644 --- a/tools/debugserver/source/RNBRemote.h +++ b/tools/debugserver/source/RNBRemote.h @@ -105,6 +105,7 @@ public: json_query_thread_extended_info,// 'jThreadExtendedInfo' json_query_get_loaded_dynamic_libraries_infos, // 'jGetLoadedDynamicLibrariesInfos' json_query_threads_info, // 'jThreadsInfo' + json_query_get_shared_cache_info, // 'jGetSharedCacheInfo' pass_signals_to_inferior, // 'QPassSignals' start_noack_mode, // 'QStartNoAckMode' prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID @@ -194,6 +195,7 @@ public: rnb_err_t HandlePacket_jThreadExtendedInfo (const char *p); rnb_err_t HandlePacket_jGetLoadedDynamicLibrariesInfos (const char *p); rnb_err_t HandlePacket_jThreadsInfo (const char *p); + rnb_err_t HandlePacket_jGetSharedCacheInfo (const char *p); rnb_err_t HandlePacket_qThreadExtraInfo (const char *p); rnb_err_t HandlePacket_qThreadStopInfo (const char *p); rnb_err_t HandlePacket_qHostInfo (const char *p); diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp index 78990a671d82..a22f046771d9 100644 --- a/tools/debugserver/source/debugserver.cpp +++ b/tools/debugserver/source/debugserver.cpp @@ -824,8 +824,9 @@ FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args) if (baton == NULL || format == NULL) return; - ::vfprintf ((FILE *)baton, format, args); - ::fprintf ((FILE *)baton, "\n"); + ::vfprintf((FILE *)baton, format, args); + ::fprintf((FILE *)baton, "\n"); + ::fflush((FILE *)baton); } @@ -885,6 +886,10 @@ static struct option g_long_options[] = int main (int argc, char *argv[]) { + // If debugserver is launched with DYLD_INSERT_LIBRARIES, unset it so we + // don't spawn child processes with this enabled. + unsetenv("DYLD_INSERT_LIBRARIES"); + const char *argv_sub_zero = argv[0]; // save a copy of argv[0] for error reporting post-launch #if defined (__APPLE__) @@ -1076,7 +1081,7 @@ main (int argc, char *argv[]) case 'K': g_detach_on_error = false; - + break; case 'W': if (optarg && optarg[0]) working_dir.assign(optarg); diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp index 0b72e22c80c8..c057d71a8300 100644 --- a/tools/driver/Driver.cpp +++ b/tools/driver/Driver.cpp @@ -27,7 +27,6 @@ #include <string> -#include <thread> #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" #include "lldb/API/SBCommandReturnObject.h" @@ -37,10 +36,13 @@ #include "lldb/API/SBHostOS.h" #include "lldb/API/SBLanguageRuntime.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" -#include "lldb/API/SBProcess.h" +#include "llvm/Support/ConvertUTF.h" +#include <thread> #if !defined(__APPLE__) #include "llvm/Support/DataTypes.h" @@ -441,13 +443,24 @@ Driver::OptionData::Clear () m_script_lang = lldb::eScriptLanguageDefault; m_initial_commands.clear (); m_after_file_commands.clear (); - // If there is a local .lldbinit, source that: - SBFileSpec local_lldbinit("./.lldbinit", true); - if (local_lldbinit.Exists()) + + // If there is a local .lldbinit, add that to the + // list of things to be sourced, if the settings + // permit it. + SBFileSpec local_lldbinit (".lldbinit", true); + + SBFileSpec homedir_dot_lldb = SBHostOS::GetUserHomeDirectory(); + homedir_dot_lldb.AppendPathComponent (".lldbinit"); + + // Only read .lldbinit in the current working directory + // if it's not the same as the .lldbinit in the home + // directory (which is already being read in). + if (local_lldbinit.Exists() + && strcmp (local_lldbinit.GetDirectory(), homedir_dot_lldb.GetDirectory()) != 0) { char path[2048]; local_lldbinit.GetPath(path, 2047); - InitialCmdEntry entry(path, true, true); + InitialCmdEntry entry(path, true, true, true); m_after_file_commands.push_back (entry); } @@ -486,18 +499,18 @@ Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement pla { SBFileSpec file(command); if (file.Exists()) - command_set->push_back (InitialCmdEntry(command, is_file)); + command_set->push_back (InitialCmdEntry(command, is_file, false)); else if (file.ResolveExecutableLocation()) { char final_path[PATH_MAX]; file.GetPath (final_path, sizeof(final_path)); - command_set->push_back (InitialCmdEntry(final_path, is_file)); + command_set->push_back (InitialCmdEntry(final_path, is_file, false)); } else error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); } else - command_set->push_back (InitialCmdEntry(command, is_file)); + command_set->push_back (InitialCmdEntry(command, is_file, false)); } void @@ -550,6 +563,30 @@ Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm) const char *command = command_entry.contents.c_str(); if (command_entry.is_file) { + // If this command_entry is a file to be sourced, and it's the ./.lldbinit file (the .lldbinit + // file in the current working directory), only read it if target.load-cwd-lldbinit is 'true'. + if (command_entry.is_cwd_lldbinit_file_read) + { + SBStringList strlist = m_debugger.GetInternalVariableValue ("target.load-cwd-lldbinit", + m_debugger.GetInstanceName()); + if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "warn") == 0) + { + FILE *output = m_debugger.GetOutputFileHandle (); + ::fprintf (output, + "There is a .lldbinit file in the current directory which is not being read.\n" + "To silence this warning without sourcing in the local .lldbinit,\n" + "add the following to the lldbinit file in your home directory:\n" + " settings set target.load-cwd-lldbinit false\n" + "To allow lldb to source .lldbinit files in the current working directory,\n" + "set the value of this variable to true. Only do so if you understand and\n" + "accept the security risk.\n"); + return; + } + if (strlist.GetSize() == 1 && strcmp (strlist.GetStringAtIndex(0), "false") == 0) + { + return; + } + } bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly; strm.Printf("command source -s %i '%s'\n", source_quietly, command); } @@ -914,7 +951,8 @@ PrepareCommandsForSourcing (const char *commands_data, size_t commands_size, int { fprintf(stderr, "error: write(%i, %p, %" PRIu64 ") failed (errno = %i) " "when trying to open LLDB commands pipe\n", - fds[WRITE], commands_data, static_cast<uint64_t>(commands_size), errno); + fds[WRITE], static_cast<const void *>(commands_data), + static_cast<uint64_t>(commands_size), errno); } else if (static_cast<size_t>(nrwr) == commands_size) { @@ -999,7 +1037,12 @@ Driver::MainLoop () atexit (reset_stdin_termios); } +#ifndef _MSC_VER + // Disabling stdin buffering with MSVC's 2015 CRT exposes a bug in fgets + // which causes it to miss newlines depending on whether there have been an + // odd or even number of characters. Bug has been reported to MS via Connect. ::setbuf (stdin, NULL); +#endif ::setbuf (stdout, NULL); m_debugger.SetErrorFileHandle (stderr, false); @@ -1032,7 +1075,7 @@ Driver::MainLoop () SBStream commands_stream; // First source in the commands specified to be run before the file arguments are processed. - WriteCommandsForSourcing(eCommandPlacementBeforeFile, commands_stream); + WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream); const size_t num_args = m_option_data.m_args.size(); if (num_args > 0) @@ -1245,7 +1288,9 @@ sigint_handler (int signo) void sigtstp_handler (int signo) { - g_driver->GetDebugger().SaveInputTerminalState(); + if (g_driver) + g_driver->GetDebugger().SaveInputTerminalState(); + signal (signo, SIG_DFL); kill (getpid(), signo); signal (signo, sigtstp_handler); @@ -1254,50 +1299,64 @@ sigtstp_handler (int signo) void sigcont_handler (int signo) { - g_driver->GetDebugger().RestoreInputTerminalState(); + if (g_driver) + g_driver->GetDebugger().RestoreInputTerminalState(); + signal (signo, SIG_DFL); kill (getpid(), signo); signal (signo, sigcont_handler); } int -main (int argc, char const *argv[], const char *envp[]) +#ifdef WIN32 +wmain(int argc, wchar_t const *wargv[]) +#else +main(int argc, char const *argv[]) +#endif { -#ifdef _MSC_VER - // disable buffering on windows - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stdin , NULL, _IONBF, 0); +#ifdef _WIN32 + // Convert wide arguments to UTF-8 + std::vector<std::string> argvStrings(argc); + std::vector<const char *> argvPointers(argc); + for (int i = 0; i != argc; ++i) + { + llvm::convertWideToUTF8(wargv[i], argvStrings[i]); + argvPointers[i] = argvStrings[i].c_str(); + } + const char **argv = argvPointers.data(); #endif - SBDebugger::Initialize(); - - SBHostOS::ThreadCreated ("<lldb.driver.main-thread>"); + SBDebugger::Initialize(); - signal (SIGPIPE, SIG_IGN); - signal (SIGWINCH, sigwinch_handler); - signal (SIGINT, sigint_handler); - signal (SIGTSTP, sigtstp_handler); - signal (SIGCONT, sigcont_handler); + SBHostOS::ThreadCreated("<lldb.driver.main-thread>"); - // Create a scope for driver so that the driver object will destroy itself - // before SBDebugger::Terminate() is called. - { - Driver driver; + signal(SIGINT, sigint_handler); +#if !defined(_MSC_VER) + signal(SIGPIPE, SIG_IGN); + signal(SIGWINCH, sigwinch_handler); + signal(SIGTSTP, sigtstp_handler); + signal(SIGCONT, sigcont_handler); +#endif - bool exiting = false; - SBError error (driver.ParseArgs (argc, argv, stdout, exiting)); - if (error.Fail()) + // Create a scope for driver so that the driver object will destroy itself + // before SBDebugger::Terminate() is called. { - const char *error_cstr = error.GetCString (); - if (error_cstr) - ::fprintf (stderr, "error: %s\n", error_cstr); - } - else if (!exiting) - { - driver.MainLoop (); + Driver driver; + + bool exiting = false; + SBError error(driver.ParseArgs(argc, argv, stdout, exiting)); + if (error.Fail()) + { + const char *error_cstr = error.GetCString(); + if (error_cstr) + ::fprintf(stderr, "error: %s\n", error_cstr); + } + else if (!exiting) + { + driver.MainLoop(); + } } - } - SBDebugger::Terminate(); - return 0; + SBDebugger::Terminate(); + return 0; } diff --git a/tools/driver/Driver.h b/tools/driver/Driver.h index 639ac41d7fe6..8ac59240bc26 100644 --- a/tools/driver/Driver.h +++ b/tools/driver/Driver.h @@ -81,14 +81,16 @@ public: struct InitialCmdEntry { - InitialCmdEntry (const char *in_contents, bool in_is_file, bool in_quiet = false) : + InitialCmdEntry (const char *in_contents, bool in_is_file, bool is_cwd_lldbinit_file_read, bool in_quiet = false) : contents (in_contents), is_file (in_is_file), - source_quietly(in_quiet) + is_cwd_lldbinit_file_read (is_cwd_lldbinit_file_read), + source_quietly (in_quiet) {} std::string contents; bool is_file; + bool is_cwd_lldbinit_file_read; // if this is reading ./.lldbinit - so we may skip if not permitted bool source_quietly; }; diff --git a/tools/driver/Makefile b/tools/driver/Makefile deleted file mode 100644 index 05a245721bde..000000000000 --- a/tools/driver/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -##===- tools/driver/Makefile -------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../.. - -TOOLNAME = lldb - -NO_PEDANTIC = 1 - -include $(LLDB_LEVEL)/Makefile - -ifneq ($(HOST_OS),MingW) -LLVMLibsOptions += -ledit -llldb -llldbUtility -else -LLVMLibsOptions += -llldb -llldbUtility -CPP.Flags += -DIMPORT_LIBLLDB -endif - -ifeq ($(HOST_OS),Darwin) - LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/ - LLVMLibsOptions += -Wl,-sectcreate -Wl,__TEXT -Wl,__info_plist -Wl,"$(PROJ_SRC_DIR)/lldb-Info.plist" -endif - -ifneq (,$(filter $(HOST_OS), Linux GNU/kFreeBSD NetBSD)) - LLVMLibsOptions += -Wl,-rpath,$(LibDir) -endif - -ifeq ($(HOST_OS),FreeBSD) - CPP.Flags += -I/usr/include/edit #-v - LLVMLibsOptions += -Wl,-rpath,$(LibDir) -endif diff --git a/tools/driver/Platform.cpp b/tools/driver/Platform.cpp index a49161540872..88c0aa1e95c8 100644 --- a/tools/driver/Platform.cpp +++ b/tools/driver/Platform.cpp @@ -16,21 +16,6 @@ #include "Platform.h" -// the control handler or SIGINT handler -static sighandler_t _ctrlHandler = NULL; - -// the default console control handler -BOOL -WINAPI CtrlHandler (DWORD ctrlType) -{ - if ( _ctrlHandler != NULL ) - { - _ctrlHandler( 0 ); - return TRUE; - } - return FALSE; -} - int ioctl (int d, int request, ...) { @@ -84,29 +69,4 @@ tcgetattr (int fildes, struct termios *termios_p) return -1; } -#ifdef _MSC_VER -sighandler_t -signal (int sig, sighandler_t sigFunc) -{ - switch ( sig ) - { - case ( SIGINT ): - { - _ctrlHandler = sigFunc; - SetConsoleCtrlHandler( CtrlHandler, TRUE ); - } - break; - case ( SIGPIPE ): - case ( SIGWINCH ): - case ( SIGTSTP ): - case ( SIGCONT ): - // ignore these for now - break; - default: - assert( !"Not implemented!" ); - } - return 0; -} -#endif - #endif diff --git a/tools/driver/Platform.h b/tools/driver/Platform.h index c42d7e3da9d4..15e21f143bb0 100644 --- a/tools/driver/Platform.h +++ b/tools/driver/Platform.h @@ -12,12 +12,11 @@ #if defined( _WIN32 ) - // this will stop signal.h being included - #define _INC_SIGNAL #include "lldb/Host/HostGetOpt.h" #include <io.h> #if defined( _MSC_VER ) #include <eh.h> + #include <signal.h> #endif #include <inttypes.h> #include "lldb/Host/windows/windows.h" @@ -37,17 +36,6 @@ // ioctls.h #define TIOCGWINSZ 0x5413 - - // signal handler function pointer type - typedef void(*sighandler_t)(int); - - // signal.h - #define SIGINT 2 - // default handler - #define SIG_DFL ( (sighandler_t) -1 ) - // ignored - #define SIG_IGN ( (sighandler_t) -2 ) - // signal.h #define SIGPIPE 13 #define SIGCONT 18 @@ -80,7 +68,6 @@ }; typedef long pid_t; #define snprintf _snprintf - extern sighandler_t signal( int sig, sighandler_t ); #define PATH_MAX MAX_PATH #endif diff --git a/tools/driver/lldb-Info.plist b/tools/driver/lldb-Info.plist index 7c1bfc734a7f..5a68a8b7adb5 100644 --- a/tools/driver/lldb-Info.plist +++ b/tools/driver/lldb-Info.plist @@ -11,7 +11,7 @@ <key>CFBundleName</key> <string>lldb</string> <key>CFBundleVersion</key> - <string>2</string> + <string>360.99.0</string> <key>SecTaskAccess</key> <array> <string>allowed</string> diff --git a/tools/lldb-mi/CMakeLists.txt b/tools/lldb-mi/CMakeLists.txt index 7fd6ed199e9d..79f657a3ddda 100644 --- a/tools/lldb-mi/CMakeLists.txt +++ b/tools/lldb-mi/CMakeLists.txt @@ -73,7 +73,6 @@ set(LLDB_MI_SOURCES MIUtilString.cpp MIUtilThreadBaseStd.cpp MIUtilVariant.cpp - Platform.cpp ) if ( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" ) @@ -83,8 +82,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" ) ) endif () -include(../../cmake/LLDBDependencies.cmake) - add_lldb_executable(lldb-mi ${LLDB_MI_SOURCES}) target_link_libraries(lldb-mi liblldb) @@ -92,8 +89,6 @@ if ( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" ) target_link_libraries(lldb-mi pthread) endif () -# TODO: why isn't this done by add_lldb_executable? -#target_link_libraries(lldb-mi ${LLDB_USED_LIBS}) llvm_config(lldb-mi ${LLVM_LINK_COMPONENTS}) set_target_properties(lldb-mi PROPERTIES VERSION ${LLDB_VERSION}) diff --git a/tools/lldb-mi/MICmdCmdBreak.cpp b/tools/lldb-mi/MICmdCmdBreak.cpp index e758a3dcccef..7238200dfcac 100644 --- a/tools/lldb-mi/MICmdCmdBreak.cpp +++ b/tools/lldb-mi/MICmdCmdBreak.cpp @@ -568,19 +568,9 @@ CMICmdCmdBreakDisable::Acknowledge() { if (m_bBrkPtDisabledOk) { - const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId)); - const CMICmnMIValueResult miValueResult("number", miValueConst); - CMICmnMIValueTuple miValueTuple(miValueResult); - const CMICmnMIValueConst miValueConst2("n"); - const CMICmnMIValueResult miValueResult2("enabled", miValueConst2); - miValueTuple.Add(miValueResult2); - const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple); - const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3); - bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString()); - const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); m_miResultRecord = miRecordResult; - return bOk; + return MIstatus::success; } const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId)); @@ -683,7 +673,7 @@ CMICmdCmdBreakEnable::Execute() if (brkPt.IsValid()) { m_bBrkPtEnabledOk = true; - brkPt.SetEnabled(false); + brkPt.SetEnabled(true); m_nBrkPtId = nBrk; } @@ -704,19 +694,9 @@ CMICmdCmdBreakEnable::Acknowledge() { if (m_bBrkPtEnabledOk) { - const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId)); - const CMICmnMIValueResult miValueResult("number", miValueConst); - CMICmnMIValueTuple miValueTuple(miValueResult); - const CMICmnMIValueConst miValueConst2("y"); - const CMICmnMIValueResult miValueResult2("enabled", miValueConst2); - miValueTuple.Add(miValueResult2); - const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple); - const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3); - bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString()); - const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); m_miResultRecord = miRecordResult; - return bOk; + return MIstatus::success; } const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId)); diff --git a/tools/lldb-mi/MICmdCmdData.cpp b/tools/lldb-mi/MICmdCmdData.cpp index 0e0cf12b0080..a46fb5563ce7 100644 --- a/tools/lldb-mi/MICmdCmdData.cpp +++ b/tools/lldb-mi/MICmdCmdData.cpp @@ -117,7 +117,8 @@ CMICmdCmdDataEvaluateExpression::Execute() lldb::SBFrame frame = thread.GetSelectedFrame(); lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str()); - if (!value.IsValid() || value.GetError().Fail()) + m_Error = value.GetError(); + if (!value.IsValid() || m_Error.Fail()) value = frame.FindVariable(rExpression.c_str()); const CMICmnLLDBUtilSBValue utilValue(value, true); if (!utilValue.IsValid() || utilValue.IsValueUnknown()) @@ -177,8 +178,10 @@ CMICmdCmdDataEvaluateExpression::Acknowledge() m_miResultRecord = miRecordResult; return MIstatus::success; } - - const CMICmnMIValueConst miValueConst("Could not evaluate expression"); + CMIUtilString mi_error_msg = "Could not evaluate expression"; + if (const char* err_msg = m_Error.GetCString()) + mi_error_msg = err_msg; + const CMICmnMIValueConst miValueConst(mi_error_msg.Escape(true)); const CMICmnMIValueResult miValueResult("msg", miValueConst); const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); m_miResultRecord = miRecordResult; diff --git a/tools/lldb-mi/MICmdCmdData.h b/tools/lldb-mi/MICmdCmdData.h index 028c71387f31..a67fd6beaf72 100644 --- a/tools/lldb-mi/MICmdCmdData.h +++ b/tools/lldb-mi/MICmdCmdData.h @@ -32,6 +32,7 @@ // Third party headers: #include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBError.h" // In-house headers: #include "MICmdBase.h" @@ -71,6 +72,7 @@ class CMICmdCmdDataEvaluateExpression : public CMICmdBase private: bool m_bExpressionValid; // True = yes is valid, false = not valid bool m_bEvaluatedExpression; // True = yes is expression evaluated, false = failed + lldb::SBError m_Error; // Error object, which is examined when m_bEvaluatedExpression is false CMIUtilString m_strValue; CMICmnMIValueTuple m_miValueTuple; bool m_bFoundInvalidChar; // True = yes found unexpected character in the expression, false = all ok diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp index 823a3748248c..9435655762a9 100644 --- a/tools/lldb-mi/MICmdCmdThread.cpp +++ b/tools/lldb-mi/MICmdCmdThread.cpp @@ -29,9 +29,10 @@ // Throws: None. //-- CMICmdCmdThreadInfo::CMICmdCmdThreadInfo() - : m_bSingleThread(false) - , m_bThreadInvalid(true) - , m_constStrArgNamedThreadId("thread-id") + : m_bSingleThread(false), + m_bThreadInvalid(true), + m_constStrArgNamedThreadId("thread-id"), + m_bHasCurrentThread(false) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "thread-info"; @@ -124,6 +125,15 @@ CMICmdCmdThreadInfo::Execute() } } + // -thread-info with multiple threads ends with the current thread id if any + if (thread.IsValid()) + { + const CMIUtilString strId(CMIUtilString::Format("%d", thread.GetIndexID())); + CMICmnMIValueConst miValueCurrThreadId(strId); + m_miValueCurrThreadId = miValueCurrThreadId; + m_bHasCurrentThread = true; + } + return MIstatus::success; } @@ -179,7 +189,12 @@ CMICmdCmdThreadInfo::Acknowledge() ++it; } - const CMICmnMIValueResult miValueResult("threads", miValueList); + CMICmnMIValueResult miValueResult("threads", miValueList); + if (m_bHasCurrentThread) + { + CMIUtilString strCurrThreadId = "current-thread-id"; + miValueResult.Add(strCurrThreadId, m_miValueCurrThreadId); + } const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult); m_miResultRecord = miRecordResult; diff --git a/tools/lldb-mi/MICmdCmdThread.h b/tools/lldb-mi/MICmdCmdThread.h index 7031eabddc33..e3b0adca613a 100644 --- a/tools/lldb-mi/MICmdCmdThread.h +++ b/tools/lldb-mi/MICmdCmdThread.h @@ -60,4 +60,8 @@ class CMICmdCmdThreadInfo : public CMICmdBase bool m_bThreadInvalid; // True = invalid, false = ok VecMIValueTuple_t m_vecMIValueTuple; const CMIUtilString m_constStrArgNamedThreadId; + + // mi value of current-thread-id if multiple threads are requested + bool m_bHasCurrentThread; + CMICmnMIValue m_miValueCurrThreadId; }; diff --git a/tools/lldb-mi/MICmdCmdVar.cpp b/tools/lldb-mi/MICmdCmdVar.cpp index 8e30a2ad0da4..d8e81a44b9d2 100644 --- a/tools/lldb-mi/MICmdCmdVar.cpp +++ b/tools/lldb-mi/MICmdCmdVar.cpp @@ -201,9 +201,7 @@ CMICmdCmdVarCreate::Execute() } else { - lldb::SBStream err; - if (value.GetError().GetDescription(err)) - m_strValue = err.GetData(); + m_strValue = value.GetError().GetCString(); } return MIstatus::success; diff --git a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp index ef99ac9a4207..4ded517a14c6 100644 --- a/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp +++ b/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp @@ -18,15 +18,16 @@ #include "lldb/API/SBBreakpointLocation.h" // In-house headers: +#include "MICmdData.h" #include "MICmnLLDBDebugSessionInfo.h" #include "MICmnLLDBDebugger.h" -#include "MICmnResources.h" +#include "MICmnLLDBUtilSBValue.h" #include "MICmnMIResultRecord.h" #include "MICmnMIValueConst.h" #include "MICmnMIValueList.h" #include "MICmnMIValueTuple.h" -#include "MICmdData.h" -#include "MICmnLLDBUtilSBValue.h" +#include "MICmnResources.h" +#include "Platform.h" //++ ------------------------------------------------------------------------------------ // Details: CMICmnLLDBDebugSessionInfo constructor. @@ -452,7 +453,12 @@ CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfo { CMICmnMIValueTuple miValueTuple; lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i); - const CMICmnMIValueConst miValueConst(value.GetName()); + // If one stops inside try block with, which catch clause type is unnamed + // (e.g std::exception&) then value name will be nullptr as well as value pointer + const char* name = value.GetName(); + if (name == nullptr) + continue; + const CMICmnMIValueConst miValueConst(name); const CMICmnMIValueResult miValueResultName("name", miValueConst); if (vbMarkArgs && vbIsArgs) { @@ -609,7 +615,7 @@ CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::add { lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame); - static char pBuffer[MAX_PATH]; + static char pBuffer[PATH_MAX]; const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer)); MIunused(nBytes); CMIUtilString strResolvedPath(&pBuffer[0]); diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp index 848529f0b46a..f92595ac494a 100644 --- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -770,7 +770,8 @@ CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter(const lldb::SBEv // m_pClientDriver->SetExitApplicationFlag(); // vrbYesExit = true; // return MIstatus::success; - //} break; + //} + break; case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt: pEventType = "eBroadcastBitResetPrompt"; break; diff --git a/tools/lldb-mi/MIUtilFileStd.cpp b/tools/lldb-mi/MIUtilFileStd.cpp index 9e5d10d6ba38..ed80466b2df5 100644 --- a/tools/lldb-mi/MIUtilFileStd.cpp +++ b/tools/lldb-mi/MIUtilFileStd.cpp @@ -14,8 +14,11 @@ #include <cerrno> // In-house headers: -#include "MIUtilFileStd.h" #include "MICmnResources.h" +#include "MIUtilFileStd.h" +#include "lldb/Host/FileSystem.h" + +#include "llvm/Support/ConvertUTF.h" //++ ------------------------------------------------------------------------------------ // Details: CMIUtilFileStd constructor. @@ -82,7 +85,14 @@ CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath, bool &vwrbNewCre m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb"); #else // Open a file with exclusive write and shared read permissions - m_pFileHandle = ::_fsopen(vFileNamePath.c_str(), "wb", _SH_DENYWR); + std::wstring path; + if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path)) + m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR); + else + { + errno = EINVAL; + m_pFileHandle = nullptr; + } #endif // !defined( _MSC_VER ) if (m_pFileHandle == nullptr) diff --git a/tools/lldb-mi/Makefile b/tools/lldb-mi/Makefile deleted file mode 100644 index cdd766633b16..000000000000 --- a/tools/lldb-mi/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -##===- tools/lldb-mi/Makefile -------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../.. - -TOOLNAME = lldb-mi - -NO_PEDANTIC = 1 - -LLVMLibsOptions += -ledit -llldb -llldbUtility -LINK_COMPONENTS := support - -include $(LLDB_LEVEL)/Makefile - -ifeq ($(HOST_OS),Darwin) - LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/ - LLVMLibsOptions += -Wl,-sectcreate -Wl,__TEXT -Wl,__info_plist -Wl,"$(PROJ_SRC_DIR)/lldb-Info.plist" -endif - -ifneq (,$(filter $(HOST_OS), Linux GNU/kFreeBSD NetBSD)) - LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread -endif - -ifeq ($(HOST_OS),FreeBSD) - CPP.Flags += -I/usr/include/edit #-v - LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread -endif diff --git a/tools/lldb-mi/Platform.cpp b/tools/lldb-mi/Platform.cpp deleted file mode 100644 index 7e2eabf51b42..000000000000 --- a/tools/lldb-mi/Platform.cpp +++ /dev/null @@ -1,49 +0,0 @@ -//===-- Platform.cpp --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// this file is only relevant for Visual C++ -#if defined(_MSC_VER) - -#include <process.h> -#include <assert.h> - -#include "Platform.h" - -// the control handler or SIGINT handler -static sighandler_t _ctrlHandler = NULL; - -// the default console control handler -BOOL WINAPI CtrlHandler(DWORD ctrlType) -{ - if (_ctrlHandler != NULL) - { - _ctrlHandler(SIGINT); - return TRUE; - } - return FALSE; -} - -sighandler_t -signal(int sig, sighandler_t sigFunc) -{ - switch (sig) - { - case (SIGINT): - { - _ctrlHandler = sigFunc; - SetConsoleCtrlHandler(CtrlHandler, TRUE); - } - break; - default: - assert(!"Not implemented!"); - } - return 0; -} - -#endif diff --git a/tools/lldb-mi/Platform.h b/tools/lldb-mi/Platform.h index 093ceac0fb9d..9db8f7a156ce 100644 --- a/tools/lldb-mi/Platform.h +++ b/tools/lldb-mi/Platform.h @@ -10,12 +10,10 @@ #if defined(_MSC_VER) -// this will stop signal.h being included -#define _INC_SIGNAL - #include <io.h> #include <eh.h> #include <inttypes.h> +#include <signal.h> #include <lldb/Host/windows/Windows.h> #include <lldb/Host/HostGetOpt.h> @@ -60,7 +58,7 @@ struct termios typedef long pid_t; #define STDIN_FILENO 0 -#define PATH_MAX MAX_PATH +#define PATH_MAX 32768 #define snprintf _snprintf extern int ioctl(int d, int request, ...); @@ -73,7 +71,6 @@ typedef void (*sighandler_t)(int); // CODETAG_IOR_SIGNALS // signal.h -#define SIGINT 2 // Terminal interrupt signal #define SIGQUIT 3 // Terminal quit signal #define SIGKILL 9 // Kill (cannot be caught or ignored) #define SIGPIPE 13 // Write on a pipe with no one to read it @@ -81,10 +78,6 @@ typedef void (*sighandler_t)(int); #define SIGTSTP 20 // Terminal stop signal #define SIGSTOP 23 // Stop executing (cannot be caught or ignored) #define SIGWINCH 28 // (== SIGVTALRM) -#define SIG_DFL ((sighandler_t)-1) // Default handler -#define SIG_IGN ((sighandler_t)-2) // Ignored - -extern sighandler_t signal(int sig, sighandler_t); #else diff --git a/tools/lldb-server/Makefile b/tools/lldb-server/Makefile deleted file mode 100644 index 849b313dae8a..000000000000 --- a/tools/lldb-server/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -##===- tools/lldb-server/Makefile ------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LLDB_LEVEL := ../.. - -TOOLNAME = lldb-server - -LLVMLibsOptions += -llldb -llldbUtility - -LINK_COMPONENTS := support - -include $(LLDB_LEVEL)/Makefile - -ifeq ($(HOST_OS),Darwin) - LLVMLibsOptions += -Wl,-rpath,@loader_path/../lib/ -endif - -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU/kFreeBSD NetBSD)) - LLVMLibsOptions += -Wl,-rpath,$(LibDir) -lpthread -endif diff --git a/tools/lldb-server/lldb-gdbserver.cpp b/tools/lldb-server/lldb-gdbserver.cpp index df8cb6e68554..b8c59e29eb53 100644 --- a/tools/lldb-server/lldb-gdbserver.cpp +++ b/tools/lldb-server/lldb-gdbserver.cpp @@ -32,7 +32,6 @@ #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" #include "lldb/Host/StringConvert.h" -#include "lldb/Target/Platform.h" #include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" @@ -62,7 +61,6 @@ static int g_verbose = 0; static struct option g_long_options[] = { { "debug", no_argument, &g_debug, 1 }, - { "platform", required_argument, NULL, 'p' }, { "verbose", no_argument, &g_verbose, 1 }, { "log-file", required_argument, NULL, 'l' }, { "log-channels", required_argument, NULL, 'c' }, @@ -79,28 +77,9 @@ static struct option g_long_options[] = //---------------------------------------------------------------------- // Watch for signals //---------------------------------------------------------------------- -static int g_sigpipe_received = 0; static int g_sighup_received_count = 0; #ifndef _WIN32 - -static void -signal_handler(int signo) -{ - Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); - - fprintf (stderr, "lldb-server:%s received signal %d\n", __FUNCTION__, signo); - if (log) - log->Printf ("lldb-server:%s received signal %d", __FUNCTION__, signo); - - switch (signo) - { - case SIGPIPE: - g_sigpipe_received = 1; - break; - } -} - static void sighup_handler(MainLoopBase &mainloop) { @@ -121,7 +100,6 @@ display_usage (const char *progname, const char* subcommand) fprintf(stderr, "Usage:\n %s %s " "[--log-file log-file-name] " "[--log-channels log-channel-list] " - "[--platform platform_name] " "[--setsid] " "[--named-pipe named-pipe-path] " "[--native-regs] " @@ -131,66 +109,6 @@ display_usage (const char *progname, const char* subcommand) exit(0); } -static void -dump_available_platforms (FILE *output_file) -{ - fprintf (output_file, "Available platform plugins:\n"); - for (int i = 0; ; ++i) - { - const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (i); - const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (i); - - if (!plugin_name || !plugin_desc) - break; - - fprintf (output_file, "%s\t%s\n", plugin_name, plugin_desc); - } - - if ( Platform::GetHostPlatform () ) - { - // add this since the default platform doesn't necessarily get registered by - // the plugin name (e.g. 'host' doesn't show up as a - // registered platform plugin even though it's the default). - fprintf (output_file, "%s\tDefault platform for this host.\n", Platform::GetHostPlatform ()->GetPluginName ().AsCString ()); - } -} - -static lldb::PlatformSP -setup_platform (const std::string &platform_name) -{ - lldb::PlatformSP platform_sp; - - if (platform_name.empty()) - { - printf ("using the default platform: "); - platform_sp = Platform::GetHostPlatform (); - printf ("%s\n", platform_sp->GetPluginName ().AsCString ()); - return platform_sp; - } - - Error error; - platform_sp = Platform::Create (lldb_private::ConstString(platform_name), error); - if (error.Fail ()) - { - // the host platform isn't registered with that name (at - // least, not always. Check if the given name matches - // the default platform name. If so, use it. - if ( Platform::GetHostPlatform () && ( Platform::GetHostPlatform ()->GetPluginName () == ConstString (platform_name.c_str()) ) ) - { - platform_sp = Platform::GetHostPlatform (); - } - else - { - fprintf (stderr, "error: failed to create platform with name '%s'\n", platform_name.c_str()); - dump_available_platforms (stderr); - exit (1); - } - } - printf ("using platform: %s\n", platform_name.c_str ()); - - return platform_sp; -} - void handle_attach_to_pid (GDBRemoteCommunicationServerLLGS &gdb_server, lldb::pid_t pid) { @@ -411,16 +329,9 @@ main_gdbserver (int argc, char *argv[]) MainLoop mainloop; #ifndef _WIN32 // Setup signal handlers first thing. - signal (SIGPIPE, signal_handler); + signal(SIGPIPE, SIG_IGN); MainLoop::SignalHandleUP sighup_handle = mainloop.RegisterSignal(SIGHUP, sighup_handler, error); #endif -#ifdef __linux__ - // Block delivery of SIGCHLD on linux. NativeProcessLinux will read it using signalfd. - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - pthread_sigmask(SIG_BLOCK, &set, NULL); -#endif const char *progname = argv[0]; const char *subcommand = argv[1]; @@ -428,7 +339,6 @@ main_gdbserver (int argc, char *argv[]) argv++; int long_option_index = 0; int ch; - std::string platform_name; std::string attach_target; std::string named_pipe_path; std::string log_file; @@ -467,11 +377,6 @@ main_gdbserver (int argc, char *argv[]) log_channels = StringRef(optarg); break; - case 'p': // platform name - if (optarg && optarg[0]) - platform_name = optarg; - break; - case 'N': // named pipe if (optarg && optarg[0]) named_pipe_path = optarg; @@ -480,6 +385,7 @@ main_gdbserver (int argc, char *argv[]) case 'U': // unnamed pipe if (optarg && optarg[0]) unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1); + break; case 'r': // Do nothing, native regs is the default these days @@ -531,7 +437,7 @@ main_gdbserver (int argc, char *argv[]) exit(option_error); } - if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, 0)) + if (!LLDBServerUtilities::SetupLogging(log_file, log_channels, LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) return -1; Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_VERBOSE)); @@ -554,10 +460,7 @@ main_gdbserver (int argc, char *argv[]) exit(255); } - // Setup the platform that GDBRemoteCommunicationServerLLGS will use. - lldb::PlatformSP platform_sp = setup_platform (platform_name); - - GDBRemoteCommunicationServerLLGS gdb_server (platform_sp, mainloop); + GDBRemoteCommunicationServerLLGS gdb_server(mainloop); const char *const host_and_port = argv[0]; argc -= 1; diff --git a/tools/lldb-server/lldb-server.cpp b/tools/lldb-server/lldb-server.cpp index ec92b094f485..9ece640b2885 100644 --- a/tools/lldb-server/lldb-server.cpp +++ b/tools/lldb-server/lldb-server.cpp @@ -9,6 +9,7 @@ #include "lldb/Initialization/SystemLifetimeManager.h" #include "lldb/Initialization/SystemInitializerCommon.h" +#include "lldb/lldb-private.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ManagedStatic.h" @@ -22,9 +23,10 @@ static void display_usage (const char *progname) { fprintf(stderr, "Usage:\n" + " %s v[ersion]\n" " %s g[dbserver] [options]\n" " %s p[latform] [options]\n" - "Invoke subcommand for additional help\n", progname, progname); + "Invoke subcommand for additional help\n", progname, progname, progname); exit(0); } @@ -57,20 +59,24 @@ main (int argc, char *argv[]) display_usage(progname); exit(option_error); } - else if (argv[1][0] == 'g') - { - initialize(); - main_gdbserver(argc, argv); - terminate(); - } - else if (argv[1][0] == 'p') + + switch (argv[1][0]) { - initialize(); - main_platform(argc, argv); - terminate(); - } - else { - display_usage(progname); - exit(option_error); + case 'g': + initialize(); + main_gdbserver(argc, argv); + terminate(); + break; + case 'p': + initialize(); + main_platform(argc, argv); + terminate(); + break; + case 'v': + fprintf(stderr, "%s\n", lldb_private::GetVersion()); + break; + default: + display_usage(progname); + exit(option_error); } } |