/* 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},
add (builtin->builtin_decfloat);
add (builtin->builtin_decdouble);
add (builtin->builtin_declong);
+ add (builtin->builtin_intcap_t);
+ add (builtin->builtin_uintcap_t);
lai->set_string_char_type (builtin->builtin_char);
lai->set_bool_type (builtin->builtin_int);
add (builtin->builtin_char16);
add (builtin->builtin_char32);
add (builtin->builtin_wchar);
+ add (builtin->builtin_intcap_t);
+ add (builtin->builtin_uintcap_t);
lai->set_string_char_type (builtin->builtin_char);
lai->set_bool_type (builtin->builtin_bool, "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 (type->arch (),
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");
printf_filtered ("%*sflags", spaces, "");
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 *);
--- /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. */