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
18 changed files with 224 additions and 225 deletions
|
@ -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>
|
2018-04-06 Tom Tromey <tom@tromey.com>
|
||||||
|
|
||||||
* value.c (~value): Update.
|
* 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. */
|
overhead of transfering data from a remote target to the local host. */
|
||||||
struct auxv_info
|
struct auxv_info
|
||||||
{
|
{
|
||||||
LONGEST length;
|
gdb::optional<gdb::byte_vector> data;
|
||||||
gdb_byte *data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Handles the cleanup of the auxv cache for inferior INF. ARG is ignored.
|
/* 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);
|
info = (struct auxv_info *) inferior_data (inf, auxv_inferior_data);
|
||||||
if (info != NULL)
|
if (info != NULL)
|
||||||
{
|
{
|
||||||
xfree (info->data);
|
delete info;
|
||||||
xfree (info);
|
|
||||||
set_inferior_data (inf, auxv_inferior_data, NULL);
|
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);
|
info = (struct auxv_info *) inferior_data (inf, auxv_inferior_data);
|
||||||
if (info == NULL)
|
if (info == NULL)
|
||||||
{
|
{
|
||||||
info = XCNEW (struct auxv_info);
|
info = new auxv_info;
|
||||||
info->length = target_read_alloc (ops, TARGET_OBJECT_AUXV,
|
info->data = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL);
|
||||||
NULL, &info->data);
|
|
||||||
set_inferior_data (inf, auxv_inferior_data, info);
|
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)
|
target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
|
||||||
{
|
{
|
||||||
CORE_ADDR type, val;
|
CORE_ADDR type, val;
|
||||||
gdb_byte *data;
|
auxv_info *info = get_auxv_inferior_data (ops);
|
||||||
gdb_byte *ptr;
|
|
||||||
struct auxv_info *info;
|
|
||||||
|
|
||||||
info = get_auxv_inferior_data (ops);
|
if (!info->data)
|
||||||
|
return -1;
|
||||||
|
|
||||||
data = info->data;
|
gdb_byte *data = info->data->data ();
|
||||||
ptr = data;
|
gdb_byte *ptr = data;
|
||||||
|
size_t len = info->data->size ();
|
||||||
if (info->length <= 0)
|
|
||||||
return info->length;
|
|
||||||
|
|
||||||
while (1)
|
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. */
|
case 1: /* Here's an entry, check it. */
|
||||||
if (type == match)
|
if (type == match)
|
||||||
|
@ -528,19 +522,17 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
|
||||||
{
|
{
|
||||||
struct gdbarch *gdbarch = target_gdbarch ();
|
struct gdbarch *gdbarch = target_gdbarch ();
|
||||||
CORE_ADDR type, val;
|
CORE_ADDR type, val;
|
||||||
gdb_byte *data;
|
|
||||||
gdb_byte *ptr;
|
|
||||||
struct auxv_info *info;
|
|
||||||
int ents = 0;
|
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;
|
gdb_byte *data = info->data->data ();
|
||||||
ptr = data;
|
gdb_byte *ptr = data;
|
||||||
if (info->length <= 0)
|
size_t len = info->data->size ();
|
||||||
return info->length;
|
|
||||||
|
|
||||||
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);
|
gdbarch_print_auxv_entry (gdbarch, file, type, val);
|
||||||
++ents;
|
++ents;
|
||||||
|
|
|
@ -1549,21 +1549,15 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
static void
|
static void
|
||||||
avr_io_reg_read_command (const char *args, int from_tty)
|
avr_io_reg_read_command (const char *args, int from_tty)
|
||||||
{
|
{
|
||||||
LONGEST bufsiz = 0;
|
|
||||||
gdb_byte *buf;
|
|
||||||
const char *bufstr;
|
|
||||||
char query[400];
|
char query[400];
|
||||||
const char *p;
|
|
||||||
unsigned int nreg = 0;
|
unsigned int nreg = 0;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
int i, j, k, step;
|
|
||||||
|
|
||||||
/* Find out how many io registers the target has. */
|
/* Find out how many io registers the target has. */
|
||||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
gdb::optional<gdb::byte_vector> buf
|
||||||
"avr.io_reg", &buf);
|
= target_read_alloc (¤t_target, TARGET_OBJECT_AVR, "avr.io_reg");
|
||||||
bufstr = (const char *) buf;
|
|
||||||
|
|
||||||
if (bufsiz <= 0)
|
if (!buf)
|
||||||
{
|
{
|
||||||
fprintf_unfiltered (gdb_stderr,
|
fprintf_unfiltered (gdb_stderr,
|
||||||
_("ERR: info io_registers NOT supported "
|
_("ERR: info io_registers NOT supported "
|
||||||
|
@ -1571,36 +1565,42 @@ avr_io_reg_read_command (const char *args, int from_tty)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *bufstr = (const char *) buf->data ();
|
||||||
|
|
||||||
if (sscanf (bufstr, "%x", &nreg) != 1)
|
if (sscanf (bufstr, "%x", &nreg) != 1)
|
||||||
{
|
{
|
||||||
fprintf_unfiltered (gdb_stderr,
|
fprintf_unfiltered (gdb_stderr,
|
||||||
_("Error fetching number of io registers\n"));
|
_("Error fetching number of io registers\n"));
|
||||||
xfree (buf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (buf);
|
|
||||||
|
|
||||||
reinitialize_more_filter ();
|
reinitialize_more_filter ();
|
||||||
|
|
||||||
printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
|
printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
|
||||||
|
|
||||||
/* only fetch up to 8 registers at a time to keep the buffer small */
|
/* 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? */
|
/* how many registers this round? */
|
||||||
j = step;
|
int j = step;
|
||||||
if ((i+j) >= nreg)
|
if ((i+j) >= nreg)
|
||||||
j = nreg - i; /* last block is less than 8 registers */
|
j = nreg - i; /* last block is less than 8 registers */
|
||||||
|
|
||||||
snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
|
snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
|
||||||
bufsiz = target_read_alloc (¤t_target, TARGET_OBJECT_AVR,
|
buf = target_read_alloc (¤t_target, TARGET_OBJECT_AVR, query);
|
||||||
query, &buf);
|
|
||||||
|
|
||||||
p = (const char *) buf;
|
if (!buf)
|
||||||
for (k = i; k < (i + j); k++)
|
{
|
||||||
|
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)
|
if (sscanf (p, "%[^,],%x;", query, &val) == 2)
|
||||||
{
|
{
|
||||||
|
@ -1612,8 +1612,6 @@ avr_io_reg_read_command (const char *args, int from_tty)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace gdb {
|
||||||
and providing the whole std::vector API, if you end up needing it.
|
and providing the whole std::vector API, if you end up needing it.
|
||||||
*/
|
*/
|
||||||
using byte_vector = gdb::def_vector<gdb_byte>;
|
using byte_vector = gdb::def_vector<gdb_byte>;
|
||||||
|
using char_vector = gdb::def_vector<char>;
|
||||||
|
|
||||||
} /* namespace gdb */
|
} /* 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 ());
|
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||||
gdb_byte *spu_ids;
|
|
||||||
LONGEST i, j, size;
|
|
||||||
|
|
||||||
/* Determine list of SPU ids. */
|
/* Determine list of SPU ids. */
|
||||||
size = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
|
gdb::optional<gdb::byte_vector>
|
||||||
NULL, &spu_ids);
|
spu_ids = target_read_alloc (¤t_target, TARGET_OBJECT_SPU, NULL);
|
||||||
|
|
||||||
|
if (!spu_ids)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
/* Generate corefile notes for each SPU file. */
|
/* 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];
|
char annex[32], note_name[32];
|
||||||
gdb_byte *spu_data;
|
|
||||||
LONGEST spu_len;
|
|
||||||
|
|
||||||
xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[j]);
|
xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[j]);
|
||||||
spu_len = target_read_alloc (¤t_target, TARGET_OBJECT_SPU,
|
gdb::optional<gdb::byte_vector> spu_data
|
||||||
annex, &spu_data);
|
= target_read_alloc (¤t_target, TARGET_OBJECT_SPU, annex);
|
||||||
if (spu_len > 0)
|
|
||||||
|
if (spu_data && !spu_data->empty ())
|
||||||
{
|
{
|
||||||
xsnprintf (note_name, sizeof note_name, "SPU/%s", annex);
|
xsnprintf (note_name, sizeof note_name, "SPU/%s", annex);
|
||||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||||
note_name, NT_SPU,
|
note_name, NT_SPU,
|
||||||
spu_data, spu_len);
|
spu_data->data (),
|
||||||
xfree (spu_data);
|
spu_data->size ());
|
||||||
|
|
||||||
if (!note_data)
|
if (!note_data)
|
||||||
{
|
return nullptr;
|
||||||
xfree (spu_ids);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
xfree (spu_ids);
|
|
||||||
|
|
||||||
return note_data;
|
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 linux_corefile_thread_data thread_args;
|
||||||
struct elf_internal_linux_prpsinfo prpsinfo;
|
struct elf_internal_linux_prpsinfo prpsinfo;
|
||||||
char *note_data = NULL;
|
char *note_data = NULL;
|
||||||
gdb_byte *auxv;
|
|
||||||
int auxv_len;
|
|
||||||
struct thread_info *curr_thr, *signalled_thr, *thr;
|
struct thread_info *curr_thr, *signalled_thr, *thr;
|
||||||
|
|
||||||
if (! gdbarch_iterate_over_regset_sections_p (gdbarch))
|
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;
|
return NULL;
|
||||||
|
|
||||||
/* Auxillary vector. */
|
/* Auxillary vector. */
|
||||||
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
|
gdb::optional<gdb::byte_vector> auxv =
|
||||||
NULL, &auxv);
|
target_read_alloc (¤t_target, TARGET_OBJECT_AUXV, NULL);
|
||||||
if (auxv_len > 0)
|
if (auxv && !auxv->empty ())
|
||||||
{
|
{
|
||||||
note_data = elfcore_write_note (obfd, note_data, note_size,
|
note_data = elfcore_write_note (obfd, note_data, note_size,
|
||||||
"CORE", NT_AUXV, auxv, auxv_len);
|
"CORE", NT_AUXV, auxv->data (),
|
||||||
xfree (auxv);
|
auxv->size ());
|
||||||
|
|
||||||
if (!note_data)
|
if (!note_data)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -163,11 +163,11 @@ std::unique_ptr<osdata>
|
||||||
get_osdata (const char *type)
|
get_osdata (const char *type)
|
||||||
{
|
{
|
||||||
std::unique_ptr<osdata> osdata;
|
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)
|
||||||
{
|
{
|
||||||
if (xml.get ()[0] == '\0')
|
if ((*xml)[0] == '\0')
|
||||||
{
|
{
|
||||||
if (type)
|
if (type)
|
||||||
warning (_("Empty data returned by target. Wrong osdata 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?"));
|
warning (_("Empty type list returned by target. No type data?"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
osdata = osdata_parse (xml.get ());
|
osdata = osdata_parse (xml->data ());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osdata == NULL)
|
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 defined(HAVE_LIBEXPAT)
|
||||||
if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
|
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);
|
= 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",
|
gdb_xml_parse_quick (_("threads"), "threads.dtd",
|
||||||
threads_elements, xml.get (), context);
|
threads_elements, xml->data (), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -10790,11 +10790,11 @@ static std::vector<mem_region>
|
||||||
remote_memory_map (struct target_ops *ops)
|
remote_memory_map (struct target_ops *ops)
|
||||||
{
|
{
|
||||||
std::vector<mem_region> result;
|
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);
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_MEMORY_MAP, NULL);
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
result = parse_memory_map (text.get ());
|
result = parse_memory_map (text->data ());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -12905,11 +12905,11 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val)
|
||||||
static traceframe_info_up
|
static traceframe_info_up
|
||||||
remote_traceframe_info (struct target_ops *self)
|
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,
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_TRACEFRAME_INFO,
|
||||||
NULL);
|
NULL);
|
||||||
if (text != NULL)
|
if (text)
|
||||||
return parse_traceframe_info (text.get ());
|
return parse_traceframe_info (text->data ());
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -13137,10 +13137,10 @@ btrace_sync_conf (const struct btrace_config *conf)
|
||||||
static void
|
static void
|
||||||
btrace_read_config (struct btrace_config *conf)
|
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, "");
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE_CONF, "");
|
||||||
if (xml != NULL)
|
if (xml)
|
||||||
parse_xml_btrace_conf (conf, xml.get ());
|
parse_xml_btrace_conf (conf, xml->data ());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Maybe reopen target btrace. */
|
/* Maybe reopen target btrace. */
|
||||||
|
@ -13337,12 +13337,12 @@ remote_read_btrace (struct target_ops *self,
|
||||||
(unsigned int) type);
|
(unsigned int) type);
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char> xml
|
gdb::optional<gdb::char_vector> xml
|
||||||
= target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE, annex);
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_BTRACE, annex);
|
||||||
if (xml == NULL)
|
if (!xml)
|
||||||
return BTRACE_ERR_UNKNOWN;
|
return BTRACE_ERR_UNKNOWN;
|
||||||
|
|
||||||
parse_xml_btrace (btrace, xml.get ());
|
parse_xml_btrace (btrace, xml->data ());
|
||||||
|
|
||||||
return BTRACE_ERR_NONE;
|
return BTRACE_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -13376,7 +13376,7 @@ remote_load (struct target_ops *self, const char *name, int from_tty)
|
||||||
static char *
|
static char *
|
||||||
remote_pid_to_exec_file (struct target_ops *self, int pid)
|
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;
|
struct inferior *inf;
|
||||||
char *annex = NULL;
|
char *annex = NULL;
|
||||||
|
|
||||||
|
@ -13399,7 +13399,7 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
|
||||||
filename = target_read_stralloc (¤t_target,
|
filename = target_read_stralloc (¤t_target,
|
||||||
TARGET_OBJECT_EXEC_FILE, annex);
|
TARGET_OBJECT_EXEC_FILE, annex);
|
||||||
|
|
||||||
return filename.get ();
|
return filename ? filename->data () : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement the to_can_do_single_step target_ops method. */
|
/* 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)
|
if (data->library_list != NULL)
|
||||||
return data->library_list;
|
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,
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_AIX,
|
||||||
NULL);
|
NULL);
|
||||||
if (library_document == NULL && warning_msg != NULL)
|
if (!library_document && warning_msg != NULL)
|
||||||
{
|
{
|
||||||
warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
|
warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
|
||||||
warning_msg);
|
warning_msg);
|
||||||
|
@ -292,9 +292,9 @@ solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
|
||||||
if (solib_aix_debug)
|
if (solib_aix_debug)
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
"DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
|
"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)
|
if (data->library_list == NULL && warning_msg != NULL)
|
||||||
{
|
{
|
||||||
warning (_("%s (missing XML support?)"), warning_msg);
|
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. */
|
/* Decode int_elf32_dsbt_loadmap from BUF. */
|
||||||
|
|
||||||
static struct int_elf32_dsbt_loadmap *
|
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 ());
|
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;
|
struct int_elf32_dsbt_loadmap *int_ldmbuf;
|
||||||
|
|
||||||
int version, seg, nsegs;
|
int version, seg, nsegs;
|
||||||
|
@ -278,7 +278,6 @@ decode_loadmap (gdb_byte *buf)
|
||||||
byte_order);
|
byte_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree (ext_ldmbuf);
|
|
||||||
return int_ldmbuf;
|
return int_ldmbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,26 +291,26 @@ static struct dsbt_info *get_dsbt_info (void);
|
||||||
static void
|
static void
|
||||||
dsbt_get_initial_loadmaps (void)
|
dsbt_get_initial_loadmaps (void)
|
||||||
{
|
{
|
||||||
gdb_byte *buf;
|
|
||||||
struct dsbt_info *info = get_dsbt_info ();
|
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,
|
if (!buf || buf->empty ())
|
||||||
"exec", &buf))
|
|
||||||
{
|
{
|
||||||
info->exec_loadmap = NULL;
|
info->exec_loadmap = NULL;
|
||||||
error (_("Error reading DSBT exec loadmap"));
|
error (_("Error reading DSBT exec loadmap"));
|
||||||
}
|
}
|
||||||
info->exec_loadmap = decode_loadmap (buf);
|
info->exec_loadmap = decode_loadmap (buf->data ());
|
||||||
if (solib_dsbt_debug)
|
if (solib_dsbt_debug)
|
||||||
dsbt_print_loadmap (info->exec_loadmap);
|
dsbt_print_loadmap (info->exec_loadmap);
|
||||||
|
|
||||||
if (0 >= target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC,
|
buf = target_read_alloc (¤t_target, TARGET_OBJECT_FDPIC, "exec");
|
||||||
"interp", &buf))
|
if (!buf || buf->empty ())
|
||||||
{
|
{
|
||||||
info->interp_loadmap = NULL;
|
info->interp_loadmap = NULL;
|
||||||
error (_("Error reading DSBT interp loadmap"));
|
error (_("Error reading DSBT interp loadmap"));
|
||||||
}
|
}
|
||||||
info->interp_loadmap = decode_loadmap (buf);
|
info->interp_loadmap = decode_loadmap (buf->data ());
|
||||||
if (solib_dsbt_debug)
|
if (solib_dsbt_debug)
|
||||||
dsbt_print_loadmap (info->interp_loadmap);
|
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 ());
|
gdb_assert (annex == NULL || target_augmented_libraries_svr4_read ());
|
||||||
|
|
||||||
/* Fetch the list of shared libraries. */
|
/* 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,
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES_SVR4,
|
||||||
annex);
|
annex);
|
||||||
if (svr4_library_document == NULL)
|
if (!svr4_library_document)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return svr4_parse_libraries (svr4_library_document.get (), list);
|
return svr4_parse_libraries (svr4_library_document->data (), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -257,13 +257,13 @@ solib_target_current_sos (void)
|
||||||
int ix;
|
int ix;
|
||||||
|
|
||||||
/* Fetch the list of shared libraries. */
|
/* 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);
|
= target_read_stralloc (¤t_target, TARGET_OBJECT_LIBRARIES, NULL);
|
||||||
if (library_document == NULL)
|
if (!library_document)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Parse the list. */
|
/* 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)
|
if (library_list == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
86
gdb/target.c
86
gdb/target.c
|
@ -48,6 +48,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "byte-vector.h"
|
#include "byte-vector.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
|
static void generic_tls_error (void) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
|
@ -1937,18 +1938,17 @@ target_write (struct target_ops *ops,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read OBJECT/ANNEX using OPS. Store the result in *BUF_P and return
|
/* Help for target_read_alloc and target_read_stralloc. See their comments
|
||||||
the size of the transferred data. PADDING additional bytes are
|
for details. */
|
||||||
available in *BUF_P. This is a helper function for
|
|
||||||
target_read_alloc; see the declaration of that function for more
|
|
||||||
information. */
|
|
||||||
|
|
||||||
static LONGEST
|
template <typename T>
|
||||||
|
gdb::optional<gdb::def_vector<T>>
|
||||||
target_read_alloc_1 (struct target_ops *ops, enum target_object object,
|
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::def_vector<T> buf;
|
||||||
gdb_byte *buf;
|
size_t buf_pos = 0;
|
||||||
|
const int chunk = 4096;
|
||||||
|
|
||||||
/* This function does not have a length parameter; it reads the
|
/* This function does not have a length parameter; it reads the
|
||||||
entire OBJECT). Also, it doesn't support objects fetched partly
|
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
|
/* Start by reading up to 4K at a time. The target will throttle
|
||||||
this number down if necessary. */
|
this number down if necessary. */
|
||||||
buf_alloc = 4096;
|
|
||||||
buf = (gdb_byte *) xmalloc (buf_alloc);
|
|
||||||
buf_pos = 0;
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
ULONGEST xfered_len;
|
ULONGEST xfered_len;
|
||||||
enum target_xfer_status status;
|
enum target_xfer_status status;
|
||||||
|
|
||||||
status = target_read_partial (ops, object, annex, &buf[buf_pos],
|
buf.resize (buf_pos + chunk);
|
||||||
buf_pos, buf_alloc - buf_pos - padding,
|
|
||||||
|
status = target_read_partial (ops, object, annex,
|
||||||
|
(gdb_byte *) &buf[buf_pos],
|
||||||
|
buf_pos, chunk,
|
||||||
&xfered_len);
|
&xfered_len);
|
||||||
|
|
||||||
if (status == TARGET_XFER_EOF)
|
if (status == TARGET_XFER_EOF)
|
||||||
{
|
{
|
||||||
/* Read all there was. */
|
/* Read all there was. */
|
||||||
if (buf_pos == 0)
|
buf.resize (buf_pos);
|
||||||
xfree (buf);
|
return buf;
|
||||||
else
|
|
||||||
*buf_p = buf;
|
|
||||||
return buf_pos;
|
|
||||||
}
|
}
|
||||||
else if (status != TARGET_XFER_OK)
|
else if (status != TARGET_XFER_OK)
|
||||||
{
|
{
|
||||||
/* An error occurred. */
|
/* An error occurred. */
|
||||||
xfree (buf);
|
return {};
|
||||||
return TARGET_XFER_E_IO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_pos += xfered_len;
|
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;
|
QUIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read OBJECT/ANNEX using OPS. Store the result in *BUF_P and return
|
/* See target.h */
|
||||||
the size of the transferred data. See the declaration in "target.h"
|
|
||||||
function for more information about the return value. */
|
|
||||||
|
|
||||||
LONGEST
|
gdb::optional<gdb::byte_vector>
|
||||||
target_read_alloc (struct target_ops *ops, enum target_object object,
|
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. */
|
/* See target.h. */
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char>
|
gdb::optional<gdb::char_vector>
|
||||||
target_read_stralloc (struct target_ops *ops, enum target_object object,
|
target_read_stralloc (struct target_ops *ops, enum target_object object,
|
||||||
const char *annex)
|
const char *annex)
|
||||||
{
|
{
|
||||||
gdb_byte *buffer;
|
gdb::optional<gdb::char_vector> buf
|
||||||
char *bufstr;
|
= target_read_alloc_1<char> (ops, object, annex);
|
||||||
LONGEST i, transferred;
|
|
||||||
|
|
||||||
transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
|
if (!buf)
|
||||||
bufstr = (char *) buffer;
|
return {};
|
||||||
|
|
||||||
if (transferred < 0)
|
if (buf->back () != '\0')
|
||||||
return NULL;
|
buf->push_back ('\0');
|
||||||
|
|
||||||
if (transferred == 0)
|
|
||||||
return gdb::unique_xmalloc_ptr<char> (xstrdup (""));
|
|
||||||
|
|
||||||
bufstr[transferred] = 0;
|
|
||||||
|
|
||||||
/* Check for embedded NUL bytes; but allow trailing NULs. */
|
/* Check for embedded NUL bytes; but allow trailing NULs. */
|
||||||
for (i = strlen (bufstr); i < transferred; i++)
|
for (auto it = std::find (buf->begin (), buf->end (), '\0');
|
||||||
if (bufstr[i] != 0)
|
it != buf->end (); it++)
|
||||||
|
if (*it != '\0')
|
||||||
{
|
{
|
||||||
warning (_("target object %d, annex %s, "
|
warning (_("target object %d, annex %s, "
|
||||||
"contained unexpected null characters"),
|
"contained unexpected null characters"),
|
||||||
|
@ -2042,7 +2024,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gdb::unique_xmalloc_ptr<char> (bufstr);
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory transfer methods. */
|
/* Memory transfer methods. */
|
||||||
|
@ -2744,7 +2726,7 @@ target_supports_multi_process (void)
|
||||||
|
|
||||||
/* See target.h. */
|
/* See target.h. */
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char>
|
gdb::optional<gdb::char_vector>
|
||||||
target_get_osdata (const char *type)
|
target_get_osdata (const char *type)
|
||||||
{
|
{
|
||||||
struct target_ops *t;
|
struct target_ops *t;
|
||||||
|
@ -2758,7 +2740,7 @@ target_get_osdata (const char *type)
|
||||||
t = find_default_run_target ("get OS data");
|
t = find_default_run_target ("get OS data");
|
||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return {};
|
||||||
|
|
||||||
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
|
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 (*progress) (ULONGEST, void *),
|
||||||
void *baton);
|
void *baton);
|
||||||
|
|
||||||
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will
|
/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will be read
|
||||||
be read using OPS. The return value will be -1 if the transfer
|
using OPS. The return value will be uninstantiated if the transfer fails or
|
||||||
fails or is not supported; 0 if the object is empty; or the length
|
is not supported.
|
||||||
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.
|
|
||||||
|
|
||||||
This method should be used for objects sufficiently small to store
|
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
|
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
|
size is known in advance. Don't try to read TARGET_OBJECT_MEMORY
|
||||||
through this function. */
|
through this function. */
|
||||||
|
|
||||||
extern LONGEST target_read_alloc (struct target_ops *ops,
|
extern gdb::optional<gdb::byte_vector> target_read_alloc
|
||||||
enum target_object object,
|
(struct target_ops *ops, enum target_object object, const char *annex);
|
||||||
const char *annex, gdb_byte **buf_p);
|
|
||||||
|
|
||||||
/* Read OBJECT/ANNEX using OPS. The result is NUL-terminated and
|
/* Read OBJECT/ANNEX using OPS. The result is a NUL-terminated character vector
|
||||||
returned as a string. If an error occurs or the transfer is
|
(therefore usable as a NUL-terminated string). If an error occurs or the
|
||||||
unsupported, NULL is returned. Empty objects are returned as
|
transfer is unsupported, the return value will be uninstantiated. Empty
|
||||||
allocated but empty strings. A warning is issued if the result
|
objects are returned as allocated but empty strings. Therefore, on success,
|
||||||
contains any embedded NUL bytes. */
|
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);
|
(struct target_ops *ops, enum target_object object, const char *annex);
|
||||||
|
|
||||||
/* See target_ops->to_xfer_partial. */
|
/* 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);
|
struct target_ops *find_target_at (enum strata stratum);
|
||||||
|
|
||||||
/* Read OS data object of type TYPE from the target, and return it in
|
/* Read OS data object of type TYPE from the target, and return it in XML
|
||||||
XML format. The result is NUL-terminated and returned as a string.
|
format. The return value follows the same rules as target_read_stralloc. */
|
||||||
If an error occurs or the transfer is unsupported, NULL is
|
|
||||||
returned. Empty objects are returned as allocated but empty
|
|
||||||
strings. */
|
|
||||||
|
|
||||||
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. */
|
/* Stuff that should be shared among the various remote targets. */
|
||||||
|
|
||||||
/* Debugging level. 0 is off, and non-zero values mean to print some debug
|
/* 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,
|
sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
|
||||||
void *ignore)
|
void *ignore)
|
||||||
{
|
{
|
||||||
LONGEST size;
|
|
||||||
gdb_byte *buf;
|
|
||||||
|
|
||||||
/* We need to read the whole object before we know its size. */
|
/* We need to read the whole object before we know its size. */
|
||||||
size = target_read_alloc (¤t_target,
|
gdb::optional<gdb::byte_vector> buf
|
||||||
TARGET_OBJECT_STATIC_TRACE_DATA,
|
= target_read_alloc (¤t_target, TARGET_OBJECT_STATIC_TRACE_DATA,
|
||||||
NULL, &buf);
|
NULL);
|
||||||
if (size >= 0)
|
if (buf)
|
||||||
{
|
{
|
||||||
struct value *v;
|
struct value *v;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
|
|
||||||
type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
|
type = init_vector_type (builtin_type (gdbarch)->builtin_true_char,
|
||||||
size);
|
buf->size ());
|
||||||
v = allocate_value (type);
|
v = allocate_value (type);
|
||||||
memcpy (value_contents_raw (v), buf, size);
|
memcpy (value_contents_raw (v), buf->data (), buf->size ());
|
||||||
xfree (buf);
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -793,13 +793,13 @@ xinclude_start_include (struct gdb_xml_parser *parser,
|
||||||
gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
|
gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
|
||||||
MAX_XINCLUDE_DEPTH);
|
MAX_XINCLUDE_DEPTH);
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char> text = data->fetcher (href,
|
gdb::optional<gdb::char_vector> text
|
||||||
data->fetcher_baton);
|
= data->fetcher (href, data->fetcher_baton);
|
||||||
if (text == NULL)
|
if (!text)
|
||||||
gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
|
gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
|
||||||
|
|
||||||
if (!xml_process_xincludes (data->output, parser->name (),
|
if (!xml_process_xincludes (data->output, parser->name (),
|
||||||
text.get (), data->fetcher,
|
text->data (), data->fetcher,
|
||||||
data->fetcher_baton,
|
data->fetcher_baton,
|
||||||
data->include_depth + 1))
|
data->include_depth + 1))
|
||||||
gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
|
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);
|
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)
|
xml_fetch_content_from_file (const char *filename, void *baton)
|
||||||
{
|
{
|
||||||
const char *dirname = (const char *) 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);
|
file = gdb_fopen_cloexec (filename, FOPEN_RT);
|
||||||
|
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
return NULL;
|
return {};
|
||||||
|
|
||||||
/* Read in the whole file. */
|
/* Read in the whole file. */
|
||||||
|
|
||||||
|
@ -1001,16 +1001,16 @@ xml_fetch_content_from_file (const char *filename, void *baton)
|
||||||
len = ftell (file.get ());
|
len = ftell (file.get ());
|
||||||
rewind (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 ()))
|
|| ferror (file.get ()))
|
||||||
{
|
{
|
||||||
warning (_("Read error from \"%s\""), filename);
|
warning (_("Read error from \"%s\""), filename);
|
||||||
return NULL;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
text.get ()[len] = '\0';
|
text.back () = '\0';
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "gdb_obstack.h"
|
#include "gdb_obstack.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
#include "xml-utils.h"
|
#include "xml-utils.h"
|
||||||
|
#include "common/byte-vector.h"
|
||||||
|
|
||||||
struct gdb_xml_parser;
|
struct gdb_xml_parser;
|
||||||
struct gdb_xml_element;
|
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. */
|
/* Callback to fetch a new XML file, based on the provided HREF. */
|
||||||
|
|
||||||
typedef gdb::unique_xmalloc_ptr<char> (*xml_fetch_another) (const char *href,
|
typedef gdb::optional<gdb::char_vector> (*xml_fetch_another) (const char *href,
|
||||||
void *baton);
|
void *baton);
|
||||||
|
|
||||||
/* Append the expansion of TEXT after processing <xi:include> tags in
|
/* Append the expansion of TEXT after processing <xi:include> tags in
|
||||||
RESULT. FETCHER will be called (with FETCHER_BATON) to retrieve
|
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);
|
const char *value);
|
||||||
|
|
||||||
/* Open FILENAME, read all its text into memory, close it, and return
|
/* 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);
|
(const char *filename, void *baton);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -305,12 +305,12 @@ syscall_parse_xml (const char *document, xml_fetch_another fetcher,
|
||||||
static struct syscalls_info *
|
static struct syscalls_info *
|
||||||
xml_init_syscalls_info (const char *filename)
|
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);
|
= xml_fetch_content_from_file (filename, gdb_datadir);
|
||||||
if (full_file == NULL)
|
if (!full_file)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return syscall_parse_xml (full_file.get (),
|
return syscall_parse_xml (full_file->data (),
|
||||||
xml_fetch_content_from_file,
|
xml_fetch_content_from_file,
|
||||||
(void *) ldirname (filename).c_str ());
|
(void *) ldirname (filename).c_str ());
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,15 +668,15 @@ tdesc_parse_xml (const char *document, xml_fetch_another fetcher,
|
||||||
const struct target_desc *
|
const struct target_desc *
|
||||||
file_read_description_xml (const char *filename)
|
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);
|
= xml_fetch_content_from_file (filename, NULL);
|
||||||
if (tdesc_str == NULL)
|
if (!tdesc_str)
|
||||||
{
|
{
|
||||||
warning (_("Could not open \"%s\""), filename);
|
warning (_("Could not open \"%s\""), filename);
|
||||||
return NULL;
|
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 ());
|
(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
|
is "target.xml". Other calls may be performed for the DTD or
|
||||||
for <xi:include>. */
|
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_)
|
fetch_available_features_from_target (const char *name, void *baton_)
|
||||||
{
|
{
|
||||||
struct target_ops *ops = (struct target_ops *) 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 *
|
const struct target_desc *
|
||||||
target_read_description_xml (struct target_ops *ops)
|
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);
|
= fetch_available_features_from_target ("target.xml", ops);
|
||||||
if (tdesc_str == NULL)
|
if (!tdesc_str)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return tdesc_parse_xml (tdesc_str.get (),
|
return tdesc_parse_xml (tdesc_str->data (),
|
||||||
fetch_available_features_from_target,
|
fetch_available_features_from_target,
|
||||||
ops);
|
ops);
|
||||||
}
|
}
|
||||||
|
@ -735,15 +735,15 @@ target_fetch_description_xml (struct target_ops *ops)
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
#else
|
#else
|
||||||
gdb::unique_xmalloc_ptr<char>
|
gdb::optional<gdb::char_vector>
|
||||||
tdesc_str = fetch_available_features_from_target ("target.xml", ops);
|
tdesc_str = fetch_available_features_from_target ("target.xml", ops);
|
||||||
if (tdesc_str == NULL)
|
if (!tdesc_str)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::string output;
|
std::string output;
|
||||||
if (!xml_process_xincludes (output,
|
if (!xml_process_xincludes (output,
|
||||||
_("target description"),
|
_("target description"),
|
||||||
tdesc_str.get (),
|
tdesc_str->data (),
|
||||||
fetch_available_features_from_target, ops, 0))
|
fetch_available_features_from_target, ops, 0))
|
||||||
{
|
{
|
||||||
warning (_("Could not load XML target description; ignoring"));
|
warning (_("Could not load XML target description; ignoring"));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue