From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id CDBA23857C45 for ; Tue, 20 Jun 2023 07:47:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CDBA23857C45 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-3f9b23dc270so18126095e9.0 for ; Tue, 20 Jun 2023 00:47:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1687247222; x=1689839222; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=Hs/mnx8V6hPmF7WEkKR6TKbDHvD297HvoaKE5TYRI1w=; b=K202d/dYaEW7LZGBbEv2Mz+opjDC7Q9nkG2syR2tLJ8ISiIZfGlcNR2XUz0z8wYyjm GqoSjvZjLJ1m87VS8CTq41DbhhA8a64A9llE+v3PulglkDW0Pbcbxnk7f8oQupWNQLdI s7F1r7MY8DOFd2n+hV2PU1ltnShwHT8V21Id0E0ZHoY/wVGtm645j7rdCATsJrXdE+oQ TKWhl/j+ehlh4ALjmLyNt2qM1/oxXlKnIvrVHcJ3erXm1L/nweuXIwKzU6VW4Q17iCFU p1Kv1DGkoS2No/cuFI6wLetcm+3grHatrUAKQxwwtM20ugQZdi/5VgWAsRGOY7XawqeG 4aHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687247222; x=1689839222; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Hs/mnx8V6hPmF7WEkKR6TKbDHvD297HvoaKE5TYRI1w=; b=D+wumLncSzYtpjdBPPjqorYSRCJZmTTRgfDm0o6d0d6kKQ4xFiYoGvd8PWfDqXrXKW rWgd27K9h2Lge2EPjshFmvNnZRvTENoKsVvEm5K0MXEjf4y7zjIL/IVzY6cqeaKXpg9o AQBfxjOkAmnM+jw+L3nDyUk3sjjmvRZdGzzLIBcqNJf3o50xfeDcKYkH1NVgWf6Wh36w rKx5utTRt16EFG4IB2M4R15YR0i9RPR+enQu4p63QhmWGpk5Qik/itsX4u/VS3mwrXLL WZep/wBR935LUXHrJG5DwAtfZ2Buh25ZUjL3veBtspYD5zoBxAulvkfH+dup14uNaWal JW9g== X-Gm-Message-State: AC+VfDy5vllSm5O2HqoIVZNd3AjCipFQ3rbkrheeBuRpmSrLAFHYxANJ j3Ka8gXktoe7xZz3+1PwFFRP+PBDtdUTPWTX4y/HXg== X-Google-Smtp-Source: ACHHUZ72m8ZsIpkVu/ku8tTyEzW+Vyq+EL4wvTk/fb+S5tAlH9rt4AO1UJmzeLcP5GcUhZTnBr7iow== X-Received: by 2002:a05:600c:2199:b0:3f9:b8df:26b0 with SMTP id e25-20020a05600c219900b003f9b8df26b0mr444274wme.5.1687247222460; Tue, 20 Jun 2023 00:47:02 -0700 (PDT) Received: from poulhies-Precision-5550.lan ([2001:861:3382:1a90:4c16:36ea:1b76:c001]) by smtp.gmail.com with ESMTPSA id f20-20020a7bcc14000000b003f8044b3436sm12622307wmh.23.2023.06.20.00.47.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Jun 2023 00:47:01 -0700 (PDT) From: =?UTF-8?q?Marc=20Poulhi=C3=A8s?= To: gcc-patches@gcc.gnu.org Cc: Daniel King Subject: [COMMITTED] ada: Add CHERI intrinsic bindings and helper functions. Date: Tue, 20 Jun 2023 09:47:00 +0200 Message-Id: <20230620074700.1252872-1-poulhies@adacore.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Daniel King The package Interfaces.CHERI provides intrinsic bindings and helper functions to allow software to query, create, and manipulate CHERI capabilities. gcc/ada/ * libgnat/i-cheri.ads: Add CHERI intrinsics and helper functions. * libgnat/i-cheri.adb: Likewise Tested on x86_64-pc-linux-gnu, committed on master. --- gcc/ada/libgnat/i-cheri.adb | 75 ++++++ gcc/ada/libgnat/i-cheri.ads | 470 ++++++++++++++++++++++++++++++++++++ 2 files changed, 545 insertions(+) create mode 100644 gcc/ada/libgnat/i-cheri.adb create mode 100644 gcc/ada/libgnat/i-cheri.ads diff --git a/gcc/ada/libgnat/i-cheri.adb b/gcc/ada/libgnat/i-cheri.adb new file mode 100644 index 00000000000..174fdcc5b47 --- /dev/null +++ b/gcc/ada/libgnat/i-cheri.adb @@ -0,0 +1,75 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- I N T E R F A C E S . C H E R I -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023, AdaCore -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +package body Interfaces.CHERI is + + ---------------------------- + -- Set_Address_And_Bounds -- + ---------------------------- + + procedure Set_Address_And_Bounds + (Cap : in out Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + is + begin + Cap := Capability_With_Address_And_Bounds (Cap, Address, Length); + end Set_Address_And_Bounds; + + ---------------------------------- + -- Set_Address_And_Exact_Bounds -- + ---------------------------------- + + procedure Set_Address_And_Exact_Bounds + (Cap : in out Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + is + begin + Cap := Capability_With_Address_And_Exact_Bounds (Cap, Address, Length); + end Set_Address_And_Exact_Bounds; + + ---------------------- + -- Align_Address_Up -- + ---------------------- + + function Align_Address_Up + (Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + return System.Storage_Elements.Integer_Address + is + Mask : constant System.Storage_Elements.Integer_Address := + Representable_Alignment_Mask (Length); + begin + return (Address + (not Mask)) and Mask; + end Align_Address_Up; + +end Interfaces.CHERI; diff --git a/gcc/ada/libgnat/i-cheri.ads b/gcc/ada/libgnat/i-cheri.ads new file mode 100644 index 00000000000..547b033dbaf --- /dev/null +++ b/gcc/ada/libgnat/i-cheri.ads @@ -0,0 +1,470 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- I N T E R F A C E S . C H E R I -- +-- -- +-- S p e c -- +-- -- +-- Copyright (C) 2023, AdaCore -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 3, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- . -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This package provides bindings to CHERI intrinsics and some common +-- operations on capabilities. + +with System; +with System.Storage_Elements; + +package Interfaces.CHERI with + Preelaborate, + No_Elaboration_Code_All +is + + use type System.Storage_Elements.Integer_Address; + + subtype Capability is System.Address; + + type Bounds_Length is range 0 .. System.Memory_Size - 1 with + Size => System.Word_Size; + + ---------------------------- + -- Capability Permissions -- + ---------------------------- + + type Permissions_Mask is mod System.Memory_Size with + Size => System.Word_Size; + + Global : constant Permissions_Mask := 16#0001#; + Executive : constant Permissions_Mask := 16#0002#; + Mutable_Load : constant Permissions_Mask := 16#0040#; + Compartment_Id : constant Permissions_Mask := 16#0080#; + Branch_Sealed_Pair : constant Permissions_Mask := 16#0100#; + Access_System_Registers : constant Permissions_Mask := 16#0200#; + Permit_Unseal : constant Permissions_Mask := 16#0400#; + Permit_Seal : constant Permissions_Mask := 16#0800#; + Permit_Store_Local : constant Permissions_Mask := 16#1000#; + Permit_Store_Capability : constant Permissions_Mask := 16#2000#; + Permit_Load_Capability : constant Permissions_Mask := 16#4000#; + Permit_Execute : constant Permissions_Mask := 16#8000#; + Permit_Store : constant Permissions_Mask := 16#1_0000#; + Permit_Load : constant Permissions_Mask := 16#2_0000#; + + function "and" + (Cap : Capability; + Mask : Permissions_Mask) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_perms_and"; + -- Perform a bitwise-AND of a capability permissions and the specified + -- mask, returning the new capability. + + function Get_Permissions (Cap : Capability) return Permissions_Mask with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_perms_get"; + -- Get the permissions of a capability + + function Clear_Permissions + (Cap : Capability; + Mask : Permissions_Mask) + return Capability is + (Cap and not Mask); + -- Clear the specified permissions of a capability, returning the new + -- capability. + + function Has_All_Permissions + (Cap : Capability; + Permissions : Permissions_Mask) + return Boolean is + ((Get_Permissions (Cap) and Permissions) = Permissions); + -- Query whether all of the specified permission bits are set in a + -- capability's permissions flags. + + ----------------------- + -- Common Intrinsics -- + ----------------------- + + function Capability_With_Address + (Cap : Capability; + Addr : System.Storage_Elements.Integer_Address) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_address_set"; + -- Return a new capability with the same bounds and permissions as Cap, + -- with the address set to Addr. + + function Get_Address + (Cap : Capability) + return System.Storage_Elements.Integer_Address + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_address_get"; + -- Get the address of a capability + + procedure Set_Address + (Cap : in out Capability; + Addr : System.Storage_Elements.Integer_Address) + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_address_set"; + -- Set the address of a capability + + function Get_Base + (Cap : Capability) + return System.Storage_Elements.Integer_Address + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_base_get"; + -- Get the lower bound of a capability + + function Get_Offset (Cap : Capability) return Bounds_Length with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_offset_get"; + -- Get the difference between the address and the lower bound of a + -- capability. + + procedure Set_Offset + (Cap : in out Capability; + Offset : Bounds_Length) + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_offset_set"; + -- Set the address relative to the lower bound of a capability + + function Capability_With_Offset + (Cap : Capability; + Value : Bounds_Length) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_offset_set"; + -- Set the address relative to the lower bound of a capability, returning + -- the new capability. + + function Increment_Offset + (Cap : Capability; + Value : Bounds_Length) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_offset_increment"; + -- Increment the address of a capability by the specified amount, + -- returning the new capability. + + function Get_Length (Cap : Capability) return Bounds_Length with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_length_get"; + -- Get the length of a capability's bounds + + function Clear_Tag (Cap : Capability) return Capability with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_tag_clear"; + -- Clear the capability validity tag, returning the new capability + + function Get_Tag (Cap : Capability) return Boolean with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_tag_get"; + -- Get the validty tag of a capability + + function Is_Valid (Cap : Capability) return Boolean is (Get_Tag (Cap)); + -- Check whether a capability is valid + + function Is_Invalid (Cap : Capability) return Boolean is + (not Is_Valid (Cap)); + -- Check whether a capability is invalid + + function Is_Equal_Exact (A, B : Capability) return Boolean with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_equal_exact"; + -- Check for bit equality between two capabilities + + function Is_Subset (A, B : Capability) return Boolean with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_subset_test"; + -- Returns True if capability A is a subset or equal to capability B + + -------------------- + -- Bounds Setting -- + -------------------- + + function Capability_With_Bounds + (Cap : Capability; + Length : Bounds_Length) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_bounds_set"; + -- Narrow the bounds of a capability so that the lower bound is the + -- current address and the upper bound is suitable for the Length, + -- returning the new capability. + -- + -- Note that the effective bounds of the returned capability may be wider + -- than the range Get_Address (Cap) .. Get_Address (Cap) + Length - 1 due + -- to capability compression, but they will always be a subset of the + -- original bounds. + + function Capability_With_Exact_Bounds + (Cap : Capability; + Length : Bounds_Length) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_bounds_set_exact"; + -- Narrow the bounds of a capability so that the lower bound is the + -- current address and the upper bound is suitable for the Length, + -- returning the new capability. + -- + -- This is similar to Capability_With_Bounds but will clear the capability + -- tag in the returned capability if the bounds cannot be set exactly, due + -- to capability compression. + + function Capability_With_Address_And_Bounds + (Cap : Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + return Capability is + (Capability_With_Bounds + (Capability_With_Address (Cap, Address), Length)); + -- Set the address and narrow the bounds of the capability so that the + -- lower bound is Address and the upper bound is Address + Length, + -- returning the new capability. + -- + -- Note that the effective bounds of the returned capability may be wider + -- than the range Address .. Address + Length - 1 due to capability + -- compression, but they will always be a subset of the original bounds. + + function Capability_With_Address_And_Exact_Bounds + (Cap : Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + return Capability is + (Capability_With_Exact_Bounds + (Capability_With_Address (Cap, Address), Length)); + -- Set the address and narrow the bounds of the capability so that the + -- lower bound is Address and the upper bound is Address + Length, + -- returning the new capability. + -- + -- This is similar to Capability_With_Address_And_Bounds but will clear the + -- capability tag in the returned capability if the bounds cannot be set + -- exactly, due to capability compression. + + procedure Set_Bounds + (Cap : in out Capability; + Length : Bounds_Length) + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_bounds_set"; + -- Narrow the bounds of a capability so that the lower bound is the + -- current address and the upper bound is suitable for the Length. + -- + -- Note that the effective bounds of the output capability may be wider + -- than the range Get_Address (Cap) .. Get_Address (Cap) + Length - 1 due + -- to capability compression, but they will always be a subset of the + -- original bounds. + + procedure Set_Exact_Bounds + (Cap : in out Capability; + Length : Bounds_Length) + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_bounds_set_exact"; + -- Narrow the bounds of a capability so that the lower bound is the + -- current address and the upper bound is suitable for the Length. + -- + -- This is similar to Set_Bounds but will clear the capability tag if the + -- bounds cannot be set exactly, due to capability compression. + + procedure Set_Address_And_Bounds + (Cap : in out Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + with + Inline_Always; + -- Set the address and narrow the bounds of the capability so that the + -- lower bound is Address and the upper bound is Address + Length. + -- + -- Note that the effective bounds of the output capability may be wider + -- than the range Address .. Address + Length - 1 due to capability + -- compression, but they will always be a subset of the original bounds. + + procedure Set_Address_And_Exact_Bounds + (Cap : in out Capability; + Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + with + Inline_Always; + -- Set the address and narrow the bounds of the capability so that the + -- lower bound is Address and the upper bound is Address + Length. + -- + -- This is similar to Set_Address_And_Bounds but will clear the capability + -- tag if the bounds cannot be set exactly, due to capability compression. + + function Representable_Length (Length : Bounds_Length) return Bounds_Length + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_round_representable_length"; + -- Returns the length that a capability would have after using Set_Bounds + -- to set the Length (assuming appropriate alignment of the base). + + function Representable_Alignment_Mask + (Length : Bounds_Length) + return System.Storage_Elements.Integer_Address + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_representable_alignment_mask"; + -- Returns a bitmask that can be used to align an address downwards such + -- that it is sufficiently aligned to create a precisely bounded + -- capability. + + function Align_Address_Down + (Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + return System.Storage_Elements.Integer_Address is + (Address and Representable_Alignment_Mask (Length)); + -- Align an address such that it is sufficiently aligned to create a + -- precisely bounded capability, rounding down if necessary. + -- + -- Due to capability compression, the upper and lower bounds of a + -- capability must be aligned based on the length of the bounds to ensure + -- that the capability is representable. This function aligns an address + -- down to the next boundary if it is not already aligned. + + function Capability_With_Address_Aligned_Down + (Cap : Capability; + Length : Bounds_Length) + return Capability is + (Capability_With_Address + (Cap, Align_Address_Down (Get_Address (Cap), Length))); + -- Align a capability's address such that it is sufficiently aligned to + -- create a precisely bounded capability, rounding down if necessary. + -- + -- Due to capability compression, the upper and lower bounds of a + -- capability must be aligned based on the length of the bounds to ensure + -- that the capability is representable. This function aligns an address + -- down to the next boundary if it is not already aligned. + + function Align_Address_Up + (Address : System.Storage_Elements.Integer_Address; + Length : Bounds_Length) + return System.Storage_Elements.Integer_Address + with + Inline; + -- Align an address such that it is sufficiently aligned to create a + -- precisely bounded capability, rounding upwards if necessary. + -- + -- Due to capability compression, the upper and lower bounds of a + -- capability must be aligned based on the length of the bounds to ensure + -- that the capability is representable. This function aligns an address up + -- to the next boundary if it is not already aligned. + + function Capability_With_Address_Aligned_Up + (Cap : Capability; + Length : Bounds_Length) + return Capability is + (Capability_With_Address + (Cap, Align_Address_Up (Get_Address (Cap), Length))); + -- Align a capability's address such that it is sufficiently aligned to + -- create a precisely bounded capability, rounding upwards if necessary. + -- + -- Due to capability compression, the upper and lower bounds of a + -- capability must be aligned based on the length of the bounds to ensure + -- that the capability is representable. This function aligns an address up + -- to the next boundary if it is not already aligned. + + ------------------------------------------ + -- Object Types, Sealing, and Unsealing -- + ------------------------------------------ + + type Object_Type is + range -2**(System.Word_Size - 1) .. +2**(System.Word_Size - 1) - 1 with + Size => System.Word_Size; + + Type_Unsealed : constant Object_Type := 0; + Type_Sentry : constant Object_Type := 1; + + function Get_Object_Type (Cap : Capability) return Object_Type with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_type_get"; + -- Get the object type of a capability + + function Is_Sealed (Cap : Capability) return Boolean with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_sealed_get"; + -- Check whether a capability is sealed + + function Is_Unsealed (Cap : Capability) return Boolean is + (not Is_Sealed (Cap)); + -- Check whether a capability is unsealed + + function Is_Sentry (Cap : Capability) return Boolean is + (Get_Object_Type (Cap) = Type_Sentry); + -- Check whether a capability is a sealed entry + + function Create_Sentry (Cap : Capability) return Capability with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_seal_entry"; + -- Create a sealed entry and return the new capability. + + function Seal + (Cap : Capability; + Sealing_Cap : Capability) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_seal"; + -- Seal a capability with a sealing capability, by setting the object type + -- of the capability to the Sealing_Cap's value, returning the sealed + -- capability. + + function Unseal + (Cap : Capability; + Unsealing_Cap : Capability) + return Capability + with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_unseal"; + -- Unseal a capability with an unsealing capability, by checking the object + -- type of the capability against the Sealing_Cap's value, returning the + -- unsealed capability. + + ----------------------------------- + -- Capability Register Accessors -- + ----------------------------------- + + function Get_PCC return System.Address with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_program_counter_get"; + -- Get the Program Counter Capablity (PCC) + + function Get_DDC return System.Address with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_global_data_get"; + -- Get the Default Data Capability (DDC) + + function Get_CSP return System.Address with + Import, Convention => Intrinsic, + External_Name => "__builtin_cheri_stack_get"; + -- Get the Capability Stack Pointer (CSP) + +end Interfaces.CHERI; -- 2.40.0