/* Make sure linking a non-root-visible type emits a non-root-visible type, rather than silently promoting it to root-visible. Do it by dumping, thus also testing the {non-root sigils} you get when dumping non-root-visible types. */ #include <ctf-api.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main (int argc, char *argv[]) { ctf_dict_t *in1; ctf_dict_t *fp; ctf_dict_t *dump_fp; ctf_archive_t *arc1; ctf_archive_t *final_arc; ctf_sect_t s; ctf_encoding_t encoding = { CTF_INT_SIGNED, 0, sizeof (char) }; unsigned char *buf1, *buf2; size_t buf1_sz, buf2_sz; ctf_dump_state_t *dump_state = NULL; ctf_next_t *i = NULL; int err; /* Linking does not currently work on mingw because of an unreliable tmpfile implementation on that platform (see https://github.com/msys2/MINGW-packages/issues/18878). Simply skip for now. */ #ifdef __MINGW32__ printf ("UNSUPPORTED: platform bug breaks ctf_link\n"); return 0; #else if ((fp = ctf_create (&err)) == NULL) goto create_err; if ((in1 = ctf_create (&err)) == NULL) goto create_err; /* A non-root addition. */ if ((ctf_add_integer (in1, CTF_ADD_NONROOT, "foo", &encoding)) == CTF_ERR) { fprintf (stderr, "Cannot add: %s\n", ctf_errmsg (ctf_errno (in1))); return 1; } /* Write it out and read it back in, to turn it into an archive. This would be unnecessary if ctf_link_add() were public :( */ if ((buf1 = ctf_write_mem (in1, &buf1_sz, -1)) == NULL) { fprintf (stderr, "Cannot serialize: %s\n", ctf_errmsg (ctf_errno (in1))); return 1; } s.cts_name = "foo"; s.cts_data = (void *) buf1; s.cts_size = buf1_sz; s.cts_entsize = 64; /* Unimportant. */ if ((arc1 = ctf_arc_bufopen (&s, NULL, NULL, &err)) == NULL) goto open_err; ctf_dict_close (in1); /* Link! Even a one-file link does deduplication. */ if (ctf_link_add_ctf (fp, arc1, "a") < 0) goto link_err; if (ctf_link (fp, 0) < 0) goto link_err; /* Write it out. We need a new buf here, because the archive is still using the other buf. */ if ((buf2 = ctf_link_write (fp, &buf2_sz, 4096)) == NULL) goto link_err; /* Read it back in. */ s.cts_data = (void *) buf2; s.cts_size = buf2_sz; if ((final_arc = ctf_arc_bufopen (&s, NULL, NULL, &err)) == NULL) goto open_err; /* Dump the types, and search for the {sigils of non-rootedness}. */ while ((dump_fp = ctf_archive_next (final_arc, &i, NULL, 0, &err)) != NULL) { char *dumpstr; while ((dumpstr = ctf_dump (dump_fp, &dump_state, CTF_SECT_TYPE, NULL, NULL)) != NULL) { if (strchr (dumpstr, '{') != NULL && strchr (dumpstr, '}') != NULL) printf ("Non-root type found.\n"); free (dumpstr); } ctf_dict_close (dump_fp); } if (err != ECTF_NEXT_END) { fprintf (stderr, "Archive iteration error: %s\n", ctf_errmsg (err)); return 1; } ctf_arc_close (final_arc); free (buf1); free (buf2); ctf_dict_close (fp); return 0; create_err: fprintf (stderr, "Cannot create: %s\n", ctf_errmsg (err)); return 1; open_err: fprintf (stderr, "Cannot open: %s\n", ctf_errmsg (err)); return 1; link_err: fprintf (stderr, "Cannot link: %s\n", ctf_errmsg (ctf_errno (fp))); return 1; #endif }