Adjust byte order variable display/change if DW_AT_endianity is present.

- 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
This commit is contained in:
Peeter Joot 2017-10-06 16:13:04 -04:00 committed by Tom Tromey
parent b52696f9e5
commit 34877895ca
29 changed files with 269 additions and 58 deletions

View file

@ -1,3 +1,82 @@
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> 2019-11-21 Simon Marchi <simon.marchi@polymtl.ca>
* top.c (current_ui_gdb_stdout_ptr): Spell out by hand. * top.c (current_ui_gdb_stdout_ptr): Spell out by hand.

View file

@ -4546,7 +4546,7 @@ value_pointer (struct value *value, struct type *type)
addr = value_address (value); addr = value_address (value);
gdbarch_address_to_pointer (gdbarch, type, buf, addr); 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; return addr;
} }
@ -9678,7 +9678,7 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
val = allocate_value (type1); val = allocate_value (type1);
store_unsigned_integer (value_contents_raw (val), store_unsigned_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)), TYPE_LENGTH (value_type (val)),
gdbarch_byte_order (get_type_arch (type1)), v); type_byte_order (type1), v);
return val; return val;
} }

View file

@ -476,7 +476,7 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string,
unsigned int length, int force_ellipses, int type_len, unsigned int length, int force_ellipses, int type_len,
const struct value_print_options *options) 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 i;
unsigned int things_printed = 0; unsigned int things_printed = 0;
int in_quotes = 0; int in_quotes = 0;
@ -719,7 +719,7 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr,
struct value *original_value, struct value *original_value,
const struct value_print_options *options) 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); struct type *elttype = TYPE_TARGET_TYPE (type);
unsigned int eltlen; unsigned int eltlen;
unsigned int len; unsigned int len;

View file

@ -245,7 +245,7 @@ c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
struct type *element_type = TYPE_TARGET_TYPE (type); struct type *element_type = TYPE_TARGET_TYPE (type);
int req_length = *length; int req_length = *length;
enum bfd_endian byte_order enum bfd_endian byte_order
= gdbarch_byte_order (get_type_arch (type)); = type_byte_order (type);
if (element_type == NULL) if (element_type == NULL)
goto error; goto error;

View file

@ -247,8 +247,7 @@ c_val_print_array (struct type *type, const gdb_byte *valaddr,
{ {
LONGEST low_bound, high_bound; LONGEST low_bound, high_bound;
int eltlen, len; int eltlen, len;
struct gdbarch *gdbarch = get_type_arch (type); enum bfd_endian byte_order = type_byte_order (type);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int i = 0; /* Number of characters printed. */ unsigned int i = 0; /* Number of characters printed. */
if (!get_array_bounds (type, &low_bound, &high_bound)) if (!get_array_bounds (type, &low_bound, &high_bound))

View file

@ -740,7 +740,7 @@ void
cp_print_class_member (const gdb_byte *valaddr, struct type *type, cp_print_class_member (const gdb_byte *valaddr, struct type *type,
struct ui_file *stream, const char *prefix) 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. /* VAL is a byte offset into the structure type SELF_TYPE.
Find the name of the field for that offset and Find the name of the field for that offset and

View file

@ -1601,7 +1601,7 @@ rw_pieced_value (struct value *v, struct value *from)
bits_to_skip += (8 * value_offset (value_parent (v)) bits_to_skip += (8 * value_offset (value_parent (v))
+ value_bitpos (v)); + value_bitpos (v));
if (from != NULL if (from != NULL
&& (gdbarch_byte_order (get_type_arch (value_type (from))) && (type_byte_order (value_type (from))
== BFD_ENDIAN_BIG)) == BFD_ENDIAN_BIG))
{ {
/* Use the least significant bits of FROM. */ /* Use the least significant bits of FROM. */

View file

@ -17661,24 +17661,24 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *type; struct type *type;
struct attribute *attr; struct attribute *attr;
int encoding = 0, bits = 0; int encoding = 0, bits = 0;
int endianity = 0;
const char *name; const char *name;
gdbarch *arch;
attr = dwarf2_attr (die, DW_AT_encoding, cu); attr = dwarf2_attr (die, DW_AT_encoding, cu);
if (attr != nullptr) if (attr != nullptr)
{ encoding = DW_UNSND (attr);
encoding = DW_UNSND (attr);
}
attr = dwarf2_attr (die, DW_AT_byte_size, cu); attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr) if (attr != nullptr)
{ bits = DW_UNSND (attr) * TARGET_CHAR_BIT;
bits = DW_UNSND (attr) * TARGET_CHAR_BIT;
}
name = dwarf2_name (die, cu); name = dwarf2_name (die, cu);
if (!name) 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) switch (encoding)
{ {
case DW_ATE_address: case DW_ATE_address:
@ -17729,8 +17729,6 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
break; break;
case DW_ATE_UTF: case DW_ATE_UTF:
{ {
gdbarch *arch = get_objfile_arch (objfile);
if (bits == 16) if (bits == 16)
type = builtin_type (arch)->builtin_char16; type = builtin_type (arch)->builtin_char16;
else if (bits == 32) else if (bits == 32)
@ -17757,6 +17755,18 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
maybe_set_alignment (cu, die, type); 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); return set_die_type (die, type, cu);
} }

View file

@ -59,7 +59,7 @@ f_get_encoding (struct type *type)
encoding = target_charset (get_type_arch (type)); encoding = target_charset (get_type_arch (type));
break; break;
case 4: case 4:
if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_BIG) if (type_byte_order (type) == BFD_ENDIAN_BIG)
encoding = "UTF-32BE"; encoding = "UTF-32BE";
else else
encoding = "UTF-32LE"; encoding = "UTF-32LE";

View file

@ -309,7 +309,7 @@ CORE_ADDR
unsigned_pointer_to_address (struct gdbarch *gdbarch, unsigned_pointer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf) 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); return extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
} }
@ -318,7 +318,7 @@ CORE_ADDR
signed_pointer_to_address (struct gdbarch *gdbarch, signed_pointer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf) 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); return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order);
} }
@ -329,7 +329,7 @@ void
unsigned_address_to_pointer (struct gdbarch *gdbarch, struct type *type, unsigned_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
gdb_byte *buf, CORE_ADDR addr) 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); store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr);
} }
@ -338,7 +338,7 @@ void
address_to_signed_pointer (struct gdbarch *gdbarch, struct type *type, address_to_signed_pointer (struct gdbarch *gdbarch, struct type *type,
gdb_byte *buf, CORE_ADDR addr) 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); store_signed_integer (buf, TYPE_LENGTH (type), byte_order, addr);
} }
@ -620,7 +620,7 @@ default_read_var_value (struct symbol *var, const struct block *var_block,
/* Put the constant back in target format. */ /* Put the constant back in target format. */
v = allocate_value (type); v = allocate_value (type);
store_signed_integer (value_contents_raw (v), TYPE_LENGTH (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)); (LONGEST) SYMBOL_VALUE (var));
VALUE_LVAL (v) = not_lval; VALUE_LVAL (v) = not_lval;
return v; return v;
@ -840,7 +840,7 @@ default_value_from_register (struct gdbarch *gdbarch, struct type *type,
an integral number of registers. Otherwise, you need to do an integral number of registers. Otherwise, you need to do
some fiddling with the last register copied here for little some fiddling with the last register copied here for little
endian machines. */ endian machines. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG if (type_byte_order (type) == BFD_ENDIAN_BIG
&& len < register_size (gdbarch, regnum)) && len < register_size (gdbarch, regnum))
/* Big-endian, and we want less than full size. */ /* Big-endian, and we want less than full size. */
set_value_offset (value, register_size (gdbarch, regnum) - len); set_value_offset (value, register_size (gdbarch, regnum) - len);

View file

@ -3616,6 +3616,7 @@ check_types_equal (struct type *type1, struct type *type2,
|| TYPE_LENGTH (type1) != TYPE_LENGTH (type2) || TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
|| TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2) || TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)
|| TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2) || TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2)
|| TYPE_ENDIANITY_NOT_DEFAULT (type1) != TYPE_ENDIANITY_NOT_DEFAULT (type2)
|| TYPE_VARARGS (type1) != TYPE_VARARGS (type2) || TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
|| TYPE_VECTOR (type1) != TYPE_VECTOR (type2) || TYPE_VECTOR (type1) != TYPE_VECTOR (type2)
|| TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2) || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
@ -4669,6 +4670,10 @@ recursive_dump_type (struct type *type, int spaces)
{ {
puts_filtered (" TYPE_NOSIGN"); puts_filtered (" TYPE_NOSIGN");
} }
if (TYPE_ENDIANITY_NOT_DEFAULT (type))
{
puts_filtered (" TYPE_ENDIANITY_NOT_DEFAULT");
}
if (TYPE_STUB (type)) if (TYPE_STUB (type))
{ {
puts_filtered (" TYPE_STUB"); puts_filtered (" TYPE_STUB");
@ -5617,3 +5622,21 @@ _initialize_gdbtypes (void)
show_strict_type_checking, show_strict_type_checking,
&setchecklist, &showchecklist); &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;
}

View file

@ -219,6 +219,12 @@ DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
#define TYPE_NOSIGN(t) (TYPE_MAIN_TYPE (t)->flag_nosign) #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., /* * 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 if someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */ via (struct sir_not_appearing_in_this_film *)). */
@ -701,6 +707,7 @@ struct main_type
unsigned int flag_gnu_ifunc : 1; unsigned int flag_gnu_ifunc : 1;
unsigned int flag_fixed_instance : 1; unsigned int flag_fixed_instance : 1;
unsigned int flag_objfile_owned : 1; unsigned int flag_objfile_owned : 1;
unsigned int flag_endianity_not_default : 1;
/* * True if this type was declared with "class" rather than /* * True if this type was declared with "class" rather than
"struct". */ "struct". */
@ -2146,6 +2153,12 @@ extern int type_not_allocated (const struct type *type);
extern int type_not_associated (const struct type *type); 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++ /* A flag to enable printing of debugging information of C++
overloading. */ overloading. */

View file

@ -678,7 +678,7 @@ gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
{ {
struct gdbarch *gdbarch = get_type_arch (type); struct gdbarch *gdbarch = get_type_arch (type);
int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr); 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 /* FIXME drow/2006-12-24: The adjustment of "this" is currently
always zero, since the method pointer is of the correct type. always zero, since the method pointer is of the correct type.

View file

@ -2216,7 +2216,7 @@ default_print_one_register_info (struct ui_file *file,
{ {
struct value_print_options opts; struct value_print_options opts;
const gdb_byte *valaddr = value_contents_for_printing (val); 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); get_user_print_options (&opts);
opts.deref_ref = 1; opts.deref_ref = 1;

View file

@ -230,7 +230,7 @@ pascal_printstr (struct ui_file *stream, struct type *type,
const char *encoding, int force_ellipses, const char *encoding, int force_ellipses,
const struct value_print_options *options) 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 i;
unsigned int things_printed = 0; unsigned int things_printed = 0;
int in_quotes = 0; int in_quotes = 0;

View file

@ -67,7 +67,7 @@ pascal_val_print (struct type *type,
const struct value_print_options *options) const struct value_print_options *options)
{ {
struct gdbarch *gdbarch = get_type_arch (type); 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 int i = 0; /* Number of characters printed */
unsigned len; unsigned len;
struct type *elttype; struct type *elttype;

View file

@ -356,7 +356,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type,
{ {
struct gdbarch *gdbarch = get_type_arch (type); struct gdbarch *gdbarch = get_type_arch (type);
unsigned int len = TYPE_LENGTH (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. */ /* String printing should go through val_print_scalar_formatted. */
gdb_assert (options->format != 's'); gdb_assert (options->format != 's');

View file

@ -688,7 +688,7 @@ riscv_print_one_register_info (struct gdbarch *gdbarch,
{ {
struct value_print_options opts; struct value_print_options opts;
const gdb_byte *valaddr = value_contents_for_printing (val); 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); get_user_print_options (&opts);
opts.deref_ref = 1; opts.deref_ref = 1;

View file

@ -223,7 +223,7 @@ static struct so_list *
darwin_current_sos (void) darwin_current_sos (void)
{ {
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; 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); int ptr_len = TYPE_LENGTH (ptr_type);
unsigned int image_info_size; unsigned int image_info_size;
struct so_list *head = NULL; struct so_list *head = NULL;

View file

@ -897,7 +897,7 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
{ {
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; 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; ULONGEST version = 0;
try try

View file

@ -1435,8 +1435,8 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
return; return;
} }
value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), enum bfd_endian byte_order = type_byte_order (type);
gdbarch_byte_order (gdbarch)); value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order);
/* Note that we explicitly don't worry about overflow or /* Note that we explicitly don't worry about overflow or
underflow. */ underflow. */
if (set) if (set)
@ -1444,8 +1444,7 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch)
else else
--value; --value;
store_unsigned_integer (bytes, TYPE_LENGTH (type), store_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order, value);
gdbarch_byte_order (gdbarch), value);
if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0) if (target_write_memory (address, bytes, TYPE_LENGTH (type)) != 0)
warning (_("Could not write the value of a SystemTap semaphore.")); warning (_("Could not write the value of a SystemTap semaphore."));

View file

@ -1753,7 +1753,7 @@ match_endianness (const gdb_byte *from, const struct type *type, gdb_byte *to)
#define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
#endif #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++) for (i = 0; i < len; i++)
to[i] = from[len - i - 1]; to[i] = from[len - i - 1];
else else
@ -2160,8 +2160,8 @@ target_float_same_format_p (const struct type *type1,
case TYPE_CODE_DECFLOAT: case TYPE_CODE_DECFLOAT:
return (TYPE_LENGTH (type1) == TYPE_LENGTH (type2) return (TYPE_LENGTH (type1) == TYPE_LENGTH (type2)
&& (gdbarch_byte_order (get_type_arch (type1)) && (type_byte_order (type1)
== gdbarch_byte_order (get_type_arch (type2)))); == type_byte_order (type2)));
default: default:
gdb_assert_not_reached ("unexpected type code"); gdb_assert_not_reached ("unexpected type code");

View file

@ -1,3 +1,8 @@
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> 2019-11-21 Lukas Durfina <ldurfina@tachyum.com>
* gdb.arch/amd64-eval.exp: Skip test if target is not x86-64. * gdb.arch/amd64-eval.exp: Skip test if target is not x86-64.

View file

@ -0,0 +1,45 @@
/* 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 */
}

View file

@ -0,0 +1,40 @@
# 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"

View file

@ -988,7 +988,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
val = allocate_value (result_type); val = allocate_value (result_type);
store_signed_integer (value_contents_raw (val), store_signed_integer (value_contents_raw (val),
TYPE_LENGTH (result_type), TYPE_LENGTH (result_type),
gdbarch_byte_order (get_type_arch (result_type)), type_byte_order (result_type),
v); v);
} }
else else
@ -1136,8 +1136,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
val = allocate_value (result_type); val = allocate_value (result_type);
store_unsigned_integer (value_contents_raw (val), store_unsigned_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)), TYPE_LENGTH (value_type (val)),
gdbarch_byte_order type_byte_order (result_type),
(get_type_arch (result_type)),
v); v);
} }
else else
@ -1266,8 +1265,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
val = allocate_value (result_type); val = allocate_value (result_type);
store_signed_integer (value_contents_raw (val), store_signed_integer (value_contents_raw (val),
TYPE_LENGTH (value_type (val)), TYPE_LENGTH (value_type (val)),
gdbarch_byte_order type_byte_order (result_type),
(get_type_arch (result_type)),
v); v);
} }
} }
@ -1712,7 +1710,7 @@ value_bit_index (struct type *type, const gdb_byte *valaddr, int index)
return -1; return -1;
rel_index = index - low_bound; rel_index = index - low_bound;
word = extract_unsigned_integer (valaddr + (rel_index / TARGET_CHAR_BIT), 1, word = extract_unsigned_integer (valaddr + (rel_index / TARGET_CHAR_BIT), 1,
gdbarch_byte_order (gdbarch)); type_byte_order (type));
rel_index %= TARGET_CHAR_BIT; rel_index %= TARGET_CHAR_BIT;
if (gdbarch_bits_big_endian (gdbarch)) if (gdbarch_bits_big_endian (gdbarch))
rel_index = TARGET_CHAR_BIT - 1 - rel_index; rel_index = TARGET_CHAR_BIT - 1 - rel_index;

View file

@ -483,7 +483,7 @@ value_cast (struct type *type, struct value *arg2)
if (code2 == TYPE_CODE_PTR) if (code2 == TYPE_CODE_PTR)
longest = extract_unsigned_integer longest = extract_unsigned_integer
(value_contents (arg2), TYPE_LENGTH (type2), (value_contents (arg2), TYPE_LENGTH (type2),
gdbarch_byte_order (get_type_arch (type2))); type_byte_order (type2));
else else
longest = value_as_long (arg2); longest = value_as_long (arg2);
return value_from_longest (to_type, convert_to_boolean ? return value_from_longest (to_type, convert_to_boolean ?

View file

@ -2402,7 +2402,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream,
int quoter, const char *encoding) int quoter, const char *encoding)
{ {
enum bfd_endian byte_order enum bfd_endian byte_order
= gdbarch_byte_order (get_type_arch (type)); = type_byte_order (type);
gdb_byte *c_buf; gdb_byte *c_buf;
int need_escape = 0; int need_escape = 0;
@ -2722,7 +2722,7 @@ generic_printstr (struct ui_file *stream, struct type *type,
int quote_char, int c_style_terminator, int quote_char, int c_style_terminator,
const struct value_print_options *options) 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 i;
int width = TYPE_LENGTH (type); int width = TYPE_LENGTH (type);
int finished = 0; int finished = 0;
@ -2834,7 +2834,7 @@ val_print_string (struct type *elttype, const char *encoding,
int bytes_read; int bytes_read;
gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */ gdb::unique_xmalloc_ptr<gdb_byte> buffer; /* Dynamically growable fetch buffer. */
struct gdbarch *gdbarch = get_type_arch (elttype); 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); int width = TYPE_LENGTH (elttype);
/* First we need to figure out the limit on the number of characters we are /* First we need to figure out the limit on the number of characters we are

View file

@ -2737,7 +2737,7 @@ value_as_address (struct value *val)
LONGEST LONGEST
unpack_long (struct type *type, const gdb_byte *valaddr) 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); enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type); int len = TYPE_LENGTH (type);
int nosign = TYPE_UNSIGNED (type); int nosign = TYPE_UNSIGNED (type);
@ -3100,7 +3100,7 @@ static LONGEST
unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr,
LONGEST bitpos, LONGEST bitsize) 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 val;
ULONGEST valmask; ULONGEST valmask;
int lsbcount; int lsbcount;
@ -3209,7 +3209,7 @@ unpack_value_bitfield (struct value *dest_val,
int dst_bit_offset; int dst_bit_offset;
struct type *field_type = value_type (dest_val); 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 /* First, unpack and sign extend the bitfield as if it was wholly
valid. Optimized out/unavailable bits are read as zero, but valid. Optimized out/unavailable bits are read as zero, but
@ -3269,7 +3269,7 @@ void
modify_field (struct type *type, gdb_byte *addr, modify_field (struct type *type, gdb_byte *addr,
LONGEST fieldval, LONGEST bitpos, LONGEST bitsize) 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 oword;
ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize); ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
LONGEST bytesize; LONGEST bytesize;
@ -3315,7 +3315,7 @@ modify_field (struct type *type, gdb_byte *addr,
void void
pack_long (gdb_byte *buf, struct type *type, LONGEST num) 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; LONGEST len;
type = check_typedef (type); type = check_typedef (type);
@ -3363,7 +3363,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num)
type = check_typedef (type); type = check_typedef (type);
len = TYPE_LENGTH (type); len = TYPE_LENGTH (type);
byte_order = gdbarch_byte_order (get_type_arch (type)); byte_order = type_byte_order (type);
switch (TYPE_CODE (type)) switch (TYPE_CODE (type))
{ {