mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-12 12:16:04 +08:00
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.
This commit is contained in:
parent
43193fe9fc
commit
9018be22e0
@ -1,3 +1,47 @@
|
||||
2018-04-07 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2018-04-06 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* value.c (~value): Update.
|
||||
|
44
gdb/auxv.c
44
gdb/auxv.c
@ -304,8 +304,7 @@ static const struct inferior_data *auxv_inferior_data;
|
||||
overhead of transfering data from a remote target to the local host. */
|
||||
struct auxv_info
|
||||
{
|
||||
LONGEST length;
|
||||
gdb_byte *data;
|
||||
gdb::optional<gdb::byte_vector> data;
|
||||
};
|
||||
|
||||
/* Handles the cleanup of the auxv cache for inferior INF. ARG is ignored.
|
||||
@ -323,8 +322,7 @@ auxv_inferior_data_cleanup (struct inferior *inf, void *arg)
|
||||
info = (struct auxv_info *) inferior_data (inf, auxv_inferior_data);
|
||||
if (info != NULL)
|
||||
{
|
||||
xfree (info->data);
|
||||
xfree (info);
|
||||
delete info;
|
||||
set_inferior_data (inf, auxv_inferior_data, NULL);
|
||||
}
|
||||
}
|
||||
@ -358,9 +356,8 @@ get_auxv_inferior_data (struct target_ops *ops)
|
||||
info = (struct auxv_info *) inferior_data (inf, auxv_inferior_data);
|
||||
if (info == NULL)
|
||||
{
|
||||
info = XCNEW (struct auxv_info);
|
||||
info->length = target_read_alloc (ops, TARGET_OBJECT_AUXV,
|
||||
NULL, &info->data);
|
||||
info = new auxv_info;
|
||||
info->data = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL);
|
||||
set_inferior_data (inf, auxv_inferior_data, info);
|
||||
}
|
||||
|
||||
@ -375,20 +372,17 @@ int
|
||||
target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
|
||||
{
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
gdb_byte *ptr;
|
||||
struct auxv_info *info;
|
||||
auxv_info *info = get_auxv_inferior_data (ops);
|
||||
|
||||
info = get_auxv_inferior_data (ops);
|
||||
if (!info->data)
|
||||
return -1;
|
||||
|
||||
data = info->data;
|
||||
ptr = data;
|
||||
|
||||
if (info->length <= 0)
|
||||
return info->length;
|
||||
gdb_byte *data = info->data->data ();
|
||||
gdb_byte *ptr = data;
|
||||
size_t len = info->data->size ();
|
||||
|
||||
while (1)
|
||||
switch (target_auxv_parse (ops, &ptr, data + info->length, &type, &val))
|
||||
switch (target_auxv_parse (ops, &ptr, data + len, &type, &val))
|
||||
{
|
||||
case 1: /* Here's an entry, check it. */
|
||||
if (type == match)
|
||||
@ -528,19 +522,17 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
|
||||
{
|
||||
struct gdbarch *gdbarch = target_gdbarch ();
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
gdb_byte *ptr;
|
||||
struct auxv_info *info;
|
||||
int ents = 0;
|
||||
auxv_info *info = get_auxv_inferior_data (ops);
|
||||
|
||||
info = get_auxv_inferior_data (ops);
|
||||
if (!info->data)
|
||||
return -1;
|
||||
|
||||
data = info->data;
|
||||
ptr = data;
|
||||
if (info->length <= 0)
|
||||
return info->length;
|
||||
gdb_byte *data = info->data->data ();
|
||||
gdb_byte *ptr = data;
|
||||
size_t len = info->data->size ();
|
||||
|
||||
while (target_auxv_parse (ops, &ptr, data + info->length, &type, &val) > 0)
|
||||
while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
|
||||
{
|
||||
gdbarch_print_auxv_entry (gdbarch, file, type, val);
|
||||
++ents;
|
||||
|
@ -1549,21 +1549,15 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
static void
|
||||
avr_io_reg_read_command (const char *args, int from_tty)
|
||||
{
|
||||
LONGEST bufsiz = 0;
|
||||
gdb_byte *buf;
|
||||
const char *bufstr;
|
||||
char query[400];
|
||||
const char *p;
|
||||
unsigned int nreg = 0;
|
||||
unsigned int val;
|
||||
int i, j, k, step;
|
||||
|
||||
/* Find out how many io registers the target has. */
|
||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
||||
"avr.io_reg", &buf);
|
||||
bufstr = (const char *) buf;
|
||||
gdb::optional<gdb::byte_vector> buf
|
||||
= target_read_alloc (¤t_target, TARGET_OBJECT_AVR, "avr.io_reg");
|
||||
|
||||
if (bufsiz <= 0)
|
||||
if (!buf)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("ERR: info io_registers NOT supported "
|
||||
@ -1571,36 +1565,42 @@ avr_io_reg_read_command (const char *args, int from_tty)
|
||||
return;
|
||||
}
|
||||
|
||||
const char *bufstr = (const char *) buf->data ();
|
||||
|
||||
if (sscanf (bufstr, "%x", &nreg) != 1)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("Error fetching number of io registers\n"));
|
||||
xfree (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
xfree (buf);
|
||||
|
||||
reinitialize_more_filter ();
|
||||
|
||||
printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
|
||||
|
||||
/* only fetch up to 8 registers at a time to keep the buffer small */
|
||||
step = 8;
|
||||
int step = 8;
|
||||
|
||||
for (i = 0; i < nreg; i += step)
|
||||
for (int i = 0; i < nreg; i += step)
|
||||
{
|
||||
/* how many registers this round? */
|
||||
j = step;
|
||||
int j = step;
|
||||
if ((i+j) >= nreg)
|
||||
j = nreg - i; /* last block is less than 8 registers */
|
||||
|
||||
snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
|
||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
||||
query, &buf);
|
||||
buf = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, query);
|
||||
|
||||
p = (const char *) buf;
|
||||
for (k = i; k < (i + j); k++)
|
||||
if (!buf)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
_("ERR: error reading avr.io_reg:%x,%x\n"),
|
||||
i, j);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *p = (const char *) buf->data ();
|
||||
for (int k = i; k < (i + j); k++)
|
||||
{
|
||||
if (sscanf (p, "%[^,],%x;", query, &val) == 2)
|
||||
{
|
||||
@ -1612,8 +1612,6 @@ avr_io_reg_read_command (const char *args, int from_tty)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xfree (buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ namespace gdb {
|
||||
and providing the whole std::vector API, if you end up needing it.
|
||||
*/
|
||||
using byte_vector = gdb::def_vector<gdb_byte>;
|
||||
using char_vector = gdb::def_vector<char>;
|
||||
|
||||
} /* namespace gdb */
|
||||
|
||||
|
@ -1420,47 +1420,41 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
|
||||
};
|
||||
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
gdb_byte *spu_ids;
|
||||
LONGEST i, j, size;
|
||||
|
||||
/* Determine list of SPU ids. */
|
||||
size = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
|
||||
NULL, &spu_ids);
|
||||
gdb::optional<gdb::byte_vector>
|
||||
spu_ids = target_read_alloc (¤t_target, TARGET_OBJECT_SPU, NULL);
|
||||
|
||||
if (!spu_ids)
|
||||
return nullptr;
|
||||
|
||||
/* Generate corefile notes for each SPU file. */
|
||||
for (i = 0; i < size; i += 4)
|
||||
for (size_t i = 0; i < spu_ids->size (); i += 4)
|
||||
{
|
||||
int fd = extract_unsigned_integer (spu_ids + i, 4, byte_order);
|
||||
int fd = extract_unsigned_integer (spu_ids->data () + i, 4, byte_order);
|
||||
|
||||
for (j = 0; j < sizeof (spu_files) / sizeof (spu_files[0]); j++)
|
||||
for (size_t j = 0; j < sizeof (spu_files) / sizeof (spu_files[0]); j++)
|
||||
{
|
||||
char annex[32], note_name[32];
|
||||
gdb_byte *spu_data;
|
||||
LONGEST spu_len;
|
||||
|
||||
xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[j]);
|
||||
spu_len = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
|
||||
annex, &spu_data);
|
||||
if (spu_len > 0)
|
||||
gdb::optional<gdb::byte_vector> spu_data
|
||||
= target_read_alloc (¤t_target, TARGET_OBJECT_SPU, annex);
|
||||
|
||||
if (spu_data && !spu_data->empty ())
|
||||
{
|
||||
xsnprintf (note_name, sizeof note_name, "SPU/%s", annex);
|
||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||
note_name, NT_SPU,
|
||||
spu_data, spu_len);
|
||||
xfree (spu_data);
|
||||
spu_data->data (),
|
||||
spu_data->size ());
|
||||
|
||||
if (!note_data)
|
||||
{
|
||||
xfree (spu_ids);
|
||||
return NULL;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
xfree (spu_ids);
|
||||
|
||||
return note_data;
|
||||
}
|
||||
|
||||
@ -1911,8 +1905,6 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
|
||||
struct linux_corefile_thread_data thread_args;
|
||||
struct elf_internal_linux_prpsinfo prpsinfo;
|
||||
char *note_data = NULL;
|
||||
gdb_byte *auxv;
|
||||
int auxv_len;
|
||||
struct thread_info *curr_thr, *signalled_thr, *thr;
|
||||
|
||||
if (! gdbarch_iterate_over_regset_sections_p (gdbarch))
|
||||
@ -1977,13 +1969,13 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
|
||||
return NULL;
|
||||
|
||||
/* Auxillary vector. */
|
||||
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
||||
NULL, &auxv);
|
||||
if (auxv_len > 0)
|
||||
gdb::optional<gdb::byte_vector> auxv =
|
||||
target_read_alloc (¤t_target, TARGET_OBJECT_AUXV, NULL);
|
||||
if (auxv && !auxv->empty ())
|
||||
{
|
||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||
"CORE", NT_AUXV, auxv, auxv_len);
|
||||
xfree (auxv);
|
||||
"CORE", NT_AUXV, auxv->data (),
|
||||
auxv->size ());
|
||||
|
||||
if (!note_data)
|
||||
return NULL;
|
||||
|
@ -163,11 +163,11 @@ std::unique_ptr<osdata>
|
||||
get_osdata (const char *type)
|
||||
{
|
||||
std::unique_ptr<osdata> osdata;
|
||||
gdb::unique_xmalloc_ptr<char> xml = target_get_osdata (type);
|
||||
gdb::optional<gdb::char_vector> xml = target_get_osdata (type);
|
||||
|
||||
if (xml)
|
||||
{
|
||||
if (xml.get ()[0] == '\0')
|
||||
if ((*xml)[0] == '\0')
|
||||
{
|
||||
if (type)
|
||||
warning (_("Empty data returned by target. Wrong osdata type?"));
|
||||
@ -175,7 +175,7 @@ get_osdata (const char *type)
|
||||
warning (_("Empty type list returned by target. No type data?"));
|
||||
}
|
||||
else
|
||||
osdata = osdata_parse (xml.get ());
|
||||
osdata = osdata_parse (xml->data ());
|
||||
}
|
||||
|
||||
if (osdata == NULL)
|
||||
|
32
gdb/remote.c
32
gdb/remote.c
@ -3151,13 +3151,13 @@ remote_get_threads_with_qxfer (struct target_ops *ops,
|
||||
#if defined(HAVE_LIBEXPAT)
|
||||
if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> xml
|
||||
gdb::optional<gdb::char_vector> xml
|
||||
= target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL);
|
||||
|
||||
if (xml != NULL && *xml != '\0')
|
||||
if (xml && (*xml)[0] != '\0')
|
||||
{
|
||||
gdb_xml_parse_quick (_("threads"), "threads.dtd",
|
||||
threads_elements, xml.get (), context);
|
||||
threads_elements, xml->data (), context);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -10790,11 +10790,11 @@ static std::vector<mem_region>
|
||||
remote_memory_map (struct target_ops *ops)
|
||||
{
|
||||
std::vector<mem_region> result;
|
||||
gdb::unique_xmalloc_ptr<char> text
|
||||
gdb::optional<gdb::char_vector> text
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_MEMORY_MAP, NULL);
|
||||
|
||||
if (text)
|
||||
result = parse_memory_map (text.get ());
|
||||
result = parse_memory_map (text->data ());
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -12905,11 +12905,11 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val)
|
||||
static traceframe_info_up
|
||||
remote_traceframe_info (struct target_ops *self)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> text
|
||||
gdb::optional<gdb::char_vector> text
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_TRACEFRAME_INFO,
|
||||
NULL);
|
||||
if (text != NULL)
|
||||
return parse_traceframe_info (text.get ());
|
||||
if (text)
|
||||
return parse_traceframe_info (text->data ());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -13137,10 +13137,10 @@ btrace_sync_conf (const struct btrace_config *conf)
|
||||
static void
|
||||
btrace_read_config (struct btrace_config *conf)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> xml
|
||||
gdb::optional<gdb::char_vector> xml
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE_CONF, "");
|
||||
if (xml != NULL)
|
||||
parse_xml_btrace_conf (conf, xml.get ());
|
||||
if (xml)
|
||||
parse_xml_btrace_conf (conf, xml->data ());
|
||||
}
|
||||
|
||||
/* Maybe reopen target btrace. */
|
||||
@ -13337,12 +13337,12 @@ remote_read_btrace (struct target_ops *self,
|
||||
(unsigned int) type);
|
||||
}
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> xml
|
||||
gdb::optional<gdb::char_vector> xml
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE, annex);
|
||||
if (xml == NULL)
|
||||
if (!xml)
|
||||
return BTRACE_ERR_UNKNOWN;
|
||||
|
||||
parse_xml_btrace (btrace, xml.get ());
|
||||
parse_xml_btrace (btrace, xml->data ());
|
||||
|
||||
return BTRACE_ERR_NONE;
|
||||
}
|
||||
@ -13376,7 +13376,7 @@ remote_load (struct target_ops *self, const char *name, int from_tty)
|
||||
static char *
|
||||
remote_pid_to_exec_file (struct target_ops *self, int pid)
|
||||
{
|
||||
static gdb::unique_xmalloc_ptr<char> filename;
|
||||
static gdb::optional<gdb::char_vector> filename;
|
||||
struct inferior *inf;
|
||||
char *annex = NULL;
|
||||
|
||||
@ -13399,7 +13399,7 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
|
||||
filename = target_read_stralloc (¤t_target,
|
||||
TARGET_OBJECT_EXEC_FILE, annex);
|
||||
|
||||
return filename.get ();
|
||||
return filename ? filename->data () : nullptr;
|
||||
}
|
||||
|
||||
/* Implement the to_can_do_single_step target_ops method. */
|
||||
|
@ -279,10 +279,10 @@ solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
|
||||
if (data->library_list != NULL)
|
||||
return data->library_list;
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> library_document
|
||||
gdb::optional<gdb::char_vector> library_document
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_AIX,
|
||||
NULL);
|
||||
if (library_document == NULL && warning_msg != NULL)
|
||||
if (!library_document && warning_msg != NULL)
|
||||
{
|
||||
warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
|
||||
warning_msg);
|
||||
@ -292,9 +292,9 @@ solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
|
||||
if (solib_aix_debug)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
|
||||
library_document.get ());
|
||||
library_document->data ());
|
||||
|
||||
data->library_list = solib_aix_parse_libraries (library_document.get ());
|
||||
data->library_list = solib_aix_parse_libraries (library_document->data ());
|
||||
if (data->library_list == NULL && warning_msg != NULL)
|
||||
{
|
||||
warning (_("%s (missing XML support?)"), warning_msg);
|
||||
|
@ -224,10 +224,10 @@ dsbt_print_loadmap (struct int_elf32_dsbt_loadmap *map)
|
||||
/* Decode int_elf32_dsbt_loadmap from BUF. */
|
||||
|
||||
static struct int_elf32_dsbt_loadmap *
|
||||
decode_loadmap (gdb_byte *buf)
|
||||
decode_loadmap (const gdb_byte *buf)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
|
||||
const struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
|
||||
struct int_elf32_dsbt_loadmap *int_ldmbuf;
|
||||
|
||||
int version, seg, nsegs;
|
||||
@ -278,7 +278,6 @@ decode_loadmap (gdb_byte *buf)
|
||||
byte_order);
|
||||
}
|
||||
|
||||
xfree (ext_ldmbuf);
|
||||
return int_ldmbuf;
|
||||
}
|
||||
|
||||
@ -292,26 +291,26 @@ static struct dsbt_info *get_dsbt_info (void);
|
||||
static void
|
||||
dsbt_get_initial_loadmaps (void)
|
||||
{
|
||||
gdb_byte *buf;
|
||||
struct dsbt_info *info = get_dsbt_info ();
|
||||
gdb::optional<gdb::byte_vector> buf
|
||||
= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC, "exec");
|
||||
|
||||
if (0 >= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC,
|
||||
"exec", &buf))
|
||||
if (!buf || buf->empty ())
|
||||
{
|
||||
info->exec_loadmap = NULL;
|
||||
error (_("Error reading DSBT exec loadmap"));
|
||||
}
|
||||
info->exec_loadmap = decode_loadmap (buf);
|
||||
info->exec_loadmap = decode_loadmap (buf->data ());
|
||||
if (solib_dsbt_debug)
|
||||
dsbt_print_loadmap (info->exec_loadmap);
|
||||
|
||||
if (0 >= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC,
|
||||
"interp", &buf))
|
||||
buf = target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC, "exec");
|
||||
if (!buf || buf->empty ())
|
||||
{
|
||||
info->interp_loadmap = NULL;
|
||||
error (_("Error reading DSBT interp loadmap"));
|
||||
}
|
||||
info->interp_loadmap = decode_loadmap (buf);
|
||||
info->interp_loadmap = decode_loadmap (buf->data ());
|
||||
if (solib_dsbt_debug)
|
||||
dsbt_print_loadmap (info->interp_loadmap);
|
||||
}
|
||||
|
@ -1243,13 +1243,13 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
|
||||
gdb_assert (annex == NULL || target_augmented_libraries_svr4_read ());
|
||||
|
||||
/* Fetch the list of shared libraries. */
|
||||
gdb::unique_xmalloc_ptr<char> svr4_library_document
|
||||
gdb::optional<gdb::char_vector> svr4_library_document
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_SVR4,
|
||||
annex);
|
||||
if (svr4_library_document == NULL)
|
||||
if (!svr4_library_document)
|
||||
return 0;
|
||||
|
||||
return svr4_parse_libraries (svr4_library_document.get (), list);
|
||||
return svr4_parse_libraries (svr4_library_document->data (), list);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -257,13 +257,13 @@ solib_target_current_sos (void)
|
||||
int ix;
|
||||
|
||||
/* Fetch the list of shared libraries. */
|
||||
gdb::unique_xmalloc_ptr<char> library_document
|
||||
gdb::optional<gdb::char_vector> library_document
|
||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES, NULL);
|
||||
if (library_document == NULL)
|
||||
if (!library_document)
|
||||
return NULL;
|
||||
|
||||
/* Parse the list. */
|
||||
library_list = solib_target_parse_libraries (library_document.get ());
|
||||
library_list = solib_target_parse_libraries (library_document->data ());
|
||||
|
||||
if (library_list == NULL)
|
||||
return NULL;
|
||||
|
86
gdb/target.c
86
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;
|
||||
gdb::optional<gdb::char_vector> buf
|
||||
= target_read_alloc_1<char> (ops, object, annex);
|
||||
|
||||
transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
|
||||
bufstr = (char *) buffer;
|
||||
if (!buf)
|
||||
return {};
|
||||
|
||||
if (transferred < 0)
|
||||
return NULL;
|
||||
|
||||
if (transferred == 0)
|
||||
return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
|
||||
|
||||
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);
|
||||
}
|
||||
|
37
gdb/target.h
37
gdb/target.h
@ -324,29 +324,26 @@ LONGEST target_write_with_progress (struct target_ops *ops,
|
||||
void (*progress) (ULONGEST, void *),
|
||||
void *baton);
|
||||
|
||||
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will
|
||||
be read using OPS. The return value will be -1 if the transfer
|
||||
fails or is not supported; 0 if the object is empty; or the length
|
||||
of the object otherwise. If a positive value is returned, a
|
||||
sufficiently large buffer will be allocated using xmalloc and
|
||||
returned in *BUF_P containing the contents of the object.
|
||||
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will be read
|
||||
using OPS. The return value will be uninstantiated if the transfer fails or
|
||||
is not supported.
|
||||
|
||||
This method should be used for objects sufficiently small to store
|
||||
in a single xmalloc'd buffer, when no fixed bound on the object's
|
||||
size is known in advance. Don't try to read TARGET_OBJECT_MEMORY
|
||||
through this function. */
|
||||
|
||||
extern LONGEST target_read_alloc (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex, gdb_byte **buf_p);
|
||||
extern gdb::optional<gdb::byte_vector> target_read_alloc
|
||||
(struct target_ops *ops, enum target_object object, const char *annex);
|
||||
|
||||
/* Read OBJECT/ANNEX using OPS. The result is NUL-terminated and
|
||||
returned as a string. If an error occurs or the transfer is
|
||||
unsupported, NULL is returned. Empty objects are returned as
|
||||
allocated but empty strings. A warning is issued if the result
|
||||
contains any embedded NUL bytes. */
|
||||
/* Read OBJECT/ANNEX using OPS. The result is a NUL-terminated character vector
|
||||
(therefore usable as a NUL-terminated string). If an error occurs or the
|
||||
transfer is unsupported, the return value will be uninstantiated. Empty
|
||||
objects are returned as allocated but empty strings. Therefore, on success,
|
||||
the returned vector is guaranteed to have at least one element. A warning is
|
||||
issued if the result contains any embedded NUL bytes. */
|
||||
|
||||
extern gdb::unique_xmalloc_ptr<char> target_read_stralloc
|
||||
extern gdb::optional<gdb::char_vector> target_read_stralloc
|
||||
(struct target_ops *ops, enum target_object object, const char *annex);
|
||||
|
||||
/* See target_ops->to_xfer_partial. */
|
||||
@ -2384,15 +2381,11 @@ extern struct target_ops *find_target_beneath (struct target_ops *);
|
||||
|
||||
struct target_ops *find_target_at (enum strata stratum);
|
||||
|
||||
/* Read OS data object of type TYPE from the target, and return it in
|
||||
XML format. The result is NUL-terminated and returned as a string.
|
||||
If an error occurs or the transfer is unsupported, NULL is
|
||||
returned. Empty objects are returned as allocated but empty
|
||||
strings. */
|
||||
/* Read OS data object of type TYPE from the target, and return it in XML
|
||||
format. The return value follows the same rules as target_read_stralloc. */
|
||||
|
||||
extern gdb::unique_xmalloc_ptr<char> target_get_osdata (const char *type);
|
||||
extern gdb::optional<gdb::char_vector> target_get_osdata (const char *type);
|
||||
|
||||
|
||||
/* Stuff that should be shared among the various remote targets. */
|
||||
|
||||
/* Debugging level. 0 is off, and non-zero values mean to print some debug
|
||||
|
@ -3871,23 +3871,19 @@ static struct value *
|
||||
sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
|
||||
void *ignore)
|
||||
{
|
||||
LONGEST size;
|
||||
gdb_byte *buf;
|
||||
|
||||
/* We need to read the whole object before we know its size. */
|
||||
size = target_read_alloc (¤t_target,
|
||||
TARGET_OBJECT_STATIC_TRACE_DATA,
|
||||
NULL, &buf);
|
||||
if (size >= 0)
|
||||
gdb::optional<gdb::byte_vector> buf
|
||||
= target_read_alloc (¤t_target, TARGET_OBJECT_STATIC_TRACE_DATA,
|
||||
NULL);
|
||||
if (buf)
|
||||
{
|
||||
struct value *v;
|
||||
struct type *type;
|
||||
|
||||
type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
|
||||
size);
|
||||
buf->size ());
|
||||
v = allocate_value (type);
|
||||
memcpy (value_contents_raw (v), buf, size);
|
||||
xfree (buf);
|
||||
memcpy (value_contents_raw (v), buf->data (), buf->size ());
|
||||
return v;
|
||||
}
|
||||
else
|
||||
|
@ -793,13 +793,13 @@ xinclude_start_include (struct gdb_xml_parser *parser,
|
||||
gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
|
||||
MAX_XINCLUDE_DEPTH);
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> text = data->fetcher (href,
|
||||
data->fetcher_baton);
|
||||
if (text == NULL)
|
||||
gdb::optional<gdb::char_vector> text
|
||||
= data->fetcher (href, data->fetcher_baton);
|
||||
if (!text)
|
||||
gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
|
||||
|
||||
if (!xml_process_xincludes (data->output, parser->name (),
|
||||
text.get (), data->fetcher,
|
||||
text->data (), data->fetcher,
|
||||
data->fetcher_baton,
|
||||
data->include_depth + 1))
|
||||
gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
|
||||
@ -971,7 +971,7 @@ show_debug_xml (struct ui_file *file, int from_tty,
|
||||
fprintf_filtered (file, _("XML debugging is %s.\n"), value);
|
||||
}
|
||||
|
||||
gdb::unique_xmalloc_ptr<char>
|
||||
gdb::optional<gdb::char_vector>
|
||||
xml_fetch_content_from_file (const char *filename, void *baton)
|
||||
{
|
||||
const char *dirname = (const char *) baton;
|
||||
@ -990,7 +990,7 @@ xml_fetch_content_from_file (const char *filename, void *baton)
|
||||
file = gdb_fopen_cloexec (filename, FOPEN_RT);
|
||||
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
return {};
|
||||
|
||||
/* Read in the whole file. */
|
||||
|
||||
@ -1001,16 +1001,16 @@ xml_fetch_content_from_file (const char *filename, void *baton)
|
||||
len = ftell (file.get ());
|
||||
rewind (file.get ());
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> text ((char *) xmalloc (len + 1));
|
||||
gdb::char_vector text (len + 1);
|
||||
|
||||
if (fread (text.get (), 1, len, file.get ()) != len
|
||||
if (fread (text.data (), 1, len, file.get ()) != len
|
||||
|| ferror (file.get ()))
|
||||
{
|
||||
warning (_("Read error from \"%s\""), filename);
|
||||
return NULL;
|
||||
return {};
|
||||
}
|
||||
|
||||
text.get ()[len] = '\0';
|
||||
text.back () = '\0';
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "gdb_obstack.h"
|
||||
#include "vec.h"
|
||||
#include "xml-utils.h"
|
||||
#include "common/byte-vector.h"
|
||||
|
||||
struct gdb_xml_parser;
|
||||
struct gdb_xml_element;
|
||||
@ -52,8 +53,8 @@ extern const char *xml_builtin[][2];
|
||||
|
||||
/* Callback to fetch a new XML file, based on the provided HREF. */
|
||||
|
||||
typedef gdb::unique_xmalloc_ptr<char> (*xml_fetch_another) (const char *href,
|
||||
void *baton);
|
||||
typedef gdb::optional<gdb::char_vector> (*xml_fetch_another) (const char *href,
|
||||
void *baton);
|
||||
|
||||
/* Append the expansion of TEXT after processing <xi:include> tags in
|
||||
RESULT. FETCHER will be called (with FETCHER_BATON) to retrieve
|
||||
@ -231,9 +232,10 @@ ULONGEST gdb_xml_parse_ulongest (struct gdb_xml_parser *parser,
|
||||
const char *value);
|
||||
|
||||
/* Open FILENAME, read all its text into memory, close it, and return
|
||||
the text. If something goes wrong, return NULL and warn. */
|
||||
the text. If something goes wrong, return an uninstantiated optional
|
||||
and warn. */
|
||||
|
||||
extern gdb::unique_xmalloc_ptr<char> xml_fetch_content_from_file
|
||||
extern gdb::optional<gdb::char_vector> xml_fetch_content_from_file
|
||||
(const char *filename, void *baton);
|
||||
|
||||
#endif
|
||||
|
@ -305,12 +305,12 @@ syscall_parse_xml (const char *document, xml_fetch_another fetcher,
|
||||
static struct syscalls_info *
|
||||
xml_init_syscalls_info (const char *filename)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> full_file
|
||||
gdb::optional<gdb::char_vector> full_file
|
||||
= xml_fetch_content_from_file (filename, gdb_datadir);
|
||||
if (full_file == NULL)
|
||||
if (!full_file)
|
||||
return NULL;
|
||||
|
||||
return syscall_parse_xml (full_file.get (),
|
||||
return syscall_parse_xml (full_file->data (),
|
||||
xml_fetch_content_from_file,
|
||||
(void *) ldirname (filename).c_str ());
|
||||
}
|
||||
|
@ -668,15 +668,15 @@ tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
|
||||
const struct target_desc *
|
||||
file_read_description_xml (const char *filename)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> tdesc_str
|
||||
gdb::optional<gdb::char_vector> tdesc_str
|
||||
= xml_fetch_content_from_file (filename, NULL);
|
||||
if (tdesc_str == NULL)
|
||||
if (!tdesc_str)
|
||||
{
|
||||
warning (_("Could not open \"%s\""), filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tdesc_parse_xml (tdesc_str.get (), xml_fetch_content_from_file,
|
||||
return tdesc_parse_xml (tdesc_str->data (), xml_fetch_content_from_file,
|
||||
(void *) ldirname (filename).c_str ());
|
||||
}
|
||||
|
||||
@ -687,7 +687,7 @@ file_read_description_xml (const char *filename)
|
||||
is "target.xml". Other calls may be performed for the DTD or
|
||||
for <xi:include>. */
|
||||
|
||||
static gdb::unique_xmalloc_ptr<char>
|
||||
static gdb::optional<gdb::char_vector>
|
||||
fetch_available_features_from_target (const char *name, void *baton_)
|
||||
{
|
||||
struct target_ops *ops = (struct target_ops *) baton_;
|
||||
@ -706,12 +706,12 @@ fetch_available_features_from_target (const char *name, void *baton_)
|
||||
const struct target_desc *
|
||||
target_read_description_xml (struct target_ops *ops)
|
||||
{
|
||||
gdb::unique_xmalloc_ptr<char> tdesc_str
|
||||
gdb::optional<gdb::char_vector> tdesc_str
|
||||
= fetch_available_features_from_target ("target.xml", ops);
|
||||
if (tdesc_str == NULL)
|
||||
if (!tdesc_str)
|
||||
return NULL;
|
||||
|
||||
return tdesc_parse_xml (tdesc_str.get (),
|
||||
return tdesc_parse_xml (tdesc_str->data (),
|
||||
fetch_available_features_from_target,
|
||||
ops);
|
||||
}
|
||||
@ -735,15 +735,15 @@ target_fetch_description_xml (struct target_ops *ops)
|
||||
|
||||
return {};
|
||||
#else
|
||||
gdb::unique_xmalloc_ptr<char>
|
||||
gdb::optional<gdb::char_vector>
|
||||
tdesc_str = fetch_available_features_from_target ("target.xml", ops);
|
||||
if (tdesc_str == NULL)
|
||||
if (!tdesc_str)
|
||||
return {};
|
||||
|
||||
std::string output;
|
||||
if (!xml_process_xincludes (output,
|
||||
_("target description"),
|
||||
tdesc_str.get (),
|
||||
tdesc_str->data (),
|
||||
fetch_available_features_from_target, ops, 0))
|
||||
{
|
||||
warning (_("Could not load XML target description; ignoring"));
|
||||
|
Loading…
Reference in New Issue
Block a user