+2020-10-20 Luis Machado <luis.machado@arm.com>
+
+ * gdb/c-exp.y (CAPABILITY, INTCAP_KEYWORD, UINTCAP_KEYWORD): New
+ tokens.
+ Handle new tokens.
+ * gdb/c-lang.c (c_primitive_types) <c_primitive_type_intcap_t>
+ <c_primitive_type_uintcap_t>: New fields.
+ (c_language_arch_info): Handle intcap/uintcap.
+ (cplus_primitive_types) <cplus_primitive_type_intcap_t>
+ <cplus_primitive_type_uintcap_t>: New fields.
+ (cplus_language::language_arch_info): Handle intcap/uintcap.
+ * gdb/c-typeprint.c (c_type_print_modifier): Handle the __capability
+ modifier.
+ * gdb/gdbtypes.c (make_capability_type): New function.
+ (make_unqualified_type): Handle capabilities.
+ (recursive_dump_type): Likewise.
+ (gdbtypes_post_init): Initialize capability builtins.
+ * gdb/gdbtypes.h (TYPE_INSTANCE_FLAG_CAPABILITY): New flag.
+ (TYPE_CAPABILITY): New define.
+ (struct type) <m_instance_flags>: New field.
+ (struct builtin_type) <builtin_intcap_t, builtin_uintcap_t>: New
+ fields.
+ (make_capability_type): New prototype.
+ * gdb/type-stack.c (type_stack::insert)
+ (type_stack::follow_type_instance_flags)
+ (type_stack::follow_types): Handle capability modifier.
+ * gdb/type-stack.h (enum type_pieces) <tp_capability>: New field.
+
2020-10-20 Luis Machado <luis.machado@arm.com>
* gdbtypes.h (enum type_code) <TYPE_CODE_CAPABILITY>: New enum.
/* Special type cases, put in to allow the parser to distinguish different
legal basetypes. */
%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
-%token RESTRICT ATOMIC
-%token FLOAT_KEYWORD COMPLEX
+%token RESTRICT ATOMIC CAPABILITY
+%token FLOAT_KEYWORD COMPLEX INTCAP_KEYWORD UINTCAP_KEYWORD
%token <sval> DOLLAR_VARIABLE
{ cpstate->type_stack.insert (tp_atomic); }
| RESTRICT
{ cpstate->type_stack.insert (tp_restrict); }
+ | CAPABILITY
+ { cpstate->type_stack.insert (tp_capability); }
| '@' NAME
{
cpstate->type_stack.insert (pstate,
"float",
NULL,
0); }
+ | INTCAP_KEYWORD
+ { $$ = lookup_typename (pstate->language (),
+ "__intcap_t",
+ NULL,
+ 0); }
+ | UINTCAP_KEYWORD
+ { $$ = lookup_typename (pstate->language (),
+ "__uintcap_t",
+ NULL,
+ 0); }
| LONG DOUBLE_KEYWORD
{ $$ = lookup_typename (pstate->language (),
"long double",
{"alignof", ALIGNOF, OP_NULL, FLAG_CXX},
{"double", DOUBLE_KEYWORD, OP_NULL, 0},
{"float", FLOAT_KEYWORD, OP_NULL, 0},
+ {"__intcap_t", INTCAP_KEYWORD, OP_NULL, 0},
+ {"__uintcap_t", UINTCAP_KEYWORD, OP_NULL, 0},
{"false", FALSEKEYWORD, OP_NULL, FLAG_CXX},
{"class", CLASS, OP_NULL, FLAG_CXX},
{"union", UNION, OP_NULL, 0},
{"long", LONG, OP_NULL, 0},
{"_Complex", COMPLEX, OP_NULL, 0},
{"__complex__", COMPLEX, OP_NULL, 0},
+ {"__capability", CAPABILITY, OP_NULL, 0},
{"true", TRUEKEYWORD, OP_NULL, FLAG_CXX},
{"int", INT_KEYWORD, OP_NULL, 0},
c_primitive_type_decfloat,
c_primitive_type_decdouble,
c_primitive_type_declong,
+ c_primitive_type_intcap_t,
+ c_primitive_type_uintcap_t,
nr_c_primitive_types
};
lai->primitive_type_vector [c_primitive_type_decfloat] = builtin->builtin_decfloat;
lai->primitive_type_vector [c_primitive_type_decdouble] = builtin->builtin_decdouble;
lai->primitive_type_vector [c_primitive_type_declong] = builtin->builtin_declong;
+ lai->primitive_type_vector [c_primitive_type_intcap_t] = builtin->builtin_intcap_t;
+ lai->primitive_type_vector [c_primitive_type_uintcap_t] = builtin->builtin_uintcap_t;
lai->bool_type_default = builtin->builtin_int;
}
cplus_primitive_type_char16_t,
cplus_primitive_type_char32_t,
cplus_primitive_type_wchar_t,
+ cplus_primitive_type_intcap_t,
+ cplus_primitive_type_uintcap_t,
nr_cplus_primitive_types
};
= builtin->builtin_char32;
lai->primitive_type_vector [cplus_primitive_type_wchar_t]
= builtin->builtin_wchar;
+ lai->primitive_type_vector [cplus_primitive_type_intcap_t]
+ = builtin->builtin_intcap_t;
+ lai->primitive_type_vector [cplus_primitive_type_uintcap_t]
+ = builtin->builtin_uintcap_t;
lai->bool_type_symbol = "bool";
lai->bool_type_default = builtin->builtin_bool;
did_print_modifier = 1;
}
+ if (TYPE_CAPABILITY (type))
+ {
+ if (did_print_modifier || need_pre_space)
+ fprintf_filtered (stream, " ");
+ fprintf_filtered (stream, "__capability");
+ did_print_modifier = 1;
+ }
+
address_space_id
= address_space_type_instance_flags_to_name (get_type_arch (type),
type->instance_flags ());
+
if (address_space_id)
{
if (did_print_modifier || need_pre_space)
NULL);
}
+/* Make a 'capability'-qualified version of TYPE. */
+
+struct type *
+make_capability_type (struct type *type)
+{
+ struct type *ntype;
+ ntype = make_qualified_type (type,
+ (type->instance_flags ()
+ | TYPE_INSTANCE_FLAG_CAPABILITY),
+ NULL);
+
+ /* Capability pointers are 128-bit. */
+ TYPE_LENGTH (ntype) = 16;
+
+ return ntype;
+}
+
/* Make a type without const, volatile, or restrict. */
struct type *
(type->instance_flags ()
& ~(TYPE_INSTANCE_FLAG_CONST
| TYPE_INSTANCE_FLAG_VOLATILE
- | TYPE_INSTANCE_FLAG_RESTRICT)),
+ | TYPE_INSTANCE_FLAG_RESTRICT
+ | TYPE_INSTANCE_FLAG_CAPABILITY)),
NULL);
}
{
puts_filtered (" TYPE_ATOMIC");
}
+ if (TYPE_CAPABILITY (type))
+ {
+ puts_filtered (" TYPE_CAPABILITY");
+ }
puts_filtered ("\n");
printfi_filtered (spaces, "flags");
builtin_type->builtin_func_func
= lookup_function_type (builtin_type->builtin_func_ptr);
+ /* Capability types. */
+ builtin_type->builtin_intcap_t
+ = arch_integer_type (gdbarch, 128, 0, "__intcap_t");
+ builtin_type->builtin_uintcap_t
+ = arch_integer_type (gdbarch, 128, 1, "__uintcap_t");
+
+ /* Capability pointer types. */
+ builtin_type->builtin_data_addr_capability
+ = lookup_pointer_type (builtin_type->builtin_intcap_t);
+ builtin_type->builtin_code_addr_capability
+ = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
+
/* This type represents a GDB internal function. */
builtin_type->internal_fn
= arch_type (gdbarch, TYPE_CODE_INTERNAL_FUNCTION, 0,
TYPE_INSTANCE_FLAG_ADDRESS_CLASS_2 = (1 << 5),
TYPE_INSTANCE_FLAG_NOTTEXT = (1 << 6),
TYPE_INSTANCE_FLAG_RESTRICT = (1 << 7),
- TYPE_INSTANCE_FLAG_ATOMIC = (1 << 8)
+ TYPE_INSTANCE_FLAG_ATOMIC = (1 << 8),
+ TYPE_INSTANCE_FLAG_CAPABILITY = (1 << 9)
};
DEF_ENUM_FLAGS_TYPE (enum type_instance_flag_value, type_instance_flags);
#define TYPE_ATOMIC(t) \
((((t)->instance_flags ()) & TYPE_INSTANCE_FLAG_ATOMIC) != 0)
+/* * Capability type. If this is set, the corresponding type has a
+ __capability modifier. */
+
+#define TYPE_CAPABILITY(t) \
+ ((((t)->instance_flags ()) & TYPE_INSTANCE_FLAG_CAPABILITY) != 0)
+
/* * True if this type represents either an lvalue or lvalue reference type. */
#define TYPE_IS_REFERENCE(t) \
instance flags are completely inherited from the target type. No
qualifiers can be cleared by the typedef. See also
check_typedef. */
- unsigned m_instance_flags : 9;
+ unsigned m_instance_flags : 10;
/* * Length of storage for a value of this type. The value is the
expression in host bytes of what sizeof(type) would return. This
struct type *builtin_func_func;
+ /* ARM signed integer/capability. */
+ struct type *builtin_intcap_t;
+
+ /* ARM unsigned integer/capability. */
+ struct type *builtin_uintcap_t;
+
/* Data address capability. */
struct type *builtin_data_addr_capability;
extern struct type *make_restrict_type (struct type *);
+extern struct type *make_capability_type (struct type *);
+
extern struct type *make_unqualified_type (struct type *);
extern struct type *make_atomic_type (struct type *);
+2020-10-20 Luis Machado <luis.machado@arm.com>
+
+ * gdb.arch/aarch64-morello-captypes.c: New file.
+ * gdb.arch/aarch64-morello-captypes.exp: New file.
+
2020-10-20 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/pr13961.S: Remove superfluous end-of-siblings marker.
--- /dev/null
+/* This file is part of GDB, the GNU debugger.
+
+ Copyright 2020 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/>. */
+
+int
+main (void)
+{
+ return 0;
+}
--- /dev/null
+# Copyright 2020 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 file is part of the gdb testsuite.
+
+# Test if GDB stops at various BRK instruction patterns inserted into
+# the code.
+
+if {![is_aarch64_target]} {
+ verbose "Skipping ${gdb_test_file_name}."
+ return
+}
+
+standard_testfile
+if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} {
+ return -1
+}
+
+if {![runto_main]} {
+ untested "could not run to main"
+ return -1
+}
+
+foreach type { "__intcap_t" "__uintcap_t" } {
+ gdb_test "ptype ${type}" "type = ${type}" \
+ "capability type ${type}"
+ gdb_test "p sizeof (${type})" ".* = 16" \
+ "capability type ${type} has size 16"
+}
+
+foreach type { "void" "char" "int" "long" "float" "double" "__intcap_t" "__uintcap_t" } {
+ set ptr "${type} \* __capability"
+ gdb_test "ptype ((${ptr}) 0x0)" "type = ${type} \\* __capability" \
+ "capability pointer to ${type}"
+ gdb_test "p sizeof (${ptr})" ".* = 16" \
+ "capability pointer to ${type} is size 16"
+}
gdb_assert (tp == tp_pointer || tp == tp_reference
|| tp == tp_rvalue_reference || tp == tp_const
|| tp == tp_volatile || tp == tp_restrict
- || tp == tp_atomic);
+ || tp == tp_atomic || tp == tp_capability);
/* If there is anything on the stack (we know it will be a
tp_pointer), insert the qualifier above it. Otherwise, simply
push this on the top of the stack. */
if (!m_elements.empty () && (tp == tp_const || tp == tp_volatile
- || tp == tp_restrict))
+ || tp == tp_restrict || tp == tp_capability))
slot = 1;
else
slot = 0;
case tp_restrict:
flags |= TYPE_INSTANCE_FLAG_RESTRICT;
break;
+ case tp_capability:
+ flags |= TYPE_INSTANCE_FLAG_CAPABILITY;
+ break;
default:
gdb_assert_not_reached ("unrecognized tp_ value in follow_types");
}
type_instance_flags make_addr_space = 0;
bool make_restrict = false;
bool make_atomic = false;
+ bool make_capability = false;
int array_size;
while (!done)
case tp_restrict:
make_restrict = true;
break;
+ case tp_capability:
+ make_capability = true;
+ break;
case tp_pointer:
follow_type = lookup_pointer_type (follow_type);
goto process_qualifiers;
follow_type = make_restrict_type (follow_type);
if (make_atomic)
follow_type = make_atomic_type (follow_type);
+ if (make_capability)
+ follow_type = make_capability_type (follow_type);
make_const = make_volatile = 0;
make_addr_space = 0;
- make_restrict = make_atomic = false;
+ make_restrict = make_atomic = make_capability = false;
break;
case tp_array:
array_size = pop_int ();
tp_atomic,
tp_restrict,
tp_type_stack,
- tp_kind
+ tp_kind,
+ tp_capability
};
/* The stack can contain either an enum type_pieces or an int. */