Skip to content

Commit ed838f5

Browse files
core-explorerrocallahan
authored andcommitted
GdbServerConnection.cc: do not call sprintf in a loop
1 parent 007b5dd commit ed838f5

1 file changed

Lines changed: 40 additions & 34 deletions

File tree

src/GdbServerConnection.cc

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,35 @@ void GdbServerConnection::write_binary_packet(const char* pfx, const uint8_t* da
275275
return write_packet_bytes(buf.data(), buf_num_bytes);
276276
}
277277

278-
static string string_to_hex(const string& s) {
279-
stringstream sstr;
280-
for (char ch : s) {
281-
char buf[16];
282-
sprintf(buf, "%02x", ch);
283-
sstr << buf;
278+
static void parser_assert(bool cond) {
279+
if (!cond) {
280+
fputs("Failed to parse debugger request\n", stderr);
281+
DEBUG_ASSERT(false);
282+
exit(2);
283+
}
284+
}
285+
286+
/**
287+
* For the first |input_len| bytes in |input|, append two characters to |buf| as if
288+
* snprintf("%02x") would, then write a zero terminator.
289+
*/
290+
static void write_hex_string(const uint8_t* input, size_t input_len,
291+
char* buf, size_t buf_len) {
292+
static constexpr char hex_string_table[] = "0123456789abcdef";
293+
parser_assert(buf_len >= 2 * input_len + 1);
294+
for (size_t i = 0; i < input_len; ++i) {
295+
buf[2 * i + 0] = hex_string_table[input[i] >> 4];
296+
buf[2 * i + 1] = hex_string_table[input[i] & 0xf];
284297
}
285-
return sstr.str();
298+
buf[2 * input_len] = '\0';
299+
}
300+
301+
static string string_to_hex(const string& s) {
302+
string output;
303+
output.resize(2 * s.size() + 1);
304+
write_hex_string(reinterpret_cast<const uint8_t*>(s.data()), s.size(), output.data(), output.size() + 1);
305+
output.resize(2 * s.size());
306+
return output;
286307
}
287308

288309
void GdbServerConnection::write_hex_bytes_packet(const char* prefix,
@@ -296,25 +317,14 @@ void GdbServerConnection::write_hex_bytes_packet(const char* prefix,
296317
vector<char> buf;
297318
buf.resize(pfx_num_chars + 2 * len + 1);
298319
memcpy(buf.data(), prefix, pfx_num_chars);
299-
for (size_t i = 0; i < len; ++i) {
300-
unsigned long b = bytes[i];
301-
snprintf(&buf.data()[pfx_num_chars + 2 * i], 3, "%02lx", b);
302-
}
320+
write_hex_string(bytes, len, buf.data() + pfx_num_chars, buf.size() - pfx_num_chars);
303321
write_packet(buf.data());
304322
}
305323

306324
void GdbServerConnection::write_hex_bytes_packet(const uint8_t* bytes, size_t len) {
307325
write_hex_bytes_packet("", bytes, len);
308326
}
309327

310-
static void parser_assert(bool cond) {
311-
if (!cond) {
312-
fputs("Failed to parse debugger request\n", stderr);
313-
DEBUG_ASSERT(false);
314-
exit(2);
315-
}
316-
}
317-
318328
static string decode_ascii_encoded_hex_str(const char* encoded) {
319329
ssize_t enc_len = strlen(encoded);
320330
parser_assert(enc_len % 2 == 0);
@@ -615,7 +625,7 @@ bool GdbServerConnection::xfer(const char* name, char* args) {
615625

616626
/**
617627
* Format |value| into |buf| in the manner gdb expects. |buf| must
618-
* point at a buffer with at least |1 + 2*DBG_MAX_REG_SIZE| bytes
628+
* point at a buffer with at least |1 + 2*GdbServerRegisterValue::MAX_SIZE| bytes
619629
* available. Fewer bytes than that may be written, but |buf| is
620630
* guaranteed to be null-terminated.
621631
*/
@@ -625,9 +635,7 @@ static size_t print_reg_value(const GdbServerRegisterValue& reg, char* buf) {
625635
/* gdb wants the register value in native endianness.
626636
* reg.value read in native endianness is exactly that.
627637
*/
628-
for (size_t i = 0; i < reg.size; ++i) {
629-
snprintf(&buf[2 * i], 3, "%02lx", (unsigned long)reg.value[i]);
630-
}
638+
write_hex_string(reg.value, reg.size, buf, 1 + 2*GdbServerRegisterValue::MAX_SIZE);
631639
} else {
632640
for (size_t i = 0; i < reg.size; ++i) {
633641
strcpy(&buf[2 * i], "xx");
@@ -1322,17 +1330,15 @@ bool GdbServerConnection::process_vpacket(char* payload) {
13221330
}
13231331

13241332
static string to_string(const vector<uint8_t>& bytes, size_t max_len) {
1325-
stringstream ss;
1326-
for (size_t i = 0; i < bytes.size(); ++i) {
1327-
if (i >= max_len) {
1328-
ss << "...";
1329-
break;
1330-
}
1331-
char buf[3];
1332-
sprintf(buf, "%02x", bytes[i]);
1333-
ss << buf;
1334-
}
1335-
return ss.str();
1333+
string output;
1334+
size_t num_bytes = std::min(max_len, bytes.size());
1335+
output.resize(2 * num_bytes + 1);
1336+
write_hex_string(bytes.data(), num_bytes, output.data(), output.size() + 1);
1337+
output.resize(2 * num_bytes);
1338+
if (bytes.size() > max_len) {
1339+
output += "...";
1340+
}
1341+
return output;
13361342
}
13371343

13381344
bool GdbServerConnection::process_packet() {

0 commit comments

Comments
 (0)