aboutsummaryrefslogtreecommitdiff
path: root/gdb/target.c
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@ericsson.com>2018-04-07 13:19:12 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2018-04-07 13:19:12 -0400
commit9018be22e022e6db2ba07c4e407c7244022bc69a (patch)
tree67481122825082aeabe06a4ed0f9e77f1a8c4d91 /gdb/target.c
parent43193fe9fc39138c912095ba6f21c4302abafe5e (diff)
downloadfsf-binutils-gdb-9018be22e022e6db2ba07c4e407c7244022bc69a.zip
fsf-binutils-gdb-9018be22e022e6db2ba07c4e407c7244022bc69a.tar.gz
fsf-binutils-gdb-9018be22e022e6db2ba07c4e407c7244022bc69a.tar.bz2
Make target_read_alloc & al return vectors
This patch started by changing target_read_alloc_1 to return a byte_vector, to avoid manual memory management (in target_read_alloc_1 and in the callers). To communicate failures to the callers, it actually returns a gdb::optional<gdb::byte_vector>. Adjusting target_read_stralloc was a bit more tricky, since it wants to return a buffer of char, and not gdb_byte. Since you can't just cast a gdb::byte_vector into a gdb::def_vector<char>, I made target_read_alloc_1 templated, so both versions (that return vectors of gdb_byte and char) are generated. Since target_read_stralloc now returns a gdb::char_vector instead of a gdb::unique_xmalloc_ptr<char>, a few callers need to be adjusted. gdb/ChangeLog: * common/byte-vector.h (char_vector): New type. * target.h (target_read_alloc): Return gdb::optional<byte_vector>. (target_read_stralloc): Return gdb::optional<char_vector>. (target_get_osdata): Return gdb::optional<char_vector>. * target.c (target_read_alloc_1): Templatize. Replacement manual memory management with vector. (target_read_alloc): Change return type, adjust. (target_read_stralloc): Change return type, adjust. (target_get_osdata): Change return type, adjust. * auxv.c (struct auxv_info) <length>: Remove. <data>: Change type to gdb::optional<byte_vector>. (auxv_inferior_data_cleanup): Free auxv_info with delete. (get_auxv_inferior_data): Allocate auxv_info with new, adjust. (target_auxv_search): Adjust. (fprint_target_auxv): Adjust. * avr-tdep.c (avr_io_reg_read_command): Adjust. * linux-tdep.c (linux_spu_make_corefile_notes): Adjust. (linux_make_corefile_notes): Adjust. * osdata.c (get_osdata): Adjust. * remote.c (remote_get_threads_with_qxfer): Adjust. (remote_memory_map): Adjust. (remote_traceframe_info): Adjust. (btrace_read_config): Adjust. (remote_read_btrace): Adjust. (remote_pid_to_exec_file): Adjust. * solib-aix.c (solib_aix_get_library_list): Adjust. * solib-dsbt.c (decode_loadmap): Don't free buf. (dsbt_get_initial_loadmaps): Adjust. * solib-svr4.c (svr4_current_sos_via_xfer_libraries): Adjust. * solib-target.c (solib_target_current_sos): Adjust. * tracepoint.c (sdata_make_value): Adjust. * xml-support.c (xinclude_start_include): Adjust. (xml_fetch_content_from_file): Adjust. * xml-support.h (xml_fetch_another): Change return type. (xml_fetch_content_from_file): Change return type. * xml-syscall.c (xml_init_syscalls_info): Adjust. * xml-tdesc.c (file_read_description_xml): Adjust. (fetch_available_features_from_target): Change return type. (target_fetch_description_xml): Adjust. (target_read_description_xml): Adjust.
Diffstat (limited to 'gdb/target.c')
-rw-r--r--gdb/target.c86
1 files changed, 34 insertions, 52 deletions
diff --git a/gdb/target.c b/gdb/target.c
index b9b2e75..8acdd80 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -48,6 +48,7 @@
#include <algorithm>
#include "byte-vector.h"
#include "terminal.h"
+#include <algorithm>
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
@@ -1937,18 +1938,17 @@ target_write (struct target_ops *ops,
NULL, NULL);
}
-/* Read OBJECT/ANNEX using OPS. Store the result in *BUF_P and return
- the size of the transferred data. PADDING additional bytes are
- available in *BUF_P. This is a helper function for
- target_read_alloc; see the declaration of that function for more
- information. */
+/* Help for target_read_alloc and target_read_stralloc. See their comments
+ for details. */
-static LONGEST
+template <typename T>
+gdb::optional<gdb::def_vector<T>>
target_read_alloc_1 (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte **buf_p, int padding)
+ const char *annex)
{
- size_t buf_alloc, buf_pos;
- gdb_byte *buf;
+ gdb::def_vector<T> buf;
+ size_t buf_pos = 0;
+ const int chunk = 4096;
/* This function does not have a length parameter; it reads the
entire OBJECT). Also, it doesn't support objects fetched partly
@@ -1959,82 +1959,64 @@ target_read_alloc_1 (struct target_ops *ops, enum target_object object,
/* Start by reading up to 4K at a time. The target will throttle
this number down if necessary. */
- buf_alloc = 4096;
- buf = (gdb_byte *) xmalloc (buf_alloc);
- buf_pos = 0;
while (1)
{
ULONGEST xfered_len;
enum target_xfer_status status;
- status = target_read_partial (ops, object, annex, &buf[buf_pos],
- buf_pos, buf_alloc - buf_pos - padding,
+ buf.resize (buf_pos + chunk);
+
+ status = target_read_partial (ops, object, annex,
+ (gdb_byte *) &buf[buf_pos],
+ buf_pos, chunk,
&xfered_len);
if (status == TARGET_XFER_EOF)
{
/* Read all there was. */
- if (buf_pos == 0)
- xfree (buf);
- else
- *buf_p = buf;
- return buf_pos;
+ buf.resize (buf_pos);
+ return buf;
}
else if (status != TARGET_XFER_OK)
{
/* An error occurred. */
- xfree (buf);
- return TARGET_XFER_E_IO;
+ return {};
}
buf_pos += xfered_len;
- /* If the buffer is filling up, expand it. */
- if (buf_alloc < buf_pos * 2)
- {
- buf_alloc *= 2;
- buf = (gdb_byte *) xrealloc (buf, buf_alloc);
- }
-
QUIT;
}
}
-/* Read OBJECT/ANNEX using OPS. Store the result in *BUF_P and return
- the size of the transferred data. See the declaration in "target.h"
- function for more information about the return value. */
+/* See target.h */
-LONGEST
+gdb::optional<gdb::byte_vector>
target_read_alloc (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte **buf_p)
+ const char *annex)
{
- return target_read_alloc_1 (ops, object, annex, buf_p, 0);
+ return target_read_alloc_1<gdb_byte> (ops, object, annex);
}
/* See target.h. */
-gdb::unique_xmalloc_ptr<char>
+gdb::optional<gdb::char_vector>
target_read_stralloc (struct target_ops *ops, enum target_object object,
const char *annex)
{
- gdb_byte *buffer;
- char *bufstr;
- LONGEST i, transferred;
-
- transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
- bufstr = (char *) buffer;
-
- if (transferred < 0)
- return NULL;
+ gdb::optional<gdb::char_vector> buf
+ = target_read_alloc_1<char> (ops, object, annex);
- if (transferred == 0)
- return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
+ if (!buf)
+ return {};
- bufstr[transferred] = 0;
+ if (buf->back () != '\0')
+ buf->push_back ('\0');
/* Check for embedded NUL bytes; but allow trailing NULs. */
- for (i = strlen (bufstr); i < transferred; i++)
- if (bufstr[i] != 0)
+ for (auto it = std::find (buf->begin (), buf->end (), '\0');
+ it != buf->end (); it++)
+ if (*it != '\0')
{
warning (_("target object %d, annex %s, "
"contained unexpected null characters"),
@@ -2042,7 +2024,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
break;
}
- return gdb::unique_xmalloc_ptr<char> (bufstr);
+ return buf;
}
/* Memory transfer methods. */
@@ -2744,7 +2726,7 @@ target_supports_multi_process (void)
/* See target.h. */
-gdb::unique_xmalloc_ptr<char>
+gdb::optional<gdb::char_vector>
target_get_osdata (const char *type)
{
struct target_ops *t;
@@ -2758,7 +2740,7 @@ target_get_osdata (const char *type)
t = find_default_run_target ("get OS data");
if (!t)
- return NULL;
+ return {};
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
}