From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 9 Aug 2018 17:17:46 +0200 Subject: gdb-rhbz1187581-power8-regs-5of7.patch ;; Add GDB support to access/display POWER8 registers (IBM, RH BZ 1187581). commit a04b9d62a234923826e431a209d396a628661548 Author: Pedro Franco de Carvalho Date: Mon Aug 6 16:24:55 2018 -0300 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 * tracepoint.h (collection_list) : Change type to std::vector. * 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 + + * tracepoint.h (collection_list) : Change type to + std::vector. + * 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 * tracepoint.h (class collection_list) : Remove. diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -822,10 +822,8 @@ collection_list::add_remote_register (unsigned int regno) { if (info_verbose) printf_filtered ("collect register %d\n", regno); - if (regno >= (8 * sizeof (m_regs_mask))) - error (_("Internal: register number %d too large for tracepoint"), - regno); - m_regs_mask[regno / 8] |= 1 << (regno % 8); + + m_regs_mask.at (regno / 8) |= 1 << (regno % 8); } /* 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 () - : 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_aexprs.reserve (128); } @@ -1148,7 +1157,8 @@ collection_list::collection_list () std::vector collection_list::stringify () { - char temp_buf[2048]; + gdb::char_vector temp_buf (2048); + int count; char *end; long i; @@ -1158,35 +1168,45 @@ collection_list::stringify () { if (info_verbose) printf_filtered ("\nCollecting static trace data\n"); - end = temp_buf; + end = temp_buf.data (); *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. */ break; if (m_regs_mask[i] != 0) /* Prepare to send regs_mask to the stub. */ { if (info_verbose) 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'; for (; i >= 0; i--) { QUIT; /* Allow user to bail out with ^C. */ if (info_verbose) 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) printf_filtered ("\n"); if (!m_memranges.empty () && info_verbose) 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. */ if (info_verbose) @@ -1200,9 +1220,9 @@ collection_list::stringify () } if (count + 27 > MAX_AGENT_EXPR_LEN) { - str_list.emplace_back (temp_buf, count); + str_list.emplace_back (temp_buf.data (), count); count = 0; - end = temp_buf; + end = temp_buf.data (); } { @@ -1222,7 +1242,7 @@ collection_list::stringify () } count += strlen (end); - end = temp_buf + count; + end = temp_buf.data () + count; } for (i = 0; i < m_aexprs.size (); i++) @@ -1230,9 +1250,9 @@ collection_list::stringify () QUIT; /* Allow user to bail out with ^C. */ 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; - end = temp_buf; + end = temp_buf.data (); } sprintf (end, "X%08X,", m_aexprs[i]->len); end += 10; /* 'X' + 8 hex digits + ',' */ @@ -1244,9 +1264,9 @@ collection_list::stringify () if (count != 0) { - str_list.emplace_back (temp_buf, count); + str_list.emplace_back (temp_buf.data (), count); count = 0; - end = temp_buf; + end = temp_buf.data (); } return str_list; diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -293,8 +293,9 @@ public: { return m_computed; } private: - /* room for up to 256 regs */ - unsigned char m_regs_mask[32]; + /* We need the allocator zero-initialize the mask, so we don't use + gdb::byte_vector. */ + std::vector m_regs_mask; std::vector m_memranges;