diff options
author | Peeter Joot <peeter.joot@lzlabs.com> | 2017-10-06 16:13:04 -0400 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2019-11-21 11:48:59 -0700 |
commit | 34877895ca38f74ae31bd65a6916560020d9d62b (patch) | |
tree | c040b456c573621008afce8c847ceb3fa8bb37bd /gdb/c-valprint.c | |
parent | b52696f9e567da157b152ae641f064507f993969 (diff) | |
download | gdb-34877895ca38f74ae31bd65a6916560020d9d62b.zip gdb-34877895ca38f74ae31bd65a6916560020d9d62b.tar.gz gdb-34877895ca38f74ae31bd65a6916560020d9d62b.tar.bz2 |
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
Diffstat (limited to 'gdb/c-valprint.c')
-rw-r--r-- | gdb/c-valprint.c | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index c4306f1..58675f6 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -247,8 +247,7 @@ c_val_print_array (struct type *type, const gdb_byte *valaddr, { 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)) |