From patchwork Tue Oct 10 23:30:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peeter Joot X-Patchwork-Id: 23467 Received: (qmail 22021 invoked by alias); 10 Oct 2017 23:30:37 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 21990 invoked by uid 89); 10 Oct 2017 23:30:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.3 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=ov, H*r:TLS1, wholly, Mixed X-HELO: mail-wm0-f66.google.com Received: from mail-wm0-f66.google.com (HELO mail-wm0-f66.google.com) (74.125.82.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Oct 2017 23:30:29 +0000 Received: by mail-wm0-f66.google.com with SMTP id l10so681681wmg.1 for ; Tue, 10 Oct 2017 16:30:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JBkh9q9lFTJyWa5AwtYnwyP10iktlicxbPyZaV2p1SI=; b=P7CMjf7Mnq+QbKucGXpzTWkWEEq2ELdaj+CjmSg6R18WwUX1Hqo+NMXpVsbYxDpvQJ z6r2r0TY0p8vuGRTklV+EAHdzYVvRswR/L1hytmS2hD8KqZWj16lLzGd8pgmzOdptUbx 8Ikj4q37zDblGXS587Zq3EWstKLFPx3epbpc9JqWtQByK40bR9tN2Gs+WnQ3yZTILIyW wd5xnU2UbqAAyD/XKtq8piT8gGMOmP0YuR6jym+Ln4MkD9My7UZ3oJmonFh2DY9W2X8s CSiY4E69qKZ75aUvT2HVMQj9fWk7GxdRZCR9Q5M+UMa6edAqpa5f374+Zaa9+Ehy6qur iFvA== X-Gm-Message-State: AMCzsaUvepboNjpbjgiZNOgzeyCEzIncoDflPhbZ2cVhvJOFy035C5zs FBqwCLo3+uwzvfrMIFmqSyeLEEcN X-Google-Smtp-Source: AOwi7QDZf75fhPQNqXoaQ99TrfNjKYHX0hj7fbD7hQr5MC9Sr9OoSfXwkdFLvD80UFxgjiukJg6OgQ== X-Received: by 10.80.133.203 with SMTP id q11mr6381322edh.50.1507678225838; Tue, 10 Oct 2017 16:30:25 -0700 (PDT) Received: from localhost.localdomain ([2607:fea8:a2a0:506:9d24:4c1:119a:cd6f]) by smtp.gmail.com with ESMTPSA id 33sm3431926edt.4.2017.10.10.16.30.22 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 10 Oct 2017 16:30:24 -0700 (PDT) From: Peeter Joot X-Google-Original-From: Peeter Joot To: gdb-patches@sourceware.org Cc: peeter.joot@lzlabs.com, simark@simark.ca Subject: [PATCH] review request: implementing DW_AT_endianity Date: Tue, 10 Oct 2017 19:30:10 -0400 Message-Id: <20171010233010.58471-1-peeter.joot@lzlabs.com> In-Reply-To: References: * binutils/dwarf.c (read_and_display_attr_value): Handle DW_AT_endianity, DW_END_default, DW_END_big, DW_END_little * gdb/gdbtypes.h (global scope): define TYPE_ENDIANITY_BIG, TYPE_ENDIANITY_LITTLE. New function: type_byte_order * gdb/dwarf2read.c (read_base_type): Handle DW_END_big, DW_END_little * gdb/gdbtypes.c (check_types_equal): Require matching TYPE_ENDIANITY_BIG, and TYPE_ENDIANITY_LITTLE if set. New function: type_byte_order. (recursive_dump_type): Print TYPE_ENDIANITY_BIG, and TYPE_ENDIANITY_LITTLE if set. (struct main_type): Add flag_endianity_big, flag_endianity_little * gdb/ada-lang.c (ada_value_binop) * gdb/ada-valprint.c (printstr, ada_val_print_string) * gdb/c-lang.c (c_get_string) * gdb/c-valprint.c (c_val_print_array) * gdb/cp-valprint.c (cp_print_class_member) * gdb/dwarf2loc.c (rw_pieced_value) * gdb/f-lang.c (f_get_encoding) * gdb/f-valprint.c (f_val_print) * gdb/findvar.c (default_read_var_value) * gdb/infcmd.c (default_print_one_register_info) * gdb/p-lang.c (pascal_printstr) * gdb/p-valprint.c (pascal_val_print) * gdb/printcmd.c (print_scalar_formatted, printf_decfloat) * gdb/python/py-value.c (valpy_nonzero) * gdb/solib-darwin.c (open_symbol_file_object) * gdb/solib-svr4.c (solib_svr4_r_brk) * gdb/stap-probe.c (stap_modify_semaphore) * gdb/valarith.c (value_args_as_decimal, scalar_binop, value_logical_not, value_neg) * gdb/valops.c (value_cast, value_one) * gdb/valprint.c (print_decimal_floating, generic_emit_char, generic_printstr, val_print_string) * gdb/value.c (value_as_address, unpack_long, unpack_bits_as_long, unpack_value_bitfield, modify_field, pack_long, pack_unsigned_long) use new helper function type_byte_order(, type) to replace gdbarch_byte_order (get_type_arch (type)); * gdb/testsuite/gdb.base/endianity.c, gdb/testsuite/gdb.base/endianity.exp New test. print a value in a struct with non-native endianity. Modify that value in a print statement and re-print the structure. --- ChangeLog | 5 ++++ binutils/dwarf.c | 11 +++++++++ gdb/ChangeLog | 37 ++++++++++++++++++++++++++++++ gdb/ada-lang.c | 2 +- gdb/ada-valprint.c | 4 ++-- gdb/c-lang.c | 2 +- gdb/c-valprint.c | 2 +- gdb/cp-valprint.c | 2 +- gdb/dwarf2loc.c | 5 ++-- gdb/dwarf2read.c | 18 +++++++++++++++ gdb/f-lang.c | 2 +- gdb/f-valprint.c | 2 +- gdb/findvar.c | 2 +- gdb/gdbtypes.c | 22 ++++++++++++++++++ gdb/gdbtypes.h | 14 ++++++++++++ gdb/infcmd.c | 2 +- gdb/p-lang.c | 2 +- gdb/p-valprint.c | 2 +- gdb/printcmd.c | 4 ++-- gdb/python/py-value.c | 2 +- gdb/solib-darwin.c | 5 ++-- gdb/solib-svr4.c | 5 ++-- gdb/stap-probe.c | 7 +++--- gdb/testsuite/gdb.base/endianity.c | 44 ++++++++++++++++++++++++++++++++++++ gdb/testsuite/gdb.base/endianity.exp | 34 ++++++++++++++++++++++++++++ gdb/valarith.c | 25 ++++++++++---------- gdb/valops.c | 6 ++--- gdb/valprint.c | 8 +++---- gdb/value.c | 14 ++++++------ 29 files changed, 239 insertions(+), 51 deletions(-) create mode 100644 gdb/testsuite/gdb.base/endianity.c create mode 100644 gdb/testsuite/gdb.base/endianity.exp diff --git a/ChangeLog b/ChangeLog index b5c224ecc9..a0a2c8fe52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-10-06 Peeter Joot + + * binutils/dwarf.c (read_and_display_attr_value): Handle + DW_AT_endianity, DW_END_default, DW_END_big, DW_END_little + 2017-09-15 Nick Clifton * src-release.sh (LZIPPROG): New define. Provides the name of the diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 91f95ff068..e79fd5e4b4 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -2283,6 +2283,17 @@ read_and_display_attr_value (unsigned long attribute, } break; + case DW_AT_endianity: + printf ("\t"); + switch (uvalue) + { + case DW_END_default: printf ("(default)"); break; + case DW_END_big: printf ("(big)"); break; + case DW_END_little: printf ("(little)"); break; + default: printf (_("(unknown endianity)")); break; + } + break; + case DW_AT_virtuality: printf ("\t"); switch (uvalue) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 18224e0305..6719cbace5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,40 @@ +2017-10-06 Peeter Joot + + * gdb/gdbtypes.h (global scope): define TYPE_ENDIANITY_BIG, + TYPE_ENDIANITY_LITTLE. New function: type_byte_order + * gdb/dwarf2read.c (read_base_type): Handle DW_END_big, DW_END_little + * gdb/gdbtypes.c (check_types_equal): Require matching + TYPE_ENDIANITY_BIG, and TYPE_ENDIANITY_LITTLE if set. + New function: type_byte_order. + (recursive_dump_type): Print TYPE_ENDIANITY_BIG, and + TYPE_ENDIANITY_LITTLE if set. + (struct main_type): Add flag_endianity_big, flag_endianity_little + * gdb/ada-lang.c (ada_value_binop) + * gdb/ada-valprint.c (printstr, ada_val_print_string) + * gdb/c-lang.c (c_get_string) + * gdb/c-valprint.c (c_val_print_array) + * gdb/cp-valprint.c (cp_print_class_member) + * gdb/dwarf2loc.c (rw_pieced_value) + * gdb/f-lang.c (f_get_encoding) + * gdb/f-valprint.c (f_val_print) + * gdb/findvar.c (default_read_var_value) + * gdb/infcmd.c (default_print_one_register_info) + * gdb/p-lang.c (pascal_printstr) + * gdb/p-valprint.c (pascal_val_print) + * gdb/printcmd.c (print_scalar_formatted, printf_decfloat) + * gdb/python/py-value.c (valpy_nonzero) + * gdb/solib-darwin.c (open_symbol_file_object) + * gdb/solib-svr4.c (solib_svr4_r_brk) + * gdb/stap-probe.c (stap_modify_semaphore) + * gdb/valarith.c (value_args_as_decimal, scalar_binop, value_logical_not, value_neg) + * gdb/valops.c (value_cast, value_one) + * gdb/valprint.c (print_decimal_floating, generic_emit_char, generic_printstr, val_print_string) + * gdb/value.c (value_as_address, unpack_long, unpack_bits_as_long, unpack_value_bitfield, modify_field, pack_long, pack_unsigned_long) + use new helper function type_byte_order(, type) to replace gdbarch_byte_order (get_type_arch (type)); + * gdb/testsuite/gdb.base/endianity.c, gdb/testsuite/gdb.base/endianity.exp + New test. print a value in a struct with non-native endianity. + Modify that value in a print statement and re-print the structure. + 2017-10-06 Yao Qi * Makefile.in (ALL_64_TARGET_OBS): Replace aarch64-insn.o with diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 1a0c769594..cfe0d39e81 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -9761,7 +9761,7 @@ ada_value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) 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 (NULL, type1), v); return val; } diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c index 8095eede72..0584745d14 100644 --- a/gdb/ada-valprint.c +++ b/gdb/ada-valprint.c @@ -442,7 +442,7 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, 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 (NULL, elttype); unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; @@ -683,7 +683,7 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr, 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 (NULL, type); struct type *elttype = TYPE_TARGET_TYPE (type); unsigned int eltlen; unsigned int len; diff --git a/gdb/c-lang.c b/gdb/c-lang.c index f86e26ed5f..b6b863df4c 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -243,7 +243,7 @@ c_get_string (struct value *value, gdb_byte **buffer, 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 (NULL, type); if (element_type == NULL) goto error; diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 653fed657a..767fa73907 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -246,7 +246,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 (gdbarch, type); unsigned int i = 0; /* Number of characters printed. */ if (!get_array_bounds (type, &low_bound, &high_bound)) diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index fb9bfd904f..a94391b8ef 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -755,7 +755,7 @@ void 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 (NULL, type); /* VAL is a byte offset into the structure type SELF_TYPE. Find the name of the field for that offset and diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index c485eaf8b0..9ea85f497f 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1773,8 +1773,9 @@ rw_pieced_value (struct value *v, struct value *from) struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); gdb::byte_vector buffer; + struct gdbarch *gdbarch = get_type_arch (value_type (v)); int bits_big_endian - = gdbarch_bits_big_endian (get_type_arch (value_type (v))); + = gdbarch_bits_big_endian (gdbarch); if (from != NULL) { @@ -1797,7 +1798,7 @@ rw_pieced_value (struct value *v, struct value *from) 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 (gdbarch, value_type (from)) == BFD_ENDIAN_BIG)) { /* Use the least significant bits of FROM. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 1b15adced6..0883bf1b0f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -15234,6 +15234,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) struct type *type; struct attribute *attr; int encoding = 0, bits = 0; + int endianity = 0; const char *name; attr = dwarf2_attr (die, DW_AT_encoding, cu); @@ -15252,6 +15253,11 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("DW_AT_name missing from DW_TAG_base_type")); } + attr = dwarf2_attr (die, DW_AT_endianity, cu); + if (attr) + { + endianity = DW_UNSND (attr); // break here + } switch (encoding) { @@ -15330,6 +15336,18 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) if (name && strcmp (name, "char") == 0) TYPE_NOSIGN (type) = 1; + TYPE_ENDIANITY_BIG (type) = 0; + TYPE_ENDIANITY_LITTLE (type) = 0; + switch (endianity) + { + case DW_END_big: + TYPE_ENDIANITY_BIG (type) = 1; // break here + break; + case DW_END_little: + TYPE_ENDIANITY_LITTLE (type) = 1; // break here + break; + } + return set_die_type (die, type, cu); } diff --git a/gdb/f-lang.c b/gdb/f-lang.c index 073d5291f7..79ea9ff8c1 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -55,7 +55,7 @@ f_get_encoding (struct type *type) 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 (NULL, type) == BFD_ENDIAN_BIG) encoding = "UTF-32BE"; else encoding = "UTF-32LE"; diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 5bcab9d525..6e6c001c30 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -215,7 +215,7 @@ f_val_print (struct type *type, int embedded_offset, 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 (gdbarch, type); int printed_field = 0; /* Number of fields printed. */ struct type *elttype; CORE_ADDR addr; diff --git a/gdb/findvar.c b/gdb/findvar.c index 2bc2095bf7..f980f1cbf8 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -622,7 +622,7 @@ default_read_var_value (struct symbol *var, const struct block *var_block, /* 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 (NULL, type), (LONGEST) SYMBOL_VALUE (var)); VALUE_LVAL (v) = not_lval; return v; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 73d445361d..5519ca5372 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3423,6 +3423,8 @@ check_types_equal (struct type *type1, struct type *type2, || TYPE_LENGTH (type1) != TYPE_LENGTH (type2) || TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2) || TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2) + || TYPE_ENDIANITY_BIG (type1) != TYPE_ENDIANITY_BIG (type2) + || TYPE_ENDIANITY_LITTLE (type1) != TYPE_ENDIANITY_LITTLE (type2) || TYPE_VARARGS (type1) != TYPE_VARARGS (type2) || TYPE_VECTOR (type1) != TYPE_VECTOR (type2) || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2) @@ -4460,6 +4462,14 @@ recursive_dump_type (struct type *type, int spaces) { puts_filtered (" TYPE_NOSIGN"); } + if (TYPE_ENDIANITY_BIG (type)) + { + puts_filtered (" TYPE_ENDIANITY_BIG"); + } + if (TYPE_ENDIANITY_LITTLE (type)) + { + puts_filtered (" TYPE_ENDIANITY_LITTLE"); + } if (TYPE_STUB (type)) { puts_filtered (" TYPE_STUB"); @@ -5401,3 +5411,15 @@ _initialize_gdbtypes (void) show_strict_type_checking, &setchecklist, &showchecklist); } + +enum bfd_endian +type_byte_order (struct gdbarch * gdbarch, struct type *type) +{ + if (TYPE_ENDIANITY_BIG (type)) + return BFD_ENDIAN_BIG; + else if (TYPE_ENDIANITY_LITTLE (type)) + return BFD_ENDIAN_LITTLE; + if (!gdbarch) + gdbarch = get_type_arch (type); + return gdbarch_byte_order (gdbarch); +} diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 009cea90d9..28ff20c6d9 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -210,6 +210,16 @@ DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags); #define TYPE_NOSIGN(t) (TYPE_MAIN_TYPE (t)->flag_nosign) +/* * Mixed endian archetectures can supply dwarf instrumentation + * that indicates the desired endian interpretation of the variable. + * This indicates that the interpretation should be big-endian + * even if the cpu is running in little endian mode. */ +#define TYPE_ENDIANITY_BIG(t) (TYPE_MAIN_TYPE (t)->flag_endianity_big) + +/* * The type has a little endian interpretation even if the cpu + * is running in big endian mode. */ +#define TYPE_ENDIANITY_LITTLE(t) (TYPE_MAIN_TYPE (t)->flag_endianity_little) + /* * 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 *)). */ @@ -616,6 +626,8 @@ struct main_type unsigned int flag_gnu_ifunc : 1; unsigned int flag_fixed_instance : 1; unsigned int flag_objfile_owned : 1; + unsigned int flag_endianity_big : 1; + unsigned int flag_endianity_little : 1; /* * True if this type was declared with "class" rather than "struct". */ @@ -1951,4 +1963,6 @@ extern int type_not_allocated (const struct type *type); extern int type_not_associated (const struct type *type); +extern enum bfd_endian type_byte_order (struct gdbarch *, struct type *type); + #endif /* GDBTYPES_H */ diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 187c71f344..d31a9c8ddd 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -2364,7 +2364,7 @@ default_print_one_register_info (struct ui_file *file, { 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 (NULL, regtype); get_user_print_options (&opts); opts.deref_ref = 1; diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 439a3772cb..ec2df7f29a 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -218,7 +218,7 @@ pascal_printstr (struct ui_file *stream, struct type *type, 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 (NULL, type); unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index d12b63638b..7941b0875f 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -66,7 +66,7 @@ pascal_val_print (struct type *type, 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 (gdbarch, type); unsigned int i = 0; /* Number of characters printed */ unsigned len; LONGEST low_bound, high_bound; diff --git a/gdb/printcmd.c b/gdb/printcmd.c index a8743f1f71..0e027f1b0b 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -354,7 +354,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type, { 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 (gdbarch, type); /* String printing should go through val_print_scalar_formatted. */ gdb_assert (options->format != 's'); @@ -2299,7 +2299,7 @@ printf_decfloat (struct ui_file *stream, const char *format, /* Parameter data. */ struct type *param_type = value_type (value); struct gdbarch *gdbarch = get_type_arch (param_type); - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + enum bfd_endian byte_order = type_byte_order (NULL, param_type); /* DFP output data. */ struct value *dfp_value = NULL; diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index cbbb9362ec..60683b906a 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1322,7 +1322,7 @@ valpy_nonzero (PyObject *self) else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT) nonzero = !decimal_is_zero (value_contents (self_value->value), TYPE_LENGTH (type), - gdbarch_byte_order (get_type_arch (type))); + type_byte_order (NULL, type)); else /* All other values are True. */ nonzero = 1; diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 04bbf86cf1..c6ca869860 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -232,8 +232,9 @@ open_symbol_file_object (void *from_ttyp) static struct so_list * 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 ()); + struct gdbarch *gdbarch = target_gdbarch (); + struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; + enum bfd_endian byte_order = type_byte_order (gdbarch, ptr_type); int ptr_len = TYPE_LENGTH (ptr_type); unsigned int image_info_size; struct so_list *head = NULL; diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 405de37aa5..24e523116c 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -920,9 +920,10 @@ solib_svr4_r_brk (struct svr4_info *info) static CORE_ADDR solib_svr4_r_ldsomap (struct svr4_info *info) { + struct gdbarch *gdbarch = target_gdbarch (); 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 ()); + struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; + enum bfd_endian byte_order = type_byte_order (gdbarch, ptr_type); ULONGEST version = 0; TRY diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c index 6fa0d20280..ea51d1ae49 100644 --- a/gdb/stap-probe.c +++ b/gdb/stap-probe.c @@ -1403,8 +1403,8 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch) return; } - value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), - gdbarch_byte_order (gdbarch)); + enum bfd_endian byte_order = type_byte_order (gdbarch, type); + value = extract_unsigned_integer (bytes, TYPE_LENGTH (type), byte_order); /* Note that we explicitly don't worry about overflow or underflow. */ if (set) @@ -1412,8 +1412,7 @@ stap_modify_semaphore (CORE_ADDR address, int set, struct gdbarch *gdbarch) 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.")); diff --git a/gdb/testsuite/gdb.base/endianity.c b/gdb/testsuite/gdb.base/endianity.c new file mode 100644 index 0000000000..330395a970 --- /dev/null +++ b/gdb/testsuite/gdb.base/endianity.c @@ -0,0 +1,44 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2017 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 . */ + +/* This tests the handling of dwarf attributes: + DW_AT_endianity, DW_END_big, and DW_END_little. */ +struct otherendian +{ + int v; +} +#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}; + + do_nothing (&o); /* START */ +} diff --git a/gdb/testsuite/gdb.base/endianity.exp b/gdb/testsuite/gdb.base/endianity.exp new file mode 100644 index 0000000000..e125838dfd --- /dev/null +++ b/gdb/testsuite/gdb.base/endianity.exp @@ -0,0 +1,34 @@ +# Copyright 2017 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 . + +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 { + return -1 +} + +gdb_test "print o" "= {v = 3}" + +gdb_test "print o.v = 4" "= 4" + +# expect this to fail if compiled with < gcc6. +gdb_test "x/x &o.v" "0x04000000" + +gdb_test "print o" "= {v = 4}" diff --git a/gdb/valarith.c b/gdb/valarith.c index ede60e4b68..bcb0372830 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -873,13 +873,13 @@ value_args_as_decimal (struct value *arg1, struct value *arg2, if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT) { - *byte_order_x = gdbarch_byte_order (get_type_arch (type1)); + *byte_order_x = type_byte_order (NULL, type1); *len_x = TYPE_LENGTH (type1); memcpy (x, value_contents (arg1), *len_x); } else if (is_integral_type (type1)) { - *byte_order_x = gdbarch_byte_order (get_type_arch (type2)); + *byte_order_x = type_byte_order (NULL, type2); *len_x = TYPE_LENGTH (type2); if (TYPE_UNSIGNED (type1)) decimal_from_ulongest (value_as_long (arg1), x, *len_x, *byte_order_x); @@ -895,13 +895,13 @@ value_args_as_decimal (struct value *arg1, struct value *arg2, if (TYPE_CODE (type2) == TYPE_CODE_DECFLOAT) { - *byte_order_y = gdbarch_byte_order (get_type_arch (type2)); + *byte_order_y = type_byte_order (NULL, type2); *len_y = TYPE_LENGTH (type2); memcpy (y, value_contents (arg2), *len_y); } else if (is_integral_type (type2)) { - *byte_order_y = gdbarch_byte_order (get_type_arch (type1)); + *byte_order_y = type_byte_order (NULL, type1); *len_y = TYPE_LENGTH (type1); if (TYPE_UNSIGNED (type2)) decimal_from_ulongest (value_as_long (arg2), y, *len_y, *byte_order_y); @@ -930,6 +930,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) type1 = check_typedef (value_type (arg1)); type2 = check_typedef (value_type (arg2)); + struct gdbarch *gdbarch = get_type_arch (type1); if ((TYPE_CODE (type1) != TYPE_CODE_FLT && TYPE_CODE (type1) != TYPE_CODE_DECFLOAT @@ -959,7 +960,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) result_type = type1; len_v = TYPE_LENGTH (result_type); - byte_order_v = gdbarch_byte_order (get_type_arch (result_type)); + byte_order_v = type_byte_order (gdbarch, result_type); value_args_as_decimal (arg1, arg2, v1, &len_v1, &byte_order_v1, v2, &len_v2, &byte_order_v2); @@ -1084,7 +1085,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) 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 (gdbarch, result_type), v); } else @@ -1232,8 +1233,8 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) 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 + (gdbarch, result_type), v); } else @@ -1362,8 +1363,8 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) 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 + (gdbarch, result_type), v); } } @@ -1518,7 +1519,7 @@ value_logical_not (struct value *arg1) return 0 == value_as_double (arg1); else if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT) return decimal_is_zero (value_contents (arg1), TYPE_LENGTH (type1), - gdbarch_byte_order (get_type_arch (type1))); + type_byte_order (NULL, type1)); len = TYPE_LENGTH (type1); p = value_contents (arg1); @@ -1774,7 +1775,7 @@ value_neg (struct value *arg1) memcpy (decbytes, value_contents (arg1), len); - if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_LITTLE) + if (type_byte_order (NULL, type) == BFD_ENDIAN_LITTLE) decbytes[len-1] = decbytes[len - 1] | 0x80; else decbytes[0] = decbytes[0] | 0x80; diff --git a/gdb/valops.c b/gdb/valops.c index de4544cd29..c12cd17b2e 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -466,7 +466,7 @@ value_cast (struct type *type, struct value *arg2) return value_from_double (to_type, value_as_double (arg2)); else if (code1 == TYPE_CODE_DECFLOAT && scalar) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (NULL, type); int dec_len = TYPE_LENGTH (type); gdb_byte dec[16]; @@ -502,7 +502,7 @@ value_cast (struct type *type, struct value *arg2) 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 (NULL, type2)); else longest = value_as_long (arg2); return value_from_longest (to_type, convert_to_boolean ? @@ -870,7 +870,7 @@ value_one (struct type *type) if (TYPE_CODE (type1) == TYPE_CODE_DECFLOAT) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (NULL, type); gdb_byte v[16]; decimal_from_string (v, TYPE_LENGTH (type), byte_order, "1"); diff --git a/gdb/valprint.c b/gdb/valprint.c index ca0c4768c9..73b7306fab 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -1471,7 +1471,7 @@ void print_decimal_floating (const gdb_byte *valaddr, struct type *type, struct ui_file *stream) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (NULL, type); unsigned len = TYPE_LENGTH (type); std::string str = decimal_to_string (valaddr, len, byte_order); @@ -2478,7 +2478,7 @@ generic_emit_char (int c, struct type *type, struct ui_file *stream, int quoter, const char *encoding) { enum bfd_endian byte_order - = gdbarch_byte_order (get_type_arch (type)); + = type_byte_order (NULL, type); gdb_byte *buf; int need_escape = 0; @@ -2799,7 +2799,7 @@ generic_printstr (struct ui_file *stream, struct type *type, 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 (NULL, type); unsigned int i; int width = TYPE_LENGTH (type); struct cleanup *cleanup; @@ -2918,7 +2918,7 @@ val_print_string (struct type *elttype, const char *encoding, gdb_byte *buffer = NULL; /* Dynamically growable fetch buffer. */ struct cleanup *old_chain = NULL; /* Top of the old cleanup chain. */ struct gdbarch *gdbarch = get_type_arch (elttype); - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + enum bfd_endian byte_order = type_byte_order (gdbarch, elttype); int width = TYPE_LENGTH (elttype); /* First we need to figure out the limit on the number of characters we are diff --git a/gdb/value.c b/gdb/value.c index 90423ed002..82e0065256 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -2900,7 +2900,7 @@ value_as_address (struct value *val) 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 (NULL, type); enum type_code code = TYPE_CODE (type); int len = TYPE_LENGTH (type); int nosign = TYPE_UNSIGNED (type); @@ -2949,7 +2949,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr) DOUBLEST unpack_double (struct type *type, const gdb_byte *valaddr, int *invp) { - enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); + enum bfd_endian byte_order = type_byte_order (NULL, type); enum type_code code; int len; int nosign; @@ -3305,7 +3305,7 @@ static LONGEST 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 (NULL, field_type); ULONGEST val; ULONGEST valmask; int lsbcount; @@ -3411,7 +3411,7 @@ unpack_value_bitfield (struct value *dest_val, 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 (NULL, field_type); /* First, unpack and sign extend the bitfield as if it was wholly valid. Optimized out/unavailable bits are read as zero, but @@ -3471,7 +3471,7 @@ void 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 (NULL, type); ULONGEST oword; ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize); LONGEST bytesize; @@ -3517,7 +3517,7 @@ modify_field (struct type *type, gdb_byte *addr, 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 (NULL, type); LONGEST len; type = check_typedef (type); @@ -3558,7 +3558,7 @@ pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) type = check_typedef (type); len = TYPE_LENGTH (type); - byte_order = gdbarch_byte_order (get_type_arch (type)); + byte_order = type_byte_order (NULL, type); switch (TYPE_CODE (type)) {