summaryrefslogtreecommitdiff
path: root/source/Utility
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
committerEd Maste <emaste@FreeBSD.org>2015-02-06 21:38:51 +0000
commit205afe679855a4ce8149cdaa94d3f0868ce796dc (patch)
tree09bc83f73246ee3c7a779605cd0122093d2a8a19 /source/Utility
parent0cac4ca3916ac24ab6139d03cbfd18db9e715bfe (diff)
Diffstat (limited to 'source/Utility')
-rw-r--r--source/Utility/PseudoTerminal.cpp6
-rw-r--r--source/Utility/RegisterNumber.cpp157
-rw-r--r--source/Utility/StringExtractor.cpp105
-rw-r--r--source/Utility/StringExtractor.h7
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp13
-rw-r--r--source/Utility/StringLexer.cpp78
-rw-r--r--source/Utility/UriParser.cpp58
-rw-r--r--source/Utility/UriParser.h31
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_