- Rationale:
It is possible for compilers to indicate the desired byte order
interpretation of scalar variables using the DWARF attribute:
DW_AT_endianity
A type flagged with this variable would typically use one of:
DW_END_big
DW_END_little
which instructs the debugger what the desired byte order interpretation
of the variable should be.
The GCC compiler (as of V6) has a mechanism for setting the desired byte
ordering of the fields within a structure or union. For, example, on a
little endian target, a structure declared as:
struct big {
int v;
short a[4];
} __attribute__( ( scalar_storage_order( "big-endian" ) ) );
could be used to ensure all the structure members have a big-endian
interpretation (the compiler would automatically insert byte swap
instructions before and after respective store and load instructions).
- To reproduce
GCC V8 is required to correctly emit DW_AT_endianity DWARF attributes
in all situations when the scalar_storage_order attribute is used.
A fix for (dwarf endianity instrumentation) for GCC V6-V7 can be found
in the URL field of the following PR:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82509
- Test-case:
A new test case (testsuite/gdb.base/endianity.*) is included with this
patch.
Manual testing for mixed endianity code has also been done with GCC V8.
See:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82509#c4
- Observed vs. expected:
Without this change, using scalar_storage_order that doesn't match the
target, such as
struct otherendian
{
int v;
} __attribute__( ( scalar_storage_order( "big-endian" ) ) );
would behave like the following on a little endian target:
Breakpoint 1 at 0x401135: file endianity.c, line 41.
(gdb) run
Starting program: /home/pjoot/freeware/t/a.out
Missing separate debuginfos, use: debuginfo-install glibc-2.17-292.el7.x86_64
Breakpoint 1, main () at endianity.c:41
41 struct otherendian o = {3};
(gdb) n
43 do_nothing (&o); /* START */
(gdb) p o
$1 = {v =
50331648}
(gdb) p /x
$2 = {v = 0x3000000}
whereas with this gdb enhancement we can access the variable with the user
specified endianity:
Breakpoint 1, main () at endianity.c:41
41 struct otherendian o = {3};
(gdb) p o
$1 = {v = 0}
(gdb) n
43 do_nothing (&o); /* START */
(gdb) p o
$2 = {v = 3}
(gdb) p o.v = 4
$3 = 4
(gdb) p o.v
$4 = 4
(gdb) x/4xb &o.v
0x7fffffffd90c: 0x00 0x00 0x00 0x04
(observe that the 4 byte int variable has a big endian representation in the
hex dump.)
gdb/ChangeLog
2019-11-21 Peeter Joot <peeter.joot@lzlabs.com>
Byte reverse display of variables with DW_END_big, DW_END_little
(DW_AT_endianity) dwarf attributes if different than the native
byte order.
* ada-lang.c (ada_value_binop):
Use type_byte_order instead of gdbarch_byte_order.
* ada-valprint.c (printstr):
(ada_val_print_string):
* ada-lang.c (value_pointer):
(ada_value_binop):
Use type_byte_order instead of gdbarch_byte_order.
* c-lang.c (c_get_string):
Use type_byte_order instead of gdbarch_byte_order.
* c-valprint.c (c_val_print_array):
Use type_byte_order instead of gdbarch_byte_order.
* cp-valprint.c (cp_print_class_member):
Use type_byte_order instead of gdbarch_byte_order.
* dwarf2loc.c (rw_pieced_value):
Use type_byte_order instead of gdbarch_byte_order.
* dwarf2read.c (read_base_type): Handle DW_END_big,
DW_END_little
* f-lang.c (f_get_encoding):
Use type_byte_order instead of gdbarch_byte_order.
* findvar.c (default_read_var_value):
Use type_byte_order instead of gdbarch_byte_order.
* gdbtypes.c (check_types_equal):
Require matching TYPE_ENDIANITY_NOT_DEFAULT if set.
(recursive_dump_type): Print TYPE_ENDIANITY_BIG,
and TYPE_ENDIANITY_LITTLE if set.
(type_byte_order): new function.
* gdbtypes.h (TYPE_ENDIANITY_NOT_DEFAULT): New macro.
(struct main_type) <flag_endianity_not_default>:
New field.
(type_byte_order): New function.
* infcmd.c (default_print_one_register_info):
Use type_byte_order instead of gdbarch_byte_order.
* p-lang.c (pascal_printstr):
Use type_byte_order instead of gdbarch_byte_order.
* p-valprint.c (pascal_val_print):
Use type_byte_order instead of gdbarch_byte_order.
* printcmd.c (print_scalar_formatted):
Use type_byte_order instead of gdbarch_byte_order.
* solib-darwin.c (darwin_current_sos):
Use type_byte_order instead of gdbarch_byte_order.
* solib-svr4.c (solib_svr4_r_ldsomap):
Use type_byte_order instead of gdbarch_byte_order.
* stap-probe.c (stap_modify_semaphore):
Use type_byte_order instead of gdbarch_byte_order.
* target-float.c (target_float_same_format_p):
Use type_byte_order instead of gdbarch_byte_order.
* valarith.c (scalar_binop):
(value_bit_index):
Use type_byte_order instead of gdbarch_byte_order.
* valops.c (value_cast):
Use type_byte_order instead of gdbarch_byte_order.
* valprint.c (generic_emit_char):
(generic_printstr):
(val_print_string):
Use type_byte_order instead of gdbarch_byte_order.
* value.c (unpack_long):
(unpack_bits_as_long):
(unpack_value_bitfield):
(modify_field):
(pack_long):
(pack_unsigned_long):
Use type_byte_order instead of gdbarch_byte_order.
* findvar.c (unsigned_pointer_to_address):
(signed_pointer_to_address):
(unsigned_address_to_pointer):
(address_to_signed_pointer):
(default_read_var_value):
(default_value_from_register):
Use type_byte_order instead of gdbarch_byte_order.
* gnu-v3-abi.c (gnuv3_make_method_ptr):
Use type_byte_order instead of gdbarch_byte_order.
* riscv-tdep.c (riscv_print_one_register_info):
Use type_byte_order instead of gdbarch_byte_order.
gdb/testsuite/ChangeLog
2019-11-21 Peeter Joot <peeter.joot@lzlabs.com>
* gdb.base/endianity.c: New test.
* gdb.base/endianity.exp: New file.
Change-Id: I4bd98c1b4508c2d7c5a5dbb15d7b7b1cb4e667e2
+2019-11-21 Peeter Joot <peeter.joot@lzlabs.com>
+
+ Byte reverse display of variables with DW_END_big, DW_END_little
+ (DW_AT_endianity) dwarf attributes if different than the native
+ byte order.
+ * ada-lang.c (ada_value_binop):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * ada-valprint.c (printstr):
+ (ada_val_print_string):
+ * ada-lang.c (value_pointer):
+ (ada_value_binop):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * c-lang.c (c_get_string):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * c-valprint.c (c_val_print_array):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * cp-valprint.c (cp_print_class_member):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * dwarf2loc.c (rw_pieced_value):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * dwarf2read.c (read_base_type): Handle DW_END_big,
+ DW_END_little
+ * f-lang.c (f_get_encoding):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * findvar.c (default_read_var_value):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * gdbtypes.c (check_types_equal):
+ Require matching TYPE_ENDIANITY_NOT_DEFAULT if set.
+ (recursive_dump_type): Print TYPE_ENDIANITY_BIG,
+ and TYPE_ENDIANITY_LITTLE if set.
+ (type_byte_order): new function.
+ * gdbtypes.h (TYPE_ENDIANITY_NOT_DEFAULT): New macro.
+ (struct main_type) <flag_endianity_not_default>:
+ New field.
+ (type_byte_order): New function.
+ * infcmd.c (default_print_one_register_info):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * p-lang.c (pascal_printstr):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * p-valprint.c (pascal_val_print):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * printcmd.c (print_scalar_formatted):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * solib-darwin.c (darwin_current_sos):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * solib-svr4.c (solib_svr4_r_ldsomap):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * stap-probe.c (stap_modify_semaphore):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * target-float.c (target_float_same_format_p):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * valarith.c (scalar_binop):
+ (value_bit_index):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * valops.c (value_cast):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * valprint.c (generic_emit_char):
+ (generic_printstr):
+ (val_print_string):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * value.c (unpack_long):
+ (unpack_bits_as_long):
+ (unpack_value_bitfield):
+ (modify_field):
+ (pack_long):
+ (pack_unsigned_long):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * findvar.c (unsigned_pointer_to_address):
+ (signed_pointer_to_address):
+ (unsigned_address_to_pointer):
+ (address_to_signed_pointer):
+ (default_read_var_value):
+ (default_value_from_register):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * gnu-v3-abi.c (gnuv3_make_method_ptr):
+ Use type_byte_order instead of gdbarch_byte_order.
+ * riscv-tdep.c (riscv_print_one_register_info):
+ Use type_byte_order instead of gdbarch_byte_order.
+
2019-11-21 Simon Marchi <simon.marchi@polymtl.ca>
* top.c (current_ui_gdb_stdout_ptr): Spell out by hand.
addr = value_address (value);
gdbarch_address_to_pointer (gdbarch, type, buf, addr);
- addr = extract_unsigned_integer (buf, len, gdbarch_byte_order (gdbarch));
+ addr = extract_unsigned_integer (buf, len, type_byte_order (type));
return addr;
}
val = allocate_value (type1);
store_unsigned_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)),
- gdbarch_byte_order (get_type_arch (type1)), v);
+ type_byte_order (type1), v);
return val;
}
unsigned int length, int force_ellipses, int type_len,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype));
+ enum bfd_endian byte_order = type_byte_order (elttype);
unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
struct value *original_value,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
struct type *elttype = TYPE_TARGET_TYPE (type);
unsigned int eltlen;
unsigned int len;
struct type *element_type = TYPE_TARGET_TYPE (type);
int req_length = *length;
enum bfd_endian byte_order
- = gdbarch_byte_order (get_type_arch (type));
+ = type_byte_order (type);
if (element_type == NULL)
goto error;
{
LONGEST low_bound, high_bound;
int eltlen, len;
- struct gdbarch *gdbarch = get_type_arch (type);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
unsigned int i = 0; /* Number of characters printed. */
if (!get_array_bounds (type, &low_bound, &high_bound))
cp_print_class_member (const gdb_byte *valaddr, struct type *type,
struct ui_file *stream, const char *prefix)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
/* VAL is a byte offset into the structure type SELF_TYPE.
Find the name of the field for that offset and
bits_to_skip += (8 * value_offset (value_parent (v))
+ value_bitpos (v));
if (from != NULL
- && (gdbarch_byte_order (get_type_arch (value_type (from)))
+ && (type_byte_order (value_type (from))
== BFD_ENDIAN_BIG))
{
/* Use the least significant bits of FROM. */
struct type *type;
struct attribute *attr;
int encoding = 0, bits = 0;
+ int endianity = 0;
const char *name;
+ gdbarch *arch;
attr = dwarf2_attr (die, DW_AT_encoding, cu);
if (attr != nullptr)
- {
- encoding = DW_UNSND (attr);
- }
+ encoding = DW_UNSND (attr);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- {
- bits = DW_UNSND (attr) * TARGET_CHAR_BIT;
- }
+ bits = DW_UNSND (attr) * TARGET_CHAR_BIT;
name = dwarf2_name (die, cu);
if (!name)
- {
- complaint (_("DW_AT_name missing from DW_TAG_base_type"));
- }
+ complaint (_("DW_AT_name missing from DW_TAG_base_type"));
+ attr = dwarf2_attr (die, DW_AT_endianity, cu);
+ if (attr)
+ endianity = DW_UNSND (attr);
+ arch = get_objfile_arch (objfile);
switch (encoding)
{
case DW_ATE_address:
break;
case DW_ATE_UTF:
{
- gdbarch *arch = get_objfile_arch (objfile);
-
if (bits == 16)
type = builtin_type (arch)->builtin_char16;
else if (bits == 32)
maybe_set_alignment (cu, die, type);
+ switch (endianity)
+ {
+ case DW_END_big:
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_LITTLE)
+ TYPE_ENDIANITY_NOT_DEFAULT (type) = 1;
+ break;
+ case DW_END_little:
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
+ TYPE_ENDIANITY_NOT_DEFAULT (type) = 1;
+ break;
+ }
+
return set_die_type (die, type, cu);
}
encoding = target_charset (get_type_arch (type));
break;
case 4:
- if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_BIG)
+ if (type_byte_order (type) == BFD_ENDIAN_BIG)
encoding = "UTF-32BE";
else
encoding = "UTF-32LE";
unsigned_pointer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
return extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
}
signed_pointer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order);
}
unsigned_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
gdb_byte *buf, CORE_ADDR addr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr);
}
address_to_signed_pointer (struct gdbarch *gdbarch, struct type *type,
gdb_byte *buf, CORE_ADDR addr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
store_signed_integer (buf, TYPE_LENGTH (type), byte_order, addr);
}
/* Put the constant back in target format. */
v = allocate_value (type);
store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
- gdbarch_byte_order (get_type_arch (type)),
+ type_byte_order (type),
(LONGEST) SYMBOL_VALUE (var));
VALUE_LVAL (v) = not_lval;
return v;
an integral number of registers. Otherwise, you need to do
some fiddling with the last register copied here for little
endian machines. */
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
+ if (type_byte_order (type) == BFD_ENDIAN_BIG
&& len < register_size (gdbarch, regnum))
/* Big-endian, and we want less than full size. */
set_value_offset (value, register_size (gdbarch, regnum) - len);
|| TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
|| TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)
|| TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2)
+ || TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2)
|| TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
|| TYPE_VECTOR (type1) != TYPE_VECTOR (type2)
|| TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
{
puts_filtered (" TYPE_NOSIGN");
}
+ if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+ {
+ puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT");
+ }
if (TYPE_STUB (type))
{
puts_filtered (" TYPE_STUB");
show_strict_type_checking,
&setchecklist, &showchecklist);
}
+
+/* See gdbtypes.h. */
+enum bfd_endian
+type_byte_order (const struct type *type)
+{
+ bfd_endian byteorder = gdbarch_byte_order (get_type_arch (type));
+ if (TYPE_ENDIANITY_NOT_DEFAULT (type))
+ {
+ if (byteorder == BFD_ENDIAN_BIG)
+ return BFD_ENDIAN_LITTLE;
+ else if (byteorder == BFD_ENDIAN_LITTLE)
+ return BFD_ENDIAN_BIG;
+ else
+ return BFD_ENDIAN_UNKNOWN;
+ }
+
+ return byteorder;
+}
#define TYPE_NOSIGN(t) (TYPE_MAIN_TYPE (t)->flag_nosign)
+/* * A compiler may supply dwarf instrumentation
+ that indicates the desired endian interpretation of the variable
+ differs from the native endian representation. */
+
+#define TYPE_ENDIANITY_NOT_DEFAULT(t) (TYPE_MAIN_TYPE (t)->flag_endianity_not_default)
+
/* * This appears in a type's flags word if it is a stub type (e.g.,
if someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */
unsigned int flag_gnu_ifunc : 1;
unsigned int flag_fixed_instance : 1;
unsigned int flag_objfile_owned : 1;
+ unsigned int flag_endianity_not_default : 1;
/* * True if this type was declared with "class" rather than
"struct". */
extern int type_not_associated (const struct type *type);
+/* * When the type includes explicit byte ordering, return that.
+ Otherwise, the byte ordering from gdbarch_byte_order for
+ get_type_arch is returned. */
+
+extern enum bfd_endian type_byte_order (const struct type *type);
+
/* A flag to enable printing of debugging information of C++
overloading. */
{
struct gdbarch *gdbarch = get_type_arch (type);
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
/* FIXME drow/2006-12-24: The adjustment of "this" is currently
always zero, since the method pointer is of the correct type.
{
struct value_print_options opts;
const gdb_byte *valaddr = value_contents_for_printing (val);
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype));
+ enum bfd_endian byte_order = type_byte_order (regtype);
get_user_print_options (&opts);
opts.deref_ref = 1;
const char *encoding, int force_ellipses,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
unsigned int i;
unsigned int things_printed = 0;
int in_quotes = 0;
const struct value_print_options *options)
{
struct gdbarch *gdbarch = get_type_arch (type);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
unsigned int i = 0; /* Number of characters printed */
unsigned len;
struct type *elttype;
{
struct gdbarch *gdbarch = get_type_arch (type);
unsigned int len = TYPE_LENGTH (type);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (type);
/* String printing should go through val_print_scalar_formatted. */
gdb_assert (options->format != 's');
{
struct value_print_options opts;
const gdb_byte *valaddr = value_contents_for_printing (val);
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (regtype));
+ enum bfd_endian byte_order = type_byte_order (regtype);
get_user_print_options (&opts);
opts.deref_ref = 1;
darwin_current_sos (void)
{
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ enum bfd_endian byte_order = type_byte_order (ptr_type);
int ptr_len = TYPE_LENGTH (ptr_type);
unsigned int image_info_size;
struct so_list *head = NULL;
{
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ enum bfd_endian byte_order = type_byte_order (ptr_type);
ULONGEST version = 0;
try
return;
}
- value = extract_unsigned_integer (bytes, TYPE_LENGTH (type),
- gdbarch_byte_order (gdbarch));
+ enum bfd_endian byte_order = type_byte_order (type);
+ value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order);
/* Note that we explicitly don't worry about overflow or
underflow. */
if (set)
else
--value;
- store_unsigned_integer (bytes, TYPE_LENGTH (type),
- gdbarch_byte_order (gdbarch), value);
+ store_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order, value);
if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0)
warning (_("Could not write the value of a SystemTap semaphore."));
#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
#endif
- if (gdbarch_byte_order (get_type_arch (type)) == OPPOSITE_BYTE_ORDER)
+ if (type_byte_order (type) == OPPOSITE_BYTE_ORDER)
for (i = 0; i < len; i++)
to[i] = from[len - i - 1];
else
case TYPE_CODE_DECFLOAT:
return (TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
- && (gdbarch_byte_order (get_type_arch (type1))
- == gdbarch_byte_order (get_type_arch (type2))));
+ && (type_byte_order (type1)
+ == type_byte_order (type2)));
default:
gdb_assert_not_reached ("unexpected type code");
+2019-11-21 Peeter Joot <peeter.joot@lzlabs.com>
+
+ * gdb.base/endianity.c: New test.
+ * gdb.base/endianity.exp: New file.
+
2019-11-21 Lukas Durfina <ldurfina@tachyum.com>
* gdb.arch/amd64-eval.exp: Skip test if target is not x86-64.
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2019 Free Software Foundation, Inc.
+
+ 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/>. */
+
+/* This tests the handling of dwarf attributes:
+ DW_AT_endianity, DW_END_big, and DW_END_little. */
+struct otherendian
+{
+ int v;
+ short w;
+}
+#if defined __GNUC__ && (__GNUC__ >= 6)
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+__attribute__( ( scalar_storage_order( "big-endian" ) ) )
+#else
+__attribute__( ( scalar_storage_order( "little-endian" ) ) )
+#endif
+#endif
+;
+
+void
+do_nothing (struct otherendian *c)
+{
+}
+
+int
+main (void)
+{
+ struct otherendian o = {3,2};
+
+ do_nothing (&o); /* START */
+}
--- /dev/null
+# Copyright 2019 Free Software Foundation, Inc.
+
+# 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/>.
+
+standard_testfile .c
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } {
+ return -1
+}
+
+set bp_location [gdb_get_line_number "START"]
+if ![runto "endianity.c:$bp_location" ] then {
+ fail "couldn't run to start"
+ return -1
+}
+
+gdb_test "print o" "= {v = 3, w = 2}" "print o before assignment"
+
+gdb_test "print o.v = 4" "= 4"
+gdb_test "print o.w = 3" "= 3"
+
+# scalar_storage_order requires gcc >= 6
+if { ([test_compiler_info {gcc-[0-5]-*}] || ![test_compiler_info gcc*]) } {
+ setup_xfail "*-*-*"
+}
+gdb_test "x/x &o.v" "0x04000000"
+gdb_test "x/xh &o.w" "0x0300"
+
+gdb_test "print o" "= {v = 4, w = 3}" "print o after assignment"
val = allocate_value (result_type);
store_signed_integer (value_contents_raw (val),
TYPE_LENGTH (result_type),
- gdbarch_byte_order (get_type_arch (result_type)),
+ type_byte_order (result_type),
v);
}
else
val = allocate_value (result_type);
store_unsigned_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)),
- gdbarch_byte_order
- (get_type_arch (result_type)),
+ type_byte_order (result_type),
v);
}
else
val = allocate_value (result_type);
store_signed_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)),
- gdbarch_byte_order
- (get_type_arch (result_type)),
+ type_byte_order (result_type),
v);
}
}
return -1;
rel_index = index - low_bound;
word = extract_unsigned_integer (valaddr + (rel_index / TARGET_CHAR_BIT), 1,
- gdbarch_byte_order (gdbarch));
+ type_byte_order (type));
rel_index %= TARGET_CHAR_BIT;
if (gdbarch_bits_big_endian (gdbarch))
rel_index = TARGET_CHAR_BIT - 1 - rel_index;
if (code2 == TYPE_CODE_PTR)
longest = extract_unsigned_integer
(value_contents (arg2), TYPE_LENGTH (type2),
- gdbarch_byte_order (get_type_arch (type2)));
+ type_byte_order (type2));
else
longest = value_as_long (arg2);
return value_from_longest (to_type, convert_to_boolean ?
int quoter, const char *encoding)
{
enum bfd_endian byte_order
- = gdbarch_byte_order (get_type_arch (type));
+ = type_byte_order (type);
gdb_byte *c_buf;
int need_escape = 0;
int quote_char, int c_style_terminator,
const struct value_print_options *options)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
unsigned int i;
int width = TYPE_LENGTH (type);
int finished = 0;
int bytes_read;
gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
struct gdbarch *gdbarch = get_type_arch (elttype);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ enum bfd_endian byte_order = type_byte_order (elttype);
int width = TYPE_LENGTH (elttype);
/* First we need to figure out the limit on the number of characters we are
LONGEST
unpack_long (struct type *type, const gdb_byte *valaddr)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
int nosign = TYPE_UNSIGNED (type);
unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
LONGEST bitpos, LONGEST bitsize)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (field_type));
+ enum bfd_endian byte_order = type_byte_order (field_type);
ULONGEST val;
ULONGEST valmask;
int lsbcount;
int dst_bit_offset;
struct type *field_type = value_type (dest_val);
- byte_order = gdbarch_byte_order (get_type_arch (field_type));
+ byte_order = type_byte_order (field_type);
/* First, unpack and sign extend the bitfield as if it was wholly
valid. Optimized out/unavailable bits are read as zero, but
modify_field (struct type *type, gdb_byte *addr,
LONGEST fieldval, LONGEST bitpos, LONGEST bitsize)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
ULONGEST oword;
ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
LONGEST bytesize;
void
pack_long (gdb_byte *buf, struct type *type, LONGEST num)
{
- enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
+ enum bfd_endian byte_order = type_byte_order (type);
LONGEST len;
type = check_typedef (type);
type = check_typedef (type);
len = TYPE_LENGTH (type);
- byte_order = gdbarch_byte_order (get_type_arch (type));
+ byte_order = type_byte_order (type);
switch (TYPE_CODE (type))
{