3 Commits

Author SHA1 Message Date
9018be22e0 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.
2018-04-07 13:19:12 -04:00
e2882c8578 Update copyright year range in all GDB files
gdb/ChangeLog:

        Update copyright year range in all GDB files
2018-01-02 07:38:06 +04:00
d5722aa2fe Introduce gdb::byte_vector, add allocator that default-initializes
In some cases we've been replacing heap-allocated gdb_byte buffers
managed with xmalloc/make_cleanup(xfree) with gdb::vector<gdb_byte>.
That usually pessimizes the code a little bit because std::vector
value-initializes elements (which for gdb_byte means
zero-initialization), while if you're creating a temporary buffer,
you're most certaintly going to fill it in with some data.  An
alternative is to use

  unique_ptr<gdb_byte[]> buf (new gdb_byte[size]);

but it looks like that's not very popular.

Recently, a use of obstacks in dwarf2read.c was replaced with
std::vector<gdb_byte> and that as well introduced a pessimization for
always memsetting the buffer when it's garanteed that the zeros will
be overwritten immediately.  (see dwarf2read.c change in this patch to
find it.)

So here's a different take at addressing this issue "by design":

#1 - Introduce default_init_allocator<T>

I.e., a custom allocator that does default construction using default
initialization, meaning, no more zero initialization.  That's the
default_init_allocation<T> class added in this patch.

See "Notes" at
<http://en.cppreference.com/w/cpp/container/vector/resize>.

#2 - Introduce def_vector<T>

I.e., a convenience typedef, because typing the allocator is annoying:

  using def_vector<T> = std::vector<T, gdb::default_init_allocator<T>>;

#3 - Introduce byte_vector

Because gdb_byte vectors will be the common thing, add a convenience
"byte_vector" typedef:

  using byte_vector = def_vector<gdb_byte>;

which is really the same as:

  std::vector<gdb_byte, gdb::default_init_allocator<gdb_byte>>;

The intent then is to make "gdb::byte_vector" be the go-to for dynamic
byte buffers.  So the less friction, the better.

#4 - Adjust current code to use it.

To set the example going forward.  Replace std::vector uses and also
unique_ptr<byte[]> uses.

One nice thing is that with this allocator, for changes like these:

  -std::unique_ptr<byte[]> buf (new gdb_byte[some_size]);
  +gdb::byte_vector buf (some_size);
   fill_with_data (buf.data (), buf.size ());

the generated code is the same as before.  I.e., the compiler
de-structures the vector and gets rid of the unused "reserved vs size"
related fields.

The other nice thing is that it's easier to write
  gdb::byte_vector buf (size);
than
  std::unique_ptr<gdb_byte[]> buf (new gdb_byte[size]);
or even (C++14):
  auto buf = std::make_unique<gdb_byte[]> (size); // zero-initializes...

#5 - Suggest s/std::vector<gdb_byte>/gdb::byte_vector/ going forward.

Note that this commit actually fixes a couple of bugs where the current
code is incorrectly using "std::vector::reserve(new_size)" and then
accessing the vector's internal buffer beyond the vector's size: see
dwarf2loc.c and charset.c.  That's undefined behavior and may trigger
debug mode assertion failures.  With default_init_allocator,
"resize()" behaves like "reserve()" performance wise, in that it
leaves new elements with unspecified values, but, it does that safely
without triggering undefined behavior when you access those values.

gdb/ChangeLog:
2017-06-14  Pedro Alves  <palves@redhat.com>

	* ada-lang.c: Include "common/byte-vector.h".
	(ada_value_primitive_packed_val): Use gdb::byte_vector.
	* charset.c (wchar_iterator::iterate): Resize the vector instead
	of reserving it.
	* common/byte-vector.h: Include "common/def-vector.h".
	(wchar_iterator::m_out): Now a gdb::def_vector<gdb_wchar_t>.
	* cli/cli-dump.c: Include "common/byte-vector.h".
	(dump_memory_to_file, restore_binary_file): Use gdb::byte_vector.
	* common/byte-vector.h: New file.
	* common/def-vector.h: New file.
	* common/default-init-alloc.h: New file.
	* dwarf2loc.c: Include "common/byte-vector.h".
	(rw_pieced_value): Use gdb::byte_vector, and resize the vector
	instead of reserving it.
	* dwarf2read.c: Include "common/byte-vector.h".
	(data_buf::m_vec): Now a gdb::byte_vector.
	* gdb_regex.c: Include "common/def-vector.h".
	(compiled_regex::compiled_regex): Use gdb::def_vector<char>.
	* mi/mi-main.c: Include "common/byte-vector.h".
	(mi_cmd_data_read_memory): Use gdb::byte_vector.
	* printcmd.c: Include "common/byte-vector.h".
	(print_scalar_formatted): Use gdb::byte_vector.
	* valprint.c: Include "common/byte-vector.h".
	(maybe_negate_by_bytes, print_decimal_chars): Use
	gdb::byte_vector.
2017-06-14 11:08:52 +01:00