Fix reconnecting to a gdbserver already debugging multiple processes, I
[deliverable/binutils-gdb.git] / bfd / elfxx-riscv.c
index 535ba7ba9852ec22f575879e9bc08a197f737e8d..658629c0c811bda9544071ba5d869345ba1cb779 100644 (file)
@@ -1,5 +1,5 @@
 /* RISC-V-specific support for ELF.
-   Copyright (C) 2011-2019 Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
 
    Contributed by Andrew Waterman (andrew@sifive.com).
    Based on TILE-Gx and MIPS targets.
@@ -1484,3 +1484,92 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
 
   subset_list->tail = NULL;
 }
+
+/* Return the number of digits for the input.  */
+
+static size_t
+riscv_estimate_digit (unsigned num)
+{
+  size_t digit = 0;
+  if (num == 0)
+    return 1;
+
+  for (digit = 0; num ; num /= 10)
+    digit++;
+
+  return digit;
+}
+
+/* Auxiliary function to estimate string length of subset list.  */
+
+static size_t
+riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
+{
+  if (subset == NULL)
+    return 6; /* For rv32/rv64/rv128 and string terminator.  */
+
+  return riscv_estimate_arch_strlen1 (subset->next)
+        + strlen (subset->name)
+        + riscv_estimate_digit (subset->major_version)
+        + 1 /* For version seperator: 'p'.  */
+        + riscv_estimate_digit (subset->minor_version)
+        + 1 /* For underscore.  */;
+}
+
+/* Estimate the string length of this subset list.  */
+
+static size_t
+riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
+{
+  return riscv_estimate_arch_strlen1 (subset_list->head);
+}
+
+/* Auxiliary function to convert subset info to string.  */
+
+static void
+riscv_arch_str1 (riscv_subset_t *subset,
+                char *attr_str, char *buf, size_t bufsz)
+{
+  const char *underline = "_";
+
+  if (subset == NULL)
+    return;
+
+  /* No underline between rvXX and i/e.   */
+  if ((strcasecmp (subset->name, "i") == 0)
+      || (strcasecmp (subset->name, "e") == 0))
+    underline = "";
+
+  snprintf (buf, bufsz, "%s%s%dp%d",
+           underline,
+           subset->name,
+           subset->major_version,
+           subset->minor_version);
+
+  strncat (attr_str, buf, bufsz);
+
+  /* Skip 'i' extension after 'e'.  */
+  if ((strcasecmp (subset->name, "e") == 0)
+      && subset->next
+      && (strcasecmp (subset->next->name, "i") == 0))
+    riscv_arch_str1 (subset->next->next, attr_str, buf, bufsz);
+  else
+    riscv_arch_str1 (subset->next, attr_str, buf, bufsz);
+}
+
+/* Convert subset info to string with explicit version info.  */
+
+char *
+riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
+{
+  size_t arch_str_len = riscv_estimate_arch_strlen (subset);
+  char *attr_str = xmalloc (arch_str_len);
+  char *buf = xmalloc (arch_str_len);
+
+  snprintf (attr_str, arch_str_len, "rv%u", xlen);
+
+  riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
+  free (buf);
+
+  return attr_str;
+}
This page took 0.024146 seconds and 4 git commands to generate.