+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-13 Simon Marchi <simon.marchi@ericsson.com>
* darwin-nat.c: Include "nat/fork-inferior.h".
#include "arch-utils.h"
#include "cli/cli-utils.h"
#include "common/function-view.h"
+#include "common/byte-vector.h"
/* Define whether or not the C operator '/' truncates towards zero for
differently signed operands (truncation direction is undefined in C).
gdb_byte *unpacked;
const int is_scalar = is_scalar_type (type);
const int is_big_endian = gdbarch_bits_big_endian (get_type_arch (type));
- std::unique_ptr<gdb_byte[]> staging;
- int staging_len = 0;
+ gdb::byte_vector staging;
type = ada_check_typedef (type);
packed, and therefore maybe not at a byte boundary. So, what
we do, is unpack the data into a byte-aligned buffer, and then
use that buffer as our object's value for resolving the type. */
- staging_len = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
- staging.reset (new gdb_byte[staging_len]);
+ int staging_len = (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+ staging.resize (staging_len);
ada_unpack_from_contents (src, bit_offset, bit_size,
- staging.get (), staging_len,
+ staging.data (), staging.size (),
is_big_endian, has_negatives (type),
is_scalar);
- type = resolve_dynamic_type (type, staging.get (), 0);
+ type = resolve_dynamic_type (type, staging.data (), 0);
if (TYPE_LENGTH (type) < (bit_size + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT)
{
/* This happens when the length of the object is dynamic,
return v;
}
- if (staging != NULL && staging_len == TYPE_LENGTH (type))
+ if (staging.size () == TYPE_LENGTH (type))
{
/* Small short-cut: If we've unpacked the data into a buffer
of the same size as TYPE's length, then we can reuse that,
instead of doing the unpacking again. */
- memcpy (unpacked, staging.get (), staging_len);
+ memcpy (unpacked, staging.data (), staging.size ());
}
else
ada_unpack_from_contents (src, bit_offset, bit_size,
++out_request;
if (out_request > m_out.size ())
- m_out.reserve (out_request);
+ m_out.resize (out_request);
continue;
case EINVAL:
#ifndef CHARSET_H
#define CHARSET_H
-#include <vector>
+#include "common/def-vector.h"
/* If the target program uses a different character set than the host,
GDB has some support for translating between the two; GDB converts
size_t m_width;
/* The output buffer. */
- std::vector<gdb_wchar_t> m_out;
+ gdb::def_vector<gdb_wchar_t> m_out;
};
\f
#include "cli/cli-utils.h"
#include "gdb_bfd.h"
#include "filestuff.h"
-
+#include "common/byte-vector.h"
static const char *
scan_expression_with_cleanup (const char **cmd, const char *def)
/* FIXME: Should use read_memory_partial() and a magic blocking
value. */
- std::unique_ptr<gdb_byte[]> buf (new gdb_byte[count]);
- read_memory (lo, buf.get (), count);
+ gdb::byte_vector buf (count);
+ read_memory (lo, buf.data (), count);
/* Have everything. Open/write the data. */
if (file_format == NULL || strcmp (file_format, "binary") == 0)
{
- dump_binary_file (filename, mode, buf.get (), count);
+ dump_binary_file (filename, mode, buf.data (), count);
}
else
{
- dump_bfd_file (filename, mode, file_format, lo, buf.get (), count);
+ dump_bfd_file (filename, mode, file_format, lo, buf.data (), count);
}
do_cleanups (old_cleanups);
perror_with_name (filename);
/* Now allocate a buffer and read the file contents. */
- std::unique_ptr<gdb_byte[]> buf (new gdb_byte[len]);
- if (fread (buf.get (), 1, len, file) != len)
+ gdb::byte_vector buf (len);
+ if (fread (buf.data (), 1, len, file) != len)
perror_with_name (filename);
/* Now write the buffer into target memory. */
len = target_write_memory (data->load_start + data->load_offset,
- buf.get (), len);
+ buf.data (), len);
if (len != 0)
warning (_("restore: memory write failed (%s)."), safe_strerror (len));
do_cleanups (cleanup);
--- /dev/null
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_BYTE_VECTOR_H
+#define COMMON_BYTE_VECTOR_H
+
+#include "common/def-vector.h"
+
+namespace gdb {
+
+/* byte_vector is a gdb_byte std::vector with a custom allocator that
+ unlike std::vector<gdb_byte> does not zero-initialize new elements
+ by default when the vector is created/resized. This is what you
+ usually want when working with byte buffers, since if you're
+ creating or growing a buffer you'll most surely want to fill it in
+ with data, in which case zero-initialization would be a
+ pessimization. For example:
+
+ gdb::byte_vector buf (some_large_size);
+ fill_with_data (buf.data (), buf.size ());
+
+ On the odd case you do need zero initialization, then you can still
+ call the overloads that specify an explicit value, like:
+
+ gdb::byte_vector buf (some_initial_size, 0);
+ buf.resize (a_bigger_size, 0);
+
+ (Or use std::vector<gdb_byte> instead.)
+
+ Note that unlike std::vector<gdb_byte>, function local
+ gdb::byte_vector objects constructed with an initial size like:
+
+ gdb::byte_vector buf (some_size);
+ fill_with_data (buf.data (), buf.size ());
+
+ usually compile down to the exact same as:
+
+ std::unique_ptr<byte[]> buf (new gdb_byte[some_size]);
+ fill_with_data (buf.get (), some_size);
+
+ with the former having the advantage of being a bit more readable,
+ and providing the whole std::vector API, if you end up needing it.
+*/
+using byte_vector = gdb::def_vector<gdb_byte>;
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEF_VECTOR_H */
--- /dev/null
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_DEF_VECTOR_H
+#define COMMON_DEF_VECTOR_H
+
+#include <vector>
+#include "common/default-init-alloc.h"
+
+namespace gdb {
+
+/* A vector that uses an allocator that default constructs using
+ default-initialization rather than value-initialization. The idea
+ is to use this when you don't want zero-initialization of elements
+ of vectors of trivial types. E.g., byte buffers. */
+
+template<typename T> using def_vector
+ = std::vector<T, gdb::default_init_allocator<T>>;
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEF_VECTOR_H */
--- /dev/null
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef COMMON_DEFAULT_INIT_ALLOC_H
+#define COMMON_DEFAULT_INIT_ALLOC_H
+
+namespace gdb {
+
+/* An allocator that default constructs using default-initialization
+ rather than value-initialization. The idea is to use this when you
+ don't want to default construct elements of containers of trivial
+ types using zero-initialization. */
+
+/* Mostly as implementation convenience, this is implemented as an
+ adapter that given an allocator A, overrides 'A::construct()'. 'A'
+ defaults to std::allocator<T>. */
+
+template<typename T, typename A = std::allocator<T>>
+class default_init_allocator : public A
+{
+public:
+ /* Pull in A's ctors. */
+ using A::A;
+
+ /* Override rebind. */
+ template<typename U>
+ struct rebind
+ {
+ /* A couple helpers just to make it a bit more readable. */
+ typedef std::allocator_traits<A> traits_;
+ typedef typename traits_::template rebind_alloc<U> alloc_;
+
+ /* This is what we're after. */
+ typedef default_init_allocator<U, alloc_> other;
+ };
+
+ /* Make the base allocator's construct method(s) visible. */
+ using A::construct;
+
+ /* .. and provide an override/overload for the case of default
+ construction (i.e., no arguments). This is where we construct
+ with default-init. */
+ template <typename U>
+ void construct (U *ptr)
+ noexcept (std::is_nothrow_default_constructible<U>::value)
+ {
+ ::new ((void *) ptr) U; /* default-init */
+ }
+};
+
+} /* namespace gdb */
+
+#endif /* COMMON_DEFAULT_INIT_ALLOC_H */
#include <vector>
#include <unordered_set>
#include "common/underlying.h"
+#include "common/byte-vector.h"
extern int dwarf_always_disassemble;
const gdb_byte *from_contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (v);
- std::vector<gdb_byte> buffer;
+ gdb::byte_vector buffer;
int bits_big_endian
= gdbarch_bits_big_endian (get_type_arch (value_type (v)));
bits_to_skip += p->offset;
this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.reserve (this_size);
+ buffer.resize (this_size);
if (from == NULL)
{
}
this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.reserve (this_size);
+ buffer.resize (this_size);
if (from == NULL)
{
#include "common/function-view.h"
#include "common/gdb_optional.h"
#include "common/underlying.h"
+#include "common/byte-vector.h"
#include <fcntl.h>
#include <sys/types.h>
return &*m_vec.end () - size;
}
- std::vector<gdb_byte> m_vec;
+ gdb::byte_vector m_vec;
};
/* An entry in the symbol table. */
#include "defs.h"
#include "gdb_regex.h"
+#include "common/def-vector.h"
compiled_regex::compiled_regex (const char *regex, int cflags,
const char *message)
if (code != 0)
{
size_t length = regerror (code, &m_pattern, NULL, 0);
- std::unique_ptr<char[]> err (new char[length]);
+ gdb::def_vector<char> err (length);
- regerror (code, &m_pattern, err.get (), length);
- error (("%s: %s"), message, err.get ());
+ regerror (code, &m_pattern, err.data (), length);
+ error (("%s: %s"), message, err.data ());
}
}
#include "gdbcmd.h"
#include "observer.h"
#include "common/gdb_optional.h"
+#include "common/byte-vector.h"
#include <ctype.h>
#include "run-time-clock.h"
/* Create a buffer and read it in. */
total_bytes = word_size * nr_rows * nr_cols;
- std::unique_ptr<gdb_byte[]> mbuf (new gdb_byte[total_bytes]);
+ gdb::byte_vector mbuf (total_bytes);
/* Dispatch memory reads to the topmost target, not the flattened
current_target. */
nr_bytes = target_read (current_target.beneath,
- TARGET_OBJECT_MEMORY, NULL, mbuf.get (),
+ TARGET_OBJECT_MEMORY, NULL, mbuf.data (),
addr, total_bytes);
if (nr_bytes <= 0)
error (_("Unable to read memory."));
#include "cli/cli-script.h"
#include "format.h"
#include "source.h"
+#include "common/byte-vector.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et al. */
/* Historically gdb has printed floats by first casting them to a
long, and then printing the long. PR cli/16242 suggests changing
this to using C-style hex float format. */
- std::vector<gdb_byte> converted_float_bytes;
+ gdb::byte_vector converted_float_bytes;
if (TYPE_CODE (type) == TYPE_CODE_FLT
&& (options->format == 'o'
|| options->format == 'x'
#include "typeprint.h"
#include <ctype.h>
#include <algorithm>
+#include "common/byte-vector.h"
/* Maximum number of wchars returned from wchar_iterate. */
#define MAX_WCHARS 4
static bool
maybe_negate_by_bytes (const gdb_byte *bytes, unsigned len,
enum bfd_endian byte_order,
- std::vector<gdb_byte> *out_vec)
+ gdb::byte_vector *out_vec)
{
gdb_byte sign_byte;
if (byte_order == BFD_ENDIAN_BIG)
int dummy;
int flip;
- std::vector<gdb_byte> negated_bytes;
+ gdb::byte_vector negated_bytes;
if (is_signed
&& maybe_negate_by_bytes (valaddr, len, byte_order, &negated_bytes))
{