diff options
author | Ed Maste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2015-02-06 21:38:51 +0000 |
commit | 205afe679855a4ce8149cdaa94d3f0868ce796dc (patch) | |
tree | 09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Utility | |
parent | 0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff) |
Diffstat (limited to 'source/Utility')
-rw-r--r-- | source/Utility/PseudoTerminal.cpp | 6 | ||||
-rw-r--r-- | source/Utility/RegisterNumber.cpp | 157 | ||||
-rw-r--r-- | source/Utility/StringExtractor.cpp | 105 | ||||
-rw-r--r-- | source/Utility/StringExtractor.h | 7 | ||||
-rw-r--r-- | source/Utility/StringExtractorGDBRemote.cpp | 13 | ||||
-rw-r--r-- | source/Utility/StringLexer.cpp | 78 | ||||
-rw-r--r-- | source/Utility/UriParser.cpp | 58 | ||||
-rw-r--r-- | source/Utility/UriParser.h | 31 |
8 files changed, 375 insertions, 80 deletions
diff --git a/source/Utility/PseudoTerminal.cpp b/source/Utility/PseudoTerminal.cpp index c906ea273005..e90955d37d4c 100644 --- a/source/Utility/PseudoTerminal.cpp +++ b/source/Utility/PseudoTerminal.cpp @@ -31,6 +31,8 @@ char *ptsname(int fd) { return 0; } pid_t fork(void) { return 0; } pid_t setsid(void) { return 0; } +#elif defined(__ANDROID_NDK__) +#include "lldb/Host/android/Android.h" #endif using namespace lldb_utility; @@ -66,7 +68,11 @@ PseudoTerminal::CloseMasterFileDescriptor () { if (m_master_fd >= 0) { + // Don't call 'close' on m_master_fd for Windows as a dummy implementation of + // posix_openpt above always gives it a 0 value. +#ifndef _WIN32 ::close (m_master_fd); +#endif m_master_fd = invalid_fd; } } diff --git a/source/Utility/RegisterNumber.cpp b/source/Utility/RegisterNumber.cpp new file mode 100644 index 000000000000..8116cda10fe5 --- /dev/null +++ b/source/Utility/RegisterNumber.cpp @@ -0,0 +1,157 @@ +//===--------------------- RegisterNumber.cpp -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/RegisterNumber.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/RegisterContext.h" + +using namespace lldb_private; + + +RegisterNumber::RegisterNumber (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num) : + m_reg_ctx_sp (thread.GetRegisterContext()), + m_regnum (num), + m_kind (kind), + m_kind_regnum_map (), + m_name ("") +{ + if (m_reg_ctx_sp.get()) + { + const lldb_private::RegisterInfo *reginfo = m_reg_ctx_sp->GetRegisterInfoAtIndex (GetAsKind (lldb::eRegisterKindLLDB)); + if (reginfo && reginfo->name) + { + m_name = reginfo->name; + } + } +} + +RegisterNumber::RegisterNumber () : + m_reg_ctx_sp(), + m_regnum (LLDB_INVALID_REGNUM), + m_kind (lldb::kNumRegisterKinds), + m_kind_regnum_map (), + m_name (nullptr) +{ +} + +void +RegisterNumber::init (lldb_private::Thread &thread, lldb::RegisterKind kind, uint32_t num) +{ + m_reg_ctx_sp = thread.GetRegisterContext(); + m_regnum = num; + m_kind = kind; + if (m_reg_ctx_sp.get()) + { + const lldb_private::RegisterInfo *reginfo = m_reg_ctx_sp->GetRegisterInfoAtIndex (GetAsKind (lldb::eRegisterKindLLDB)); + if (reginfo && reginfo->name) + { + m_name = reginfo->name; + } + } +} + +const RegisterNumber & +RegisterNumber::operator = (const RegisterNumber &rhs) +{ + m_reg_ctx_sp = rhs.m_reg_ctx_sp; + m_regnum = rhs.m_regnum; + m_kind = rhs.m_kind; + for (auto it : rhs.m_kind_regnum_map) + m_kind_regnum_map[it.first] = it.second; + m_name = rhs.m_name; + return *this; +} + +bool +RegisterNumber::operator == (RegisterNumber &rhs) +{ + if (IsValid() != rhs.IsValid()) + return false; + + if (m_kind == rhs.m_kind) + { + if (m_regnum == rhs.m_regnum) + return true; + else + return false; + } + + uint32_t rhs_regnum = rhs.GetAsKind (m_kind); + if (rhs_regnum != LLDB_INVALID_REGNUM) + { + if (m_regnum == rhs_regnum) + return true; + else + return false; + } + uint32_t lhs_regnum = GetAsKind (rhs.m_kind); + { + if (lhs_regnum == rhs.m_regnum) + return true; + else + return false; + } + return false; +} + +bool +RegisterNumber::operator != (RegisterNumber &rhs) +{ + return !(*this == rhs); +} + +bool +RegisterNumber::IsValid () const +{ + return m_reg_ctx_sp.get() + && m_kind != lldb::kNumRegisterKinds + && m_regnum != LLDB_INVALID_REGNUM; +} + +uint32_t +RegisterNumber::GetAsKind (lldb::RegisterKind kind) +{ + if (m_regnum == LLDB_INVALID_REGNUM) + return LLDB_INVALID_REGNUM; + + if (kind == m_kind) + return m_regnum; + + Collection::iterator iter = m_kind_regnum_map.find (kind); + if (iter != m_kind_regnum_map.end()) + { + return iter->second; + } + uint32_t output_regnum = LLDB_INVALID_REGNUM; + if (m_reg_ctx_sp + && m_reg_ctx_sp->ConvertBetweenRegisterKinds (m_kind, m_regnum, kind, output_regnum) + && output_regnum != LLDB_INVALID_REGNUM) + { + m_kind_regnum_map[kind] = output_regnum; + } + return output_regnum; +} + +uint32_t +RegisterNumber::GetRegisterNumber () const +{ + return m_regnum; +} + +lldb::RegisterKind +RegisterNumber::GetRegisterKind () const +{ + return m_kind; +} + +const char * +RegisterNumber::GetName () +{ + return m_name; +} diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp index 8747853213cb..a2cbe6cd4869 100644 --- a/source/Utility/StringExtractor.cpp +++ b/source/Utility/StringExtractor.cpp @@ -16,43 +16,6 @@ // Other libraries and framework includes // Project includes -static const uint8_t -g_hex_ascii_to_hex_integer[256] = { - - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, - 0x8, 0x9, 255, 255, 255, 255, 255, 255, - 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, -}; - static inline int xdigit_to_sint (char ch) { @@ -60,7 +23,9 @@ xdigit_to_sint (char ch) return 10 + ch - 'a'; if (ch >= 'A' && ch <= 'F') return 10 + ch - 'A'; - return ch - '0'; + if (ch >= '0' && ch <= '9') + return ch - '0'; + return -1; } //---------------------------------------------------------------------- @@ -129,25 +94,45 @@ StringExtractor::GetChar (char fail_value) } //---------------------------------------------------------------------- +// If a pair of valid hex digits exist at the head of the +// StringExtractor they are decoded into an unsigned byte and returned +// by this function +// +// If there is not a pair of valid hex digits at the head of the +// StringExtractor, it is left unchanged and -1 is returned +//---------------------------------------------------------------------- +int +StringExtractor::DecodeHexU8() +{ + if (GetBytesLeft() < 2) + { + return -1; + } + const int hi_nibble = xdigit_to_sint(m_packet[m_index]); + const int lo_nibble = xdigit_to_sint(m_packet[m_index+1]); + if (hi_nibble == -1 || lo_nibble == -1) + { + return -1; + } + m_index += 2; + return (uint8_t)((hi_nibble << 4) + lo_nibble); +} + +//---------------------------------------------------------------------- // Extract an unsigned character from two hex ASCII chars in the packet // string //---------------------------------------------------------------------- uint8_t StringExtractor::GetHexU8 (uint8_t fail_value, bool set_eof_on_fail) { - if (GetBytesLeft() >= 2) + int byte = DecodeHexU8(); + if (byte == -1) { - const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index])]; - const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[m_index+1])]; - if (hi_nibble < 16 && lo_nibble < 16) - { - m_index += 2; - return (hi_nibble << 4) + lo_nibble; - } + if (set_eof_on_fail || m_index >= m_packet.size()) + m_index = UINT64_MAX; + return fail_value; } - if (set_eof_on_fail || m_index >= m_packet.size()) - m_index = UINT64_MAX; - return fail_value; + return (uint8_t)byte; } uint32_t @@ -372,6 +357,28 @@ StringExtractor::GetHexBytes (void *dst_void, size_t dst_len, uint8_t fail_fill_ return bytes_extracted; } +//---------------------------------------------------------------------- +// Decodes all valid hex encoded bytes at the head of the +// StringExtractor, limited by dst_len. +// +// Returns the number of bytes successfully decoded +//---------------------------------------------------------------------- +size_t +StringExtractor::GetHexBytesAvail (void *dst_void, size_t dst_len) +{ + uint8_t *dst = (uint8_t*)dst_void; + size_t bytes_extracted = 0; + while (bytes_extracted < dst_len) + { + int decode = DecodeHexU8(); + if (decode == -1) + { + break; + } + dst[bytes_extracted++] = (uint8_t)decode; + } + return bytes_extracted; +} // Consume ASCII hex nibble character pairs until we have decoded byte_size // bytes of data. diff --git a/source/Utility/StringExtractor.h b/source/Utility/StringExtractor.h index 697499309ced..49dfe99bd358 100644 --- a/source/Utility/StringExtractor.h +++ b/source/Utility/StringExtractor.h @@ -92,9 +92,13 @@ public: return m_packet.size() - m_index; return 0; } + char GetChar (char fail_value = '\0'); + int + DecodeHexU8(); + uint8_t GetHexU8 (uint8_t fail_value = 0, bool set_eof_on_fail = true); @@ -122,6 +126,9 @@ public: size_t GetHexBytes (void *dst, size_t dst_len, uint8_t fail_fill_value); + size_t + GetHexBytesAvail (void *dst, size_t dst_len); + uint64_t GetHexWithFixedSize (uint32_t byte_size, bool little_endian, uint64_t fail_value); diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp index 17717dbe6e20..161ac6a026f2 100644 --- a/source/Utility/StringExtractorGDBRemote.cpp +++ b/source/Utility/StringExtractorGDBRemote.cpp @@ -346,14 +346,15 @@ StringExtractorGDBRemote::GetError () size_t StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str) { + // Just get the data bytes in the string as GDBRemoteCommunication::CheckForPacket() + // already removes any 0x7d escaped characters. If any 0x7d characters are left in + // the packet, then they are supposed to be there... str.clear(); - char ch; - while (GetBytesLeft()) + const size_t bytes_left = GetBytesLeft(); + if (bytes_left > 0) { - ch = GetChar(); - if (ch == 0x7d) - ch = (GetChar() ^ 0x20); - str.append(1,ch); + str.assign(m_packet, m_index, bytes_left); + m_index += bytes_left; } return str.size(); } diff --git a/source/Utility/StringLexer.cpp b/source/Utility/StringLexer.cpp index bde2fc6a4202..2f62d2cedb40 100644 --- a/source/Utility/StringLexer.cpp +++ b/source/Utility/StringLexer.cpp @@ -10,28 +10,24 @@ #include "lldb/Utility/StringLexer.h" #include <algorithm> +#include <assert.h> using namespace lldb_utility; StringLexer::StringLexer (std::string s) : -m_data(s), -m_position(0), -m_putback_data() + m_data(s), + m_position(0) { } StringLexer::StringLexer (const StringLexer& rhs) : -m_data(rhs.m_data), -m_position(rhs.m_position), -m_putback_data(rhs.m_putback_data) + m_data(rhs.m_data), + m_position(rhs.m_position) { } StringLexer::Character StringLexer::Peek () { - if (m_putback_data.empty()) - return m_data[m_position]; - else - return m_putback_data.front(); + return m_data[m_position]; } bool @@ -46,6 +42,42 @@ StringLexer::NextIf (Character c) return false; } +std::pair<bool, StringLexer::Character> +StringLexer::NextIf (std::initializer_list<Character> cs) +{ + auto val = Peek(); + for (auto c : cs) + { + if (val == c) + { + Next(); + return {true,c}; + } + } + return {false,0}; +} + +bool +StringLexer::AdvanceIf (const std::string& token) +{ + auto pos = m_position; + bool matches = true; + for (auto c : token) + { + if (!NextIf(c)) + { + matches = false; + break; + } + } + if (!matches) + { + m_position = pos; + return false; + } + return true; +} + StringLexer::Character StringLexer::Next () { @@ -57,35 +89,32 @@ StringLexer::Next () bool StringLexer::HasAtLeast (Size s) { - auto in_m_data = m_data.size()-m_position; - auto in_putback = m_putback_data.size(); - return (in_m_data + in_putback >= s); + return (m_data.size() - m_position) >= s; } - void -StringLexer::PutBack (Character c) +StringLexer::PutBack (Size s) { - m_putback_data.push_back(c); + assert (m_position >= s); + m_position -= s; } bool StringLexer::HasAny (Character c) { - const auto begin(m_putback_data.begin()); - const auto end(m_putback_data.end()); - if (std::find(begin, end, c) != end) - return true; return m_data.find(c, m_position) != std::string::npos; } +std::string +StringLexer::GetUnlexed () +{ + return std::string(m_data, m_position); +} + void StringLexer::Consume() { - if (m_putback_data.empty()) - m_position++; - else - m_putback_data.pop_front(); + m_position++; } StringLexer& @@ -95,7 +124,6 @@ StringLexer::operator = (const StringLexer& rhs) { m_data = rhs.m_data; m_position = rhs.m_position; - m_putback_data = rhs.m_putback_data; } return *this; } diff --git a/source/Utility/UriParser.cpp b/source/Utility/UriParser.cpp new file mode 100644 index 000000000000..bf1e601485b4 --- /dev/null +++ b/source/Utility/UriParser.cpp @@ -0,0 +1,58 @@ +//===-- UriParser.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Utility/UriParser.h" + +// C Includes +#include <stdlib.h> + +// C++ Includes +// Other libraries and framework includes +// Project includes + +//---------------------------------------------------------------------- +// UriParser::Parse +//---------------------------------------------------------------------- +bool +UriParser::Parse(const char* uri, + std::string& scheme, + std::string& hostname, + int& port, + std::string& path + ) +{ + char scheme_buf[100] = {0}; + char hostname_buf[256] = {0}; + char port_buf[11] = {0}; // 10==strlen(2^32) + char path_buf[2049] = {'/', 0}; + + bool ok = false; + if (4==sscanf(uri, "%99[^:/]://%255[^/:]:%[^/]/%2047s", scheme_buf, hostname_buf, port_buf, path_buf+1)) { ok = true; } + else if (3==sscanf(uri, "%99[^:/]://%255[^/:]:%[^/]", scheme_buf, hostname_buf, port_buf)) { ok = true; } + else if (3==sscanf(uri, "%99[^:/]://%255[^/]/%2047s", scheme_buf, hostname_buf, path_buf+1)) { ok = true; } + else if (2==sscanf(uri, "%99[^:/]://%255[^/]", scheme_buf, hostname_buf)) { ok = true; } + + char* end = port_buf; + int port_tmp = strtoul(port_buf, &end, 10); + if (*end != 0) + { + // there are invalid characters in port_buf + return false; + } + + if (ok) + { + scheme.assign(scheme_buf); + hostname.assign(hostname_buf); + port = port_tmp; + path.assign(path_buf); + } + return ok; +} + diff --git a/source/Utility/UriParser.h b/source/Utility/UriParser.h new file mode 100644 index 000000000000..c46628d3bd68 --- /dev/null +++ b/source/Utility/UriParser.h @@ -0,0 +1,31 @@ +//===-- UriParser.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_UriParser_h_ +#define utility_UriParser_h_ + +// C Includes +// C++ Includes +#include <string> + +// Other libraries and framework includes +// Project includes + +class UriParser +{ +public: + static bool Parse(const char* uri, + std::string& scheme, + std::string& hostname, + int& port, + std::string& path + ); +}; + +#endif // utility_UriParser_h_ |