]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
CHERI-style compact printing format
authorLuis Machado <luis.machado@linaro.org>
Tue, 15 Dec 2020 18:41:29 +0000 (15:41 -0300)
committerLuis Machado <luis.machado@linaro.org>
Wed, 16 Dec 2020 16:14:46 +0000 (13:14 -0300)
This patch adds CHERI-style compact printing format to GDB and uses it
by default.

The format is described here: https://github.com/CTSRD-CHERI/cheri-c-programming/wiki/Displaying-Capabilities

gdbsupport/ChangeLog:

2020-12-16  Luis Machado  <luis.machado@arm.com>

* capability.cc (cap_short_perms_strings): Remove.
(capability::is_null_derived): New member function.
(capability::to_str): Document and handle new CHERY-style printing
format.
* capability.h (cap_constants): Document the CAP_SEAL_TYPE_*
constants.
(struct capability) <is_null_derived>: New member function prototype.

gdbsupport/ChangeLog
gdbsupport/capability.cc
gdbsupport/capability.h

index ddf010997381794d55cd4d0782549a2e6dd95746..4fe402fe1098871c5f2cd81d9667f7394120978d 100644 (file)
@@ -1,3 +1,13 @@
+2020-12-16  Luis Machado  <luis.machado@arm.com>
+
+       * capability.cc (cap_short_perms_strings): Remove.
+       (capability::is_null_derived): New member function.
+       (capability::to_str): Document and handle new CHERY-style printing
+       format.
+       * capability.h (cap_constants): Document the CAP_SEAL_TYPE_*
+       constants.
+       (struct capability) <is_null_derived>: New member function prototype.
+
 2020-11-11  Luis Machado  <luis.machado@arm.com>
 
        * capability.cc (cap_short_perms_strings): New static global.
index 6551bab6784a5937c50d99416fe8aed763a87589..5ced9b67620d8eeeace19e9a681c4e03d920f7d8 100644 (file)
@@ -76,31 +76,6 @@ static const char *cap_perms_strings[] =
   "Load"
 };
 
-/* Short version of permission string names, indexed by bit number from
-   permissions
-   Valid bits are 0 through 17.  */
-static const char *cap_short_perms_strings[] =
-{
-  "G",
-  "E",
-  "U0",
-  "U1",
-  "U2",
-  "U3",
-  "MLd",
-  "CID",
-  "BrUn",
-  "Sys",
-  "Un",
-  "Sl",
-  "StLoC",
-  "StC",
-  "LdC",
-  "X",
-  "St",
-  "Ld"
-};
-
 /* Returns a capability, derived from the input capability, with base address
    set to the value of the input capability and the length set to a given
    value.  If precise bounds setting is not possible, either the bounds are
@@ -548,6 +523,14 @@ capability::set_offset (uint64_t offset)
   set_value (get_base () + offset);
 }
 
+/* Returns true if the capability has the top 64 bits equal to zero.
+   Returns false otherwise.  */
+
+bool capability::is_null_derived (void)
+{
+  return _bits (m_cap, 127, 64) == 0;
+}
+
 /* Returns a string representation of the capability.
 
    If COMPACT is true, use a less verbose form.  Otherwise print
@@ -556,20 +539,79 @@ capability::set_offset (uint64_t offset)
 std::string
 capability::to_str (bool compact)
 {
-  /* The printing format is the following:
-     {tag = %d, address = 0x%016x, permissions = {[%s], otype = 0x%04x,
-      [range = [0x%016x - 0x%016x)}}
+  /* There are 3 printing formats.
+
+     - (1) - If the top 64 bits are 0 and the tag is false, then we should print
+       the capability's value as a pointer. Example: 0xdeadbeef.
+
+     - (2) - If the top 64 bits are non-zero and the representation is
+       COMPACT, the capability has the following format:
+
+     - (3) - If the top 64 bits are non-zero and the representation is not
+       COMPACT, the capability has the following format:
+
+      {tag = %d, address = 0x%016x, permissions = {[%s], otype = 0x%04x,
+       [range = [0x%016x - 0x%016x)}}
   */
-  std::string cap_str ("");
-  std::string tag_str (get_tag ()? "1" : "0");
+
   std::string val_str ("");
-  std::string perm_str ("");
-  std::string otype_str ("");
-  std::string range_str ("");
 
   /* Capability value.  */
   val_str += core_addr_to_string_nz (get_value ());
 
+  /* Format 1.  */
+  if (is_null_derived ())
+    return val_str;
+
+  std::string cap_str ("");
+  std::string perm_str ("");
+  std::string range_str ("");
+
+  /* Format 2.  */
+  if (compact)
+    {
+      /* Handle compact permissions output.  */
+      if (check_permissions (1 << cap_perms_load))
+       perm_str += "r";
+      if (check_permissions (1 << cap_perms_store))
+       perm_str += "w";
+      if (check_permissions (1 << cap_perms_execute))
+       perm_str += "x";
+      if (check_permissions (1 << cap_perms_load_cap))
+       perm_str += "R";
+      if (check_permissions (1 << cap_perms_store_cap))
+       perm_str += "W";
+      if (check_permissions (1 << cap_perms_executive))
+       perm_str += "E";
+
+      /* Handle capability range.  */
+      range_str += core_addr_to_string_nz (get_base ());
+      range_str += "-";
+      range_str += core_addr_to_string_nz (get_limit ());
+
+      std::string attr_str ("");
+
+      /* Handle attributes.  */
+      if (get_tag () == false)
+       attr_str = "invalid ";
+      if (get_otype () == CAP_SEAL_TYPE_RB)
+       attr_str = "sentry ";
+      if (is_sealed ())
+       attr_str = "sealed ";
+
+      cap_str += "{";
+      cap_str = val_str + " [" + perm_str + "," + range_str + "]";
+
+      if (!attr_str.empty ())
+       cap_str += " ( " + attr_str + ")";
+
+      cap_str += "}";
+
+      return cap_str;
+    }
+
+  /* Format 3.  */
+
   /* Permissions.  */
   perm_str += "[";
 
@@ -577,15 +619,13 @@ capability::to_str (bool compact)
     if (check_permissions (1 << i))
       {
        perm_str += " ";
-
-       if (compact)
-         perm_str += cap_short_perms_strings[i];
-       else
-         perm_str += cap_perms_strings[i];
+       perm_str += cap_perms_strings[i];
       }
 
   perm_str += " ]";
 
+  std::string otype_str ("");
+
   /* Object type, if sealed.  */
   otype_str += core_addr_to_string_nz (get_otype ());
 
@@ -596,6 +636,8 @@ capability::to_str (bool compact)
   range_str += core_addr_to_string_nz (get_limit ());
   range_str += ")";
 
+  std::string tag_str (get_tag ()? "1" : "0");
+
   /* Assemble the capability string.  */
   cap_str += "{tag = " + tag_str + ", address = " + val_str + ", "
             + "permissions = {" + perm_str + " ";
index fd94768e432fc252ea78bc53069fd3cab297ed9b..d77d8094a1a7da42b74749c7cf3d1c5b8cbd199e 100644 (file)
@@ -250,8 +250,11 @@ enum cap_constants {
   CAP_PERM_LOAD = (1<<17),
   CAP_PERM_LOAD_BIT = CAP_PERMS_LO_BIT+17,
 
+  /* Equivalent to CHERI's OTYPE_RESERVED3.  */
   CAP_SEAL_TYPE_LB = 3,
+  /* Equivalent to CHERI's OTYPE_RESERVED2.  */
   CAP_SEAL_TYPE_LPB = 2,
+  /* Equivalent to CHERI's OTYPE_SENTRY.  */
   CAP_SEAL_TYPE_RB = 1,
 
   CAP_TAG_BIT = 128,
@@ -542,6 +545,11 @@ public:
      otherwise.  */
   bool is_equal (void) const;
 
+  /* Returns true if the capability has the top 64 bits equal to zero.
+     Returns false otherwise.  */
+
+  bool is_null_derived (void);
+
   /* Printing functions.  */
 
   /* Returns a string representation of the capability.