Variable size for regs mask in collection list

This patch changes collection_list to allow larger register masks.

The mask is changed from an array to a vector and is initialized to
hold the maximum possible remote register number.  The stringify
method is updated to resize temp_buf if needed.

gdb/ChangeLog:
2018-08-06  Pedro Franco de Carvalho  <pedromfc@linux.ibm.com>

	* tracepoint.h (collection_list) <m_regs_mask>: Change type to
	std::vector<unsigned char>.
	* tracepoint.c (collection_list::collection_list): Remove
	m_regs_mask initializer from initializer list.  Resize
	m_regs_mask using the largest remote register number.
	(collection_list::add_remote_register): Remove size check on
	m_regs_mask.  Use at to access element.
	(collection_list::stringify): Change type of temp_buf to
	gdb::char_vector.  Update uses of temp_buf.  Resize if needed to
	stringify the register mask.  Use pack_hex_byte for the register
	mask.
This commit is contained in:
Pedro Franco de Carvalho 2018-08-06 16:24:55 -03:00
parent 4277c4b87a
commit a04b9d62a2
3 changed files with 59 additions and 24 deletions

View File

@ -1,3 +1,17 @@
2018-08-06 Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
* tracepoint.h (collection_list) <m_regs_mask>: Change type to
std::vector<unsigned char>.
* tracepoint.c (collection_list::collection_list): Remove
m_regs_mask initializer from initializer list. Resize
m_regs_mask using the largest remote register number.
(collection_list::add_remote_register): Remove size check on
m_regs_mask. Use at to access element.
(collection_list::stringify): Change type of temp_buf to
gdb::char_vector. Update uses of temp_buf. Resize if needed to
stringify the register mask. Use pack_hex_byte for the register
mask.
2018-08-06 Pedro Franco de Carvalho <pedromfc@linux.ibm.com> 2018-08-06 Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
* tracepoint.h (class collection_list) <add_register>: Remove. * tracepoint.h (class collection_list) <add_register>: Remove.

View File

@ -822,10 +822,8 @@ collection_list::add_remote_register (unsigned int regno)
{ {
if (info_verbose) if (info_verbose)
printf_filtered ("collect register %d\n", regno); printf_filtered ("collect register %d\n", regno);
if (regno >= (8 * sizeof (m_regs_mask)))
error (_("Internal: register number %d too large for tracepoint"), m_regs_mask.at (regno / 8) |= 1 << (regno % 8);
regno);
m_regs_mask[regno / 8] |= 1 << (regno % 8);
} }
/* Add all the registers from the mask in AEXPR to the mask in the /* Add all the registers from the mask in AEXPR to the mask in the
@ -1136,9 +1134,20 @@ collection_list::add_static_trace_data ()
} }
collection_list::collection_list () collection_list::collection_list ()
: m_regs_mask (), : m_strace_data (false)
m_strace_data (false)
{ {
int max_remote_regno = 0;
for (int i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
{
int remote_regno = (gdbarch_remote_register_number
(target_gdbarch (), i));
if (remote_regno >= 0 && remote_regno > max_remote_regno)
max_remote_regno = remote_regno;
}
m_regs_mask.resize ((max_remote_regno / 8) + 1);
m_memranges.reserve (128); m_memranges.reserve (128);
m_aexprs.reserve (128); m_aexprs.reserve (128);
} }
@ -1148,7 +1157,8 @@ collection_list::collection_list ()
std::vector<std::string> std::vector<std::string>
collection_list::stringify () collection_list::stringify ()
{ {
char temp_buf[2048]; gdb::char_vector temp_buf (2048);
int count; int count;
char *end; char *end;
long i; long i;
@ -1158,35 +1168,45 @@ collection_list::stringify ()
{ {
if (info_verbose) if (info_verbose)
printf_filtered ("\nCollecting static trace data\n"); printf_filtered ("\nCollecting static trace data\n");
end = temp_buf; end = temp_buf.data ();
*end++ = 'L'; *end++ = 'L';
str_list.emplace_back (temp_buf, end - temp_buf); str_list.emplace_back (temp_buf.data (), end - temp_buf.data ());
} }
for (i = sizeof (m_regs_mask) - 1; i > 0; i--) for (i = m_regs_mask.size () - 1; i > 0; i--)
if (m_regs_mask[i] != 0) /* Skip leading zeroes in regs_mask. */ if (m_regs_mask[i] != 0) /* Skip leading zeroes in regs_mask. */
break; break;
if (m_regs_mask[i] != 0) /* Prepare to send regs_mask to the stub. */ if (m_regs_mask[i] != 0) /* Prepare to send regs_mask to the stub. */
{ {
if (info_verbose) if (info_verbose)
printf_filtered ("\nCollecting registers (mask): 0x"); printf_filtered ("\nCollecting registers (mask): 0x");
end = temp_buf;
/* One char for 'R', one for the null terminator and two per
mask byte. */
std::size_t new_size = (i + 1) * 2 + 2;
if (new_size > temp_buf.size ())
temp_buf.resize (new_size);
end = temp_buf.data ();
*end++ = 'R'; *end++ = 'R';
for (; i >= 0; i--) for (; i >= 0; i--)
{ {
QUIT; /* Allow user to bail out with ^C. */ QUIT; /* Allow user to bail out with ^C. */
if (info_verbose) if (info_verbose)
printf_filtered ("%02X", m_regs_mask[i]); printf_filtered ("%02X", m_regs_mask[i]);
sprintf (end, "%02X", m_regs_mask[i]);
end += 2; end = pack_hex_byte (end, m_regs_mask[i]);
} }
str_list.emplace_back (temp_buf); *end = '\0';
str_list.emplace_back (temp_buf.data ());
} }
if (info_verbose) if (info_verbose)
printf_filtered ("\n"); printf_filtered ("\n");
if (!m_memranges.empty () && info_verbose) if (!m_memranges.empty () && info_verbose)
printf_filtered ("Collecting memranges: \n"); printf_filtered ("Collecting memranges: \n");
for (i = 0, count = 0, end = temp_buf; i < m_memranges.size (); i++) for (i = 0, count = 0, end = temp_buf.data ();
i < m_memranges.size (); i++)
{ {
QUIT; /* Allow user to bail out with ^C. */ QUIT; /* Allow user to bail out with ^C. */
if (info_verbose) if (info_verbose)
@ -1200,9 +1220,9 @@ collection_list::stringify ()
} }
if (count + 27 > MAX_AGENT_EXPR_LEN) if (count + 27 > MAX_AGENT_EXPR_LEN)
{ {
str_list.emplace_back (temp_buf, count); str_list.emplace_back (temp_buf.data (), count);
count = 0; count = 0;
end = temp_buf; end = temp_buf.data ();
} }
{ {
@ -1222,7 +1242,7 @@ collection_list::stringify ()
} }
count += strlen (end); count += strlen (end);
end = temp_buf + count; end = temp_buf.data () + count;
} }
for (i = 0; i < m_aexprs.size (); i++) for (i = 0; i < m_aexprs.size (); i++)
@ -1230,9 +1250,9 @@ collection_list::stringify ()
QUIT; /* Allow user to bail out with ^C. */ QUIT; /* Allow user to bail out with ^C. */
if ((count + 10 + 2 * m_aexprs[i]->len) > MAX_AGENT_EXPR_LEN) if ((count + 10 + 2 * m_aexprs[i]->len) > MAX_AGENT_EXPR_LEN)
{ {
str_list.emplace_back (temp_buf, count); str_list.emplace_back (temp_buf.data (), count);
count = 0; count = 0;
end = temp_buf; end = temp_buf.data ();
} }
sprintf (end, "X%08X,", m_aexprs[i]->len); sprintf (end, "X%08X,", m_aexprs[i]->len);
end += 10; /* 'X' + 8 hex digits + ',' */ end += 10; /* 'X' + 8 hex digits + ',' */
@ -1244,9 +1264,9 @@ collection_list::stringify ()
if (count != 0) if (count != 0)
{ {
str_list.emplace_back (temp_buf, count); str_list.emplace_back (temp_buf.data (), count);
count = 0; count = 0;
end = temp_buf; end = temp_buf.data ();
} }
return str_list; return str_list;

View File

@ -292,8 +292,9 @@ public:
{ return m_computed; } { return m_computed; }
private: private:
/* room for up to 256 regs */ /* We need the allocator zero-initialize the mask, so we don't use
unsigned char m_regs_mask[32]; gdb::byte_vector. */
std::vector<unsigned char> m_regs_mask;
std::vector<memrange> m_memranges; std::vector<memrange> m_memranges;