libctf, ld: handle nonrepresentable types better
authorNick Alcock <nick.alcock@oracle.com>
Mon, 25 Oct 2021 10:17:02 +0000 (11:17 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Mon, 25 Oct 2021 10:17:05 +0000 (11:17 +0100)
ctf_type_visit (used, among other things, by the type dumping code) was
aborting when it saw a nonrepresentable type anywhere: even a single
structure member with a nonrepresentable type caused an abort with
ECTF_NONREPRESENTABLE.  This is not useful behaviour, given that the
abort comes from a type-resolution we are only doing in order to
determine whether the type is a structure or union.  We know
nonrepresentable types can't be either, so handle that case and
pass the nonrepresentable type down.

(The added test verifies that the dumper now handles this case and
prints nonrepresentable structure members as it already does
nonrepresentable top-level types, rather than skipping the whole
structure -- or, without the previous commit, skipping the whole types
section.)

ld/ChangeLog
2021-10-25  Nick Alcock  <nick.alcock@oracle.com>

* testsuite/ld-ctf/nonrepresentable-member.*: New test.

libctf/ChangeLog
2021-10-25  Nick Alcock  <nick.alcock@oracle.com>

* ctf-types.c (ctf_type_rvisit): Handle nonrepresentable types.

ld/ChangeLog
ld/testsuite/ld-ctf/nonrepresentable-member.c [new file with mode: 0644]
ld/testsuite/ld-ctf/nonrepresentable-member.d [new file with mode: 0644]
libctf/ChangeLog
libctf/ctf-types.c

index 470e446ad5f07aa8ffea184e70707affd104c067..c613b39804608b942b168d297c9dd0ecde11943c 100644 (file)
@@ -1,3 +1,7 @@
+2021-10-25  Nick Alcock  <nick.alcock@oracle.com>
+
+       * testsuite/ld-ctf/nonrepresentable-member.*: New test.
+
 2021-10-25  Nick Alcock  <nick.alcock@oracle.com>
 
        * testsuite/ld-ctf/array.d: Change --ctf=.ctf to --ctf.
diff --git a/ld/testsuite/ld-ctf/nonrepresentable-member.c b/ld/testsuite/ld-ctf/nonrepresentable-member.c
new file mode 100644 (file)
index 0000000..b3657af
--- /dev/null
@@ -0,0 +1,7 @@
+struct blah
+{
+  int boring;
+  int __attribute__((vector_size(8))) foo;
+  const int __attribute__((vector_size(8))) bar;
+  int this_is_printed;
+} wibble __attribute__((__used__));
diff --git a/ld/testsuite/ld-ctf/nonrepresentable-member.d b/ld/testsuite/ld-ctf/nonrepresentable-member.d
new file mode 100644 (file)
index 0000000..6c76253
--- /dev/null
@@ -0,0 +1,25 @@
+#as:
+#source: nonrepresentable-member.c
+#objdump: --ctf
+#ld: -shared
+#name: Nonrepresentable members
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: 0xdff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+  Types:
+#...
+    0x[0-9a-f]*: \(kind 6\) struct blah .*
+        *\[0x0\] boring: ID 0x[0-9a-f]*: \(kind 1\) int .*
+        *\[0x[0-9a-f]*\] foo: .* \(.*represent.*\)
+        *\[0x[0-9a-f]*\] bar: .* \(.*represent.*\)
+        *\[0x[0-9a-f]*\] this_is_printed: ID 0x[0-9a-f]*: \(kind 1\) int .*
+#...
+
+  Strings:
+#...
index 879e128126af14f4a0c9967044e55c4b6c195c93..245987fdf4209f36af73458430727b3e2f6f9e2e 100644 (file)
@@ -1,3 +1,7 @@
+2021-10-25  Nick Alcock  <nick.alcock@oracle.com>
+
+       * ctf-types.c (ctf_type_rvisit): Handle nonrepresentable types.
+
 2021-10-25  Nick Alcock  <nick.alcock@oracle.com>
 
        * ctf-dump.c (ctf_dump_type): Do not abort on error.
index 243de9348d3ec01c68faa50f8b797b84611c7663..55834856da943f3962cf63f1dba78db540283367 100644 (file)
@@ -1641,20 +1641,27 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
   unsigned char *vlen;
   ssize_t size, increment, vbytes;
   uint32_t kind, n, i = 0;
+  int nonrepresentable = 0;
   int rc;
 
-  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
-    return -1;                 /* errno is set for us.  */
+  if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) {
+    if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
+      return -1;               /* errno is set for us.  */
+    else
+      nonrepresentable = 1;
+  }
 
-  if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
-    return -1;                 /* errno is set for us.  */
+  if (!nonrepresentable)
+    if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
+      return -1;               /* errno is set for us.  */
 
   if ((rc = func (name, otype, offset, depth, arg)) != 0)
     return rc;
 
-  kind = LCTF_INFO_KIND (fp, tp->ctt_info);
+  if (!nonrepresentable)
+    kind = LCTF_INFO_KIND (fp, tp->ctt_info);
 
-  if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
+  if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION))
     return 0;
 
   ctf_get_ctt_size (fp, tp, &size, &increment);