aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ctf.h3
-rw-r--r--libctf/ctf-decl.c7
-rw-r--r--libctf/ctf-dump.c8
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array-ctf.c3
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array.c71
-rw-r--r--libctf/testsuite/libctf-lookup/multidim-array.lk9
6 files changed, 97 insertions, 4 deletions
diff --git a/include/ctf.h b/include/ctf.h
index 72a639a..819003e 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -213,8 +213,9 @@ typedef struct ctf_header
#define CTF_F_NEWFUNCINFO 0x2 /* New v3 func info section format. */
#define CTF_F_IDXSORTED 0x4 /* Index sections already sorted. */
#define CTF_F_DYNSTR 0x8 /* Strings come from .dynstr. */
+#define CTF_F_ARRNELEMS 0x10 /* Array elems no longer reversed. */
#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO | CTF_F_IDXSORTED \
- | CTF_F_DYNSTR)
+ | CTF_F_DYNSTR | CTF_F_ARRNELEMS)
typedef struct ctf_lblent
{
diff --git a/libctf/ctf-decl.c b/libctf/ctf-decl.c
index 9e11913..e5331b4 100644
--- a/libctf/ctf-decl.c
+++ b/libctf/ctf-decl.c
@@ -154,9 +154,12 @@ ctf_decl_push (ctf_decl_t *cd, ctf_dict_t *fp, ctf_id_t type)
cd->cd_qualp = prec;
/* By convention qualifiers of base types precede the type specifier (e.g.
- const int vs. int const) even though the two forms are equivalent. */
+ const int vs. int const) even though the two forms are equivalent.
+ As of gcc-14.2.0, arrays must also be prepended in order to dump with the
+ dimensions properly ordered. */
- if (is_qual && prec == CTF_PREC_BASE)
+ if ((is_qual && prec == CTF_PREC_BASE) || ((kind == CTF_K_ARRAY) &&
+ (fp->ctf_openflags & (CTF_F_ARRNELEMS))))
ctf_list_prepend (&cd->cd_nodes[prec], cdp);
else
ctf_list_append (&cd->cd_nodes[prec], cdp);
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index 54febd6..57fbd64 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -326,7 +326,7 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
if (fp->ctf_openflags > 0)
{
- if (asprintf (&flagstr, "%s%s%s%s%s%s%s",
+ if (asprintf (&flagstr, "%s%s%s%s%s%s%s%s%s",
fp->ctf_openflags & CTF_F_COMPRESS
? "CTF_F_COMPRESS": "",
(fp->ctf_openflags & CTF_F_COMPRESS)
@@ -343,6 +343,12 @@ ctf_dump_header (ctf_dict_t *fp, ctf_dump_state_t *state)
&& (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
| CTF_F_IDXSORTED))
? ", " : "",
+ fp->ctf_openflags & CTF_F_ARRNELEMS
+ ? "CTF_F_ARRNELEMS" : "",
+ fp->ctf_openflags & (CTF_F_ARRNELEMS)
+ && (fp->ctf_openflags & ~(CTF_F_COMPRESS | CTF_F_NEWFUNCINFO
+ | CTF_F_IDXSORTED | CTF_F_ARRNELEMS))
+ ? ", " : "",
fp->ctf_openflags & CTF_F_DYNSTR
? "CTF_F_DYNSTR" : "") < 0)
goto err;
diff --git a/libctf/testsuite/libctf-lookup/multidim-array-ctf.c b/libctf/testsuite/libctf-lookup/multidim-array-ctf.c
new file mode 100644
index 0000000..05b6ebe
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array-ctf.c
@@ -0,0 +1,3 @@
+int a[3][5][9];
+int b[1][2];
+
diff --git a/libctf/testsuite/libctf-lookup/multidim-array.c b/libctf/testsuite/libctf-lookup/multidim-array.c
new file mode 100644
index 0000000..2a86f26
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array.c
@@ -0,0 +1,71 @@
+#include <ctf-api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ ctf_archive_t *ctf;
+ ctf_dict_t *fp;
+ int err;
+ ctf_dump_state_t *dump_state = NULL;
+ char *dumpstr;
+ ctf_next_t *it = NULL;
+ ctf_id_t type;
+ int flagged = 0;
+
+ if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
+ goto open_err;
+ if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL)
+ goto open_err;
+
+ /* First, check for signs that the compiler is fixed but not emitting the
+ relevant flag yet. This combination is not expected to work right. */
+
+ while ((dumpstr = ctf_dump (fp, &dump_state, CTF_SECT_HEADER,
+ NULL, NULL)) != NULL)
+ {
+ if (strstr (dumpstr, "CTF_F_ARRNELEMS") != NULL)
+ flagged = 1;
+ free (dumpstr);
+ }
+
+ if (!flagged)
+ {
+ ctf_arinfo_t ar;
+
+ if ((type = ctf_lookup_by_symbol_name (fp, "a")) == CTF_ERR)
+ goto unexpected;
+
+ if (ctf_array_info (fp, type, &ar) < 0)
+ goto unexpected;
+
+ if (ar.ctr_nelems == 3)
+ {
+ fprintf (stderr, "UNSUPPORTED: compiler has GCC PR114186 fixed but "
+ "no indicative flag\n");
+ return 0;
+ }
+ }
+
+ /* Now check for the actual bug. */
+
+ while ((type = ctf_type_next (fp, &it, NULL, 1)) != -1)
+ printf ("%s\n", ctf_type_aname (fp, type));
+
+ ctf_dict_close (fp);
+ ctf_close (ctf);
+
+ return 0;
+
+ open_err:
+ fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err));
+ return 1;
+
+ unexpected:
+ fprintf (stderr, "Cannot look up symbol to determine compiler bugginess: %s\n",
+ ctf_errmsg (ctf_errno (fp)));
+ return 1;
+}
+
diff --git a/libctf/testsuite/libctf-lookup/multidim-array.lk b/libctf/testsuite/libctf-lookup/multidim-array.lk
new file mode 100644
index 0000000..20056f1
--- /dev/null
+++ b/libctf/testsuite/libctf-lookup/multidim-array.lk
@@ -0,0 +1,9 @@
+# source: multidim-array-ctf.c
+int
+long unsigned int
+int \[9\]
+int \[5\]\[9\]
+int \[3\]\[5\]\[9\]
+int \[2\]
+int \[1\]\[2\]
+