diff options
Diffstat (limited to 'lldb/tools/debugserver/source/DNB.cpp')
-rw-r--r-- | lldb/tools/debugserver/source/DNB.cpp | 532 |
1 files changed, 13 insertions, 519 deletions
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index c6a3dbe696b..875193440b2 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -106,16 +106,16 @@ AddProcessToMap (nub_process_t pid, MachProcessSP& procSP) // // Returns the number of items removed from the process map. //---------------------------------------------------------------------- -static size_t -RemoveProcessFromMap (nub_process_t pid) -{ - ProcessMap* process_map = GetProcessMap(false); - if (process_map) - { - return process_map->erase(pid); - } - return 0; -} +//static size_t +//RemoveProcessFromMap (nub_process_t pid) +//{ +// ProcessMap* process_map = GetProcessMap(false); +// if (process_map) +// { +// return process_map->erase(pid); +// } +// return 0; +//} //---------------------------------------------------------------------- // Get the shared pointer for PID from the existing process map. @@ -175,8 +175,8 @@ kqueue_thread (void *arg) } else if (death_event.flags & EV_ERROR) { - int error_no = death_event.data; - const char *error_str = strerror(death_event.data); + int error_no = static_cast<int>(death_event.data); + const char *error_str = strerror(error_no); if (error_str == NULL) error_str = "Unknown error"; DNBLogError ("Failed to initialize kqueue event: (%d): %s", error_no, error_str ); @@ -620,7 +620,7 @@ GetAllInfosMatchingName(const char *full_process_name, std::vector<struct kinfo_ else process_name++; - const int process_name_len = strlen(process_name); + const size_t process_name_len = strlen(process_name); std::vector<struct kinfo_proc> proc_infos; const size_t num_proc_infos = GetAllInfos(proc_infos); if (num_proc_infos > 0) @@ -1339,512 +1339,6 @@ DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_ } //---------------------------------------------------------------------- -// Formatted output that uses memory and registers from process and -// thread in place of arguments. -//---------------------------------------------------------------------- -nub_size_t -DNBPrintf (nub_process_t pid, nub_thread_t tid, nub_addr_t base_addr, FILE *file, const char *format) -{ - if (file == NULL) - return 0; - enum printf_flags - { - alternate_form = (1 << 0), - zero_padding = (1 << 1), - negative_field_width = (1 << 2), - blank_space = (1 << 3), - show_sign = (1 << 4), - show_thousands_separator= (1 << 5), - }; - - enum printf_length_modifiers - { - length_mod_h = (1 << 0), - length_mod_hh = (1 << 1), - length_mod_l = (1 << 2), - length_mod_ll = (1 << 3), - length_mod_L = (1 << 4), - length_mod_j = (1 << 5), - length_mod_t = (1 << 6), - length_mod_z = (1 << 7), - length_mod_q = (1 << 8), - }; - - nub_addr_t addr = base_addr; - char *end_format = (char*)format + strlen(format); - char *end = NULL; // For strtoXXXX calls; - std::basic_string<uint8_t> buf; - nub_size_t total_bytes_read = 0; - DNBDataRef data; - const char *f; - for (f = format; *f != '\0' && f < end_format; f++) - { - char ch = *f; - switch (ch) - { - case '%': - { - f++; // Skip the '%' character -// int min_field_width = 0; -// int precision = 0; - //uint32_t flags = 0; - uint32_t length_modifiers = 0; - uint32_t byte_size = 0; - uint32_t actual_byte_size = 0; - bool is_string = false; - bool is_register = false; - DNBRegisterValue register_value; - int64_t register_offset = 0; - nub_addr_t register_addr = INVALID_NUB_ADDRESS; - - // Create the format string to use for this conversion specification - // so we can remove and mprintf specific flags and formatters. - std::string fprintf_format("%"); - - // Decode any flags - switch (*f) - { - case '#': fprintf_format += *f++; break; //flags |= alternate_form; break; - case '0': fprintf_format += *f++; break; //flags |= zero_padding; break; - case '-': fprintf_format += *f++; break; //flags |= negative_field_width; break; - case ' ': fprintf_format += *f++; break; //flags |= blank_space; break; - case '+': fprintf_format += *f++; break; //flags |= show_sign; break; - case ',': fprintf_format += *f++; break; //flags |= show_thousands_separator;break; - case '{': - case '[': - { - // We have a register name specification that can take two forms: - // ${regname} or ${regname+offset} - // The action is to read the register value and add the signed offset - // (if any) and use that as the value to format. - // $[regname] or $[regname+offset] - // The action is to read the register value and add the signed offset - // (if any) and use the result as an address to dereference. The size - // of what is dereferenced is specified by the actual byte size that - // follows the minimum field width and precision (see comments below). - switch (*f) - { - case '{': - case '[': - { - char open_scope_ch = *f; - f++; - const char *reg_name = f; - size_t reg_name_length = strcspn(f, "+-}]"); - if (reg_name_length > 0) - { - std::string register_name(reg_name, reg_name_length); - f += reg_name_length; - register_offset = strtoll(f, &end, 0); - if (f < end) - f = end; - if ((open_scope_ch == '{' && *f != '}') || (open_scope_ch == '[' && *f != ']')) - { - fprintf(file, "error: Invalid register format string. Valid formats are %%{regname} or %%{regname+offset}, %%[regname] or %%[regname+offset]\n"); - return total_bytes_read; - } - else - { - f++; - if (DNBThreadGetRegisterValueByName(pid, tid, REGISTER_SET_ALL, register_name.c_str(), ®ister_value)) - { - // Set the address to dereference using the register value plus the offset - switch (register_value.info.size) - { - default: - case 0: - fprintf (file, "error: unsupported register size of %u.\n", register_value.info.size); - return total_bytes_read; - - case 1: register_addr = register_value.value.uint8 + register_offset; break; - case 2: register_addr = register_value.value.uint16 + register_offset; break; - case 4: register_addr = register_value.value.uint32 + register_offset; break; - case 8: register_addr = register_value.value.uint64 + register_offset; break; - case 16: - if (open_scope_ch == '[') - { - fprintf (file, "error: register size (%u) too large for address.\n", register_value.info.size); - return total_bytes_read; - } - break; - } - - if (open_scope_ch == '{') - { - byte_size = register_value.info.size; - is_register = true; // value is in a register - - } - else - { - addr = register_addr; // Use register value and offset as the address - } - } - else - { - fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.8" PRIx64 "\n", register_name.c_str(), pid, tid); - return total_bytes_read; - } - } - } - } - break; - - default: - fprintf(file, "error: %%$ must be followed by (regname + n) or [regname + n]\n"); - return total_bytes_read; - } - } - break; - } - - // Check for a minimum field width - if (isdigit(*f)) - { - //min_field_width = strtoul(f, &end, 10); - strtoul(f, &end, 10); - if (end > f) - { - fprintf_format.append(f, end - f); - f = end; - } - } - - - // Check for a precision - if (*f == '.') - { - f++; - if (isdigit(*f)) - { - fprintf_format += '.'; - //precision = strtoul(f, &end, 10); - strtoul(f, &end, 10); - if (end > f) - { - fprintf_format.append(f, end - f); - f = end; - } - } - } - - - // mprintf specific: read the optional actual byte size (abs) - // after the standard minimum field width (mfw) and precision (prec). - // Standard printf calls you can have "mfw.prec" or ".prec", but - // mprintf can have "mfw.prec.abs", ".prec.abs" or "..abs". This is nice - // for strings that may be in a fixed size buffer, but may not use all bytes - // in that buffer for printable characters. - if (*f == '.') - { - f++; - actual_byte_size = strtoul(f, &end, 10); - if (end > f) - { - byte_size = actual_byte_size; - f = end; - } - } - - // Decode the length modifiers - switch (*f) - { - case 'h': // h and hh length modifiers - fprintf_format += *f++; - length_modifiers |= length_mod_h; - if (*f == 'h') - { - fprintf_format += *f++; - length_modifiers |= length_mod_hh; - } - break; - - case 'l': // l and ll length modifiers - fprintf_format += *f++; - length_modifiers |= length_mod_l; - if (*f == 'h') - { - fprintf_format += *f++; - length_modifiers |= length_mod_ll; - } - break; - - case 'L': fprintf_format += *f++; length_modifiers |= length_mod_L; break; - case 'j': fprintf_format += *f++; length_modifiers |= length_mod_j; break; - case 't': fprintf_format += *f++; length_modifiers |= length_mod_t; break; - case 'z': fprintf_format += *f++; length_modifiers |= length_mod_z; break; - case 'q': fprintf_format += *f++; length_modifiers |= length_mod_q; break; - } - - // Decode the conversion specifier - switch (*f) - { - case '_': - // mprintf specific format items - { - ++f; // Skip the '_' character - switch (*f) - { - case 'a': // Print the current address - ++f; - fprintf_format += "ll"; - fprintf_format += *f; // actual format to show address with follows the 'a' ("%_ax") - fprintf (file, fprintf_format.c_str(), addr); - break; - case 'o': // offset from base address - ++f; - fprintf_format += "ll"; - fprintf_format += *f; // actual format to show address with follows the 'a' ("%_ox") - fprintf(file, fprintf_format.c_str(), addr - base_addr); - break; - default: - fprintf (file, "error: unsupported mprintf specific format character '%c'.\n", *f); - break; - } - continue; - } - break; - - case 'D': - case 'O': - case 'U': - fprintf_format += *f; - if (byte_size == 0) - byte_size = sizeof(long int); - break; - - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - fprintf_format += *f; - if (byte_size == 0) - { - if (length_modifiers & length_mod_hh) - byte_size = sizeof(char); - else if (length_modifiers & length_mod_h) - byte_size = sizeof(short); - else if (length_modifiers & length_mod_ll) - byte_size = sizeof(long long); - else if (length_modifiers & length_mod_l) - byte_size = sizeof(long); - else - byte_size = sizeof(int); - } - break; - - case 'a': - case 'A': - case 'f': - case 'F': - case 'e': - case 'E': - case 'g': - case 'G': - fprintf_format += *f; - if (byte_size == 0) - { - if (length_modifiers & length_mod_L) - byte_size = sizeof(long double); - else - byte_size = sizeof(double); - } - break; - - case 'c': - if ((length_modifiers & length_mod_l) == 0) - { - fprintf_format += *f; - if (byte_size == 0) - byte_size = sizeof(char); - break; - } - // Fall through to 'C' modifier below... - - case 'C': - fprintf_format += *f; - if (byte_size == 0) - byte_size = sizeof(wchar_t); - break; - - case 's': - fprintf_format += *f; - if (is_register || byte_size == 0) - is_string = 1; - break; - - case 'p': - fprintf_format += *f; - if (byte_size == 0) - byte_size = sizeof(void*); - break; - } - - if (is_string) - { - std::string mem_string; - const size_t string_buf_len = 4; - char string_buf[string_buf_len+1]; - char *string_buf_end = string_buf + string_buf_len; - string_buf[string_buf_len] = '\0'; - nub_size_t bytes_read; - nub_addr_t str_addr = is_register ? register_addr : addr; - while ((bytes_read = DNBProcessMemoryRead(pid, str_addr, string_buf_len, &string_buf[0])) > 0) - { - // Did we get a NULL termination character yet? - if (strchr(string_buf, '\0') == string_buf_end) - { - // no NULL terminator yet, append as a std::string - mem_string.append(string_buf, string_buf_len); - str_addr += string_buf_len; - } - else - { - // yep - break; - } - } - // Append as a C-string so we don't get the extra NULL - // characters in the temp buffer (since it was resized) - mem_string += string_buf; - size_t mem_string_len = mem_string.size() + 1; - fprintf(file, fprintf_format.c_str(), mem_string.c_str()); - if (mem_string_len > 0) - { - if (!is_register) - { - addr += mem_string_len; - total_bytes_read += mem_string_len; - } - } - else - return total_bytes_read; - } - else - if (byte_size > 0) - { - buf.resize(byte_size); - nub_size_t bytes_read = 0; - if (is_register) - bytes_read = register_value.info.size; - else - bytes_read = DNBProcessMemoryRead(pid, addr, buf.size(), &buf[0]); - if (bytes_read > 0) - { - if (!is_register) - total_bytes_read += bytes_read; - - if (bytes_read == byte_size) - { - switch (*f) - { - case 'd': - case 'i': - case 'o': - case 'u': - case 'X': - case 'x': - case 'a': - case 'A': - case 'f': - case 'F': - case 'e': - case 'E': - case 'g': - case 'G': - case 'p': - case 'c': - case 'C': - { - if (is_register) - data.SetData(®ister_value.value.v_uint8[0], register_value.info.size); - else - data.SetData(&buf[0], bytes_read); - DNBDataRef::offset_t data_offset = 0; - if (byte_size <= 4) - { - uint32_t u32 = data.GetMax32(&data_offset, byte_size); - // Show the actual byte width when displaying hex - fprintf(file, fprintf_format.c_str(), u32); - } - else if (byte_size <= 8) - { - uint64_t u64 = data.GetMax64(&data_offset, byte_size); - // Show the actual byte width when displaying hex - fprintf(file, fprintf_format.c_str(), u64); - } - else - { - fprintf(file, "error: integer size not supported, must be 8 bytes or less (%u bytes).\n", byte_size); - } - if (!is_register) - addr += byte_size; - } - break; - - case 's': - fprintf(file, fprintf_format.c_str(), buf.c_str()); - addr += byte_size; - break; - - default: - fprintf(file, "error: unsupported conversion specifier '%c'.\n", *f); - break; - } - } - } - } - else - return total_bytes_read; - } - break; - - case '\\': - { - f++; - switch (*f) - { - case 'e': ch = '\e'; break; - case 'a': ch = '\a'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - case '\'': ch = '\''; break; - case '\\': ch = '\\'; break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - ch = strtoul(f, &end, 8); - f = end; - break; - default: - ch = *f; - break; - } - fputc(ch, file); - } - break; - - default: - fputc(ch, file); - break; - } - } - return total_bytes_read; -} - - -//---------------------------------------------------------------------- // Get the number of threads for the specified process. //---------------------------------------------------------------------- nub_size_t |