From: Luis Machado Date: Thu, 2 Jul 2020 19:31:11 +0000 (-0300) Subject: [General] More capability type handling (merge with others) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da8a4f5b99d899eb06102b9326ede6ecf854f866;p=thirdparty%2Fbinutils-gdb.git [General] More capability type handling (merge with others) Teach more parts of GDB how to handle capabilities properly, add a function to print capabilities in their natural format and initialize capability types properly. gdb/ChangeLog: 2020-10-20 Luis Machado * c-typeprint.c (c_type_print_varspec_prefix) (c_type_print_varspec_suffix): Handle capability type. * dwarf2/read.c (read_base_type): Call init_capability_type for capabilities. * gdbtypes.c (init_capability_type): New function. (type_align): Handle capability type. (recursive_dump_type): Likewise. (arch_capability_type): New function. (gdbtypes_post_init): Call arch_capability_type for capability types. * gdbtypes.h (init_capability_type, arch_capability_type): New prototypes. * valprint.c: Include gdbsupport/capability.h. (generic_value_print_capability): New function. (generic_value_print): Handle capability types. --- diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index a16c53b8f44..38f6d7ede9a 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -467,6 +467,7 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_NAMESPACE: case TYPE_CODE_DECFLOAT: case TYPE_CODE_FIXED_POINT: + case TYPE_CODE_CAPABILITY: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; @@ -856,6 +857,7 @@ c_type_print_varspec_suffix (struct type *type, case TYPE_CODE_NAMESPACE: case TYPE_CODE_DECFLOAT: case TYPE_CODE_FIXED_POINT: + case TYPE_CODE_CAPABILITY: /* These types do not need a suffix. They are listed so that gcc -Wall will report types that may not have been considered. */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 139fee4685e..7cb63053c25 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -18285,13 +18285,11 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) break; case DW_ATE_CHERI_signed_intcap: + type = init_capability_type (objfile, bits, false, name); + break; case DW_ATE_CHERI_unsigned_intcap: - { - /* Turn DW_ATE_CHERI_*_intcap into a void * pointer. */ - type = init_type (objfile, TYPE_CODE_VOID, TARGET_CHAR_BIT, NULL); - type = init_pointer_type (objfile, bits, name, type); + type = init_capability_type (objfile, bits, true, name); break; - } default: complaint (_("unsupported DW_AT_encoding: '%s'"), diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 83b1c28af46..d42d9eda502 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3521,6 +3521,22 @@ init_fixed_point_type (struct objfile *objfile, return t; } +/* Allocate a TYPE_CODE_CAPABILITY type structure associated with OBJFILE. + BIT is the type size in bits. If UNSIGNED_P is non-zero, set + the type's TYPE_UNSIGNED flag. NAME is the type name. */ + +struct type * +init_capability_type (struct objfile *objfile, + int bit, bool unsigned_p, const char *name) +{ + struct type *t; + + t = init_type (objfile, TYPE_CODE_CAPABILITY, bit, name); + t->set_is_unsigned (unsigned_p); + + return t; +} + /* See gdbtypes.h. */ unsigned @@ -3549,6 +3565,7 @@ type_align (struct type *type) switch (type->code ()) { case TYPE_CODE_PTR: + case TYPE_CODE_CAPABILITY: case TYPE_CODE_FUNC: case TYPE_CODE_FLAGS: case TYPE_CODE_INT: @@ -5237,6 +5254,9 @@ recursive_dump_type (struct type *type, int spaces) case TYPE_CODE_FIXED_POINT: printf_filtered ("(TYPE_CODE_FIXED_POINT)"); break; + case TYPE_CODE_CAPABILITY: + printf_filtered ("(TYPE_CODE_CAPABILITY)"); + break; default: printf_filtered ("(UNKNOWN TYPE CODE)"); break; @@ -5840,6 +5860,21 @@ arch_pointer_type (struct gdbarch *gdbarch, return t; } +/* Allocate a TYPE_CODE_CAPABILITY type structure associated with GDBARCH. + BIT is the type size in bits. If UNSIGNED_P is non-zero, set + the type's TYPE_UNSIGNED flag. NAME is the type name. */ + +struct type * +arch_capability_type (struct gdbarch *gdbarch, + int bit, bool unsigned_p, const char *name) +{ + struct type *t; + + t = arch_type (gdbarch, TYPE_CODE_CAPABILITY, bit, name); + t->set_is_unsigned (unsigned_p); + return t; +} + /* Allocate a TYPE_CODE_FLAGS type structure associated with GDBARCH. NAME is the type name. BIT is the size of the flag word in bits. */ @@ -6204,9 +6239,9 @@ gdbtypes_post_init (struct gdbarch *gdbarch) /* Capability types. */ builtin_type->builtin_intcap_t - = arch_integer_type (gdbarch, 128, 0, "__intcap_t"); + = arch_capability_type (gdbarch, 128, 0, "__intcap_t"); builtin_type->builtin_uintcap_t - = arch_integer_type (gdbarch, 128, 1, "__uintcap_t"); + = arch_capability_type (gdbarch, 128, 1, "__uintcap_t"); /* Capability pointer types. */ builtin_type->builtin_data_addr_capability diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index d434413f71d..d7c2199585d 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -2498,6 +2498,8 @@ extern struct type *init_pointer_type (struct objfile *, int, const char *, struct type *); extern struct type *init_fixed_point_type (struct objfile *, int, int, const char *); +extern struct type *init_capability_type (struct objfile *objfile, int bit, + bool unsigned_p, const char *name); /* Helper functions to construct architecture-owned types. */ extern struct type *arch_type (struct gdbarch *, enum type_code, int, @@ -2513,6 +2515,8 @@ extern struct type *arch_float_type (struct gdbarch *, int, const char *, extern struct type *arch_decfloat_type (struct gdbarch *, int, const char *); extern struct type *arch_pointer_type (struct gdbarch *, int, const char *, struct type *); +extern struct type *arch_capability_type (struct gdbarch *gdbarch, int bit, + bool unsigned_p, const char *name); /* Helper functions to construct a struct or record type. An initially empty type is created using arch_composite_type(). diff --git a/gdb/valprint.c b/gdb/valprint.c index c2ffe6224bf..01a4a12b521 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -46,6 +46,8 @@ #include "gdbsupport/selftest.h" #include "selftest-arch.h" +#include "gdbsupport/capability.h" + /* Maximum number of wchars returned from wchar_iterate. */ #define MAX_WCHARS 4 @@ -491,6 +493,29 @@ generic_value_print_ptr (struct value *val, struct ui_file *stream, } } +/* generic_value_print helper for TYPE_CODE_CAPABILITY. */ + +static void +generic_value_print_capability (struct value *val, struct ui_file *stream, + const struct value_print_options *options) +{ + struct type *type = check_typedef (value_type (val)); + int length = TYPE_LENGTH (type); + const gdb_byte *contents = value_contents_for_printing (val).data (); + enum bfd_endian byte_order = type_byte_order (type); + + if (options->format && options->format == 'x') + print_hex_chars (stream, contents, length, byte_order, 0); + else + { + uint128_t dummy_cap; + memcpy (&dummy_cap, contents, length); + capability cap (dummy_cap, false); + fprintf_filtered (stream, "%s", cap.to_str ().c_str ()); + } + + return; +} /* Print '@' followed by the address contained in ADDRESS_BUFFER. */ @@ -911,6 +936,10 @@ generic_value_print (struct value *val, struct ui_file *stream, int recurse, generic_value_print_ptr (val, stream, options); break; + case TYPE_CODE_CAPABILITY: + generic_value_print_capability (val, stream, options); + break; + case TYPE_CODE_REF: case TYPE_CODE_RVALUE_REF: generic_val_print_ref (type, 0, stream, recurse,