From 5052b3e23372274399e1e56870c78eaa14172d7f Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Thu, 2 Jul 2020 16:31:11 -0300 Subject: [PATCH] [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. --- gdb/ChangeLog | 18 ++++++++++++++++++ gdb/c-typeprint.c | 2 ++ gdb/dwarf2/read.c | 8 +++----- gdb/gdbtypes.c | 39 +++++++++++++++++++++++++++++++++++++-- gdb/gdbtypes.h | 4 ++++ gdb/valprint.c | 29 +++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e44d615fe3f..e477c46fac3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +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. + 2020-10-20 Luis Machado * aarch64-tdep.c (aarch64_address_class_type_flags) diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index a1264e76ac2..f8a9dfcd05b 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -465,6 +465,7 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_COMPLEX: case TYPE_CODE_NAMESPACE: case TYPE_CODE_DECFLOAT: + 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; @@ -853,6 +854,7 @@ c_type_print_varspec_suffix (struct type *type, case TYPE_CODE_COMPLEX: case TYPE_CODE_NAMESPACE: case TYPE_CODE_DECFLOAT: + 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 000738bcd6a..d3cab7f6190 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -18025,13 +18025,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 a52a57c8394..0c362852457 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3341,6 +3341,22 @@ init_pointer_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 @@ -3370,6 +3386,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: @@ -5014,6 +5031,9 @@ recursive_dump_type (struct type *type, int spaces) case TYPE_CODE_NAMESPACE: printf_filtered ("(TYPE_CODE_NAMESPACE)"); break; + case TYPE_CODE_CAPABILITY: + printf_filtered ("(TYPE_CODE_CAPABILITY)"); + break; default: printf_filtered ("(UNKNOWN TYPE CODE)"); break; @@ -5603,6 +5623,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. */ @@ -5890,9 +5925,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 8c9278936c2..fb2062d8d59 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -2214,6 +2214,8 @@ extern struct type *init_decfloat_type (struct objfile *, int, const char *); extern struct type *init_complex_type (const char *, struct type *); extern struct type *init_pointer_type (struct objfile *, int, const char *, struct type *); +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, @@ -2229,6 +2231,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 dd70a1a3933..6e1672a3dca 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -43,6 +43,8 @@ #include "c-lang.h" #include "cp-abi.h" +#include "gdbsupport/capability.h" + /* Maximum number of wchars returned from wchar_iterate. */ #define MAX_WCHARS 4 @@ -476,6 +478,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); + 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. */ @@ -859,6 +884,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, -- 2.47.3