xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/libctf-regression/zrewrite.c (revision 4439cfd0acf9c7dc90625e5cd83b2317a9ab8967)
1 /* Make sure that you can modify then ctf_compress_write() a dict
2    and it changes after modification.  */
3 
4 #include <ctf-api.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 char *read_file(const char *path, size_t *len)
13 {
14   char *in = NULL;
15   char buf[4096];
16   int foo;
17   size_t ret;
18 
19   if ((foo = open (path, O_RDONLY)) < 0)
20     {
21       fprintf (stderr, "error opening %s: %s\n", path, strerror(errno));
22       exit (1);
23     }
24 
25   *len = 0;
26   while ((ret = read (foo, buf, 4096)) > 0)
27     {
28       if ((in = realloc (in, *len + ret)) == NULL)
29 	{
30 	  fprintf (stderr, "Out of memory\n");
31 	  exit (1);
32 	}
33 
34       memcpy (&in[*len], buf, ret);
35       *len += ret;
36     }
37 
38   if (ret < 0)
39     {
40       fprintf (stderr, "error reading %s: %s\n", path, strerror(errno));
41       exit (1);
42     }
43   close (foo);
44   return in;
45 }
46 
47 int
48 main (int argc, char *argv[])
49 {
50   ctf_dict_t *fp, *fp_b;
51   ctf_archive_t *ctf, *ctf_b;
52   int foo;
53   char *a, *b;
54   size_t a_len, b_len;
55   ctf_id_t type, ptrtype;
56   int err;
57 
58   if (argc != 2)
59     {
60       fprintf (stderr, "Syntax: %s PROGRAM\n", argv[0]);
61       exit(1);
62     }
63 
64   if ((ctf = ctf_open (argv[1], NULL, &err)) == NULL)
65     goto open_err;
66   if ((fp = ctf_dict_open (ctf, NULL, &err)) == NULL)
67     goto open_err;
68 
69   if ((foo = open ("tmpdir/one", O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
70     goto write_stderr;
71   if (ctf_compress_write (fp, foo) < 0)
72     goto write_err;
73   close (foo);
74 
75   if ((foo = open ("tmpdir/two", O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
76     goto write_stderr;
77   if (ctf_compress_write (fp, foo) < 0)
78     goto write_err;
79   close (foo);
80 
81   a = read_file ("tmpdir/one", &a_len);
82   b = read_file ("tmpdir/two", &b_len);
83 
84   if (a_len != b_len || memcmp (a, b, a_len) != 0)
85     {
86       fprintf (stderr, "consecutive compress_writes are different: lengths %zu and %zu\n", a_len, b_len);
87       return 1;
88     }
89 
90   free (b);
91 
92   /* Add some new types to the dict and write it out, then read it back in and
93      make sure they're still there, and that at least some of the
94      originally-present data objects are still there too.  */
95 
96   if ((type = ctf_lookup_by_name (fp, "struct a_struct")) == CTF_ERR)
97     fprintf (stderr, "Lookup of struct a_struct failed: %s\n", ctf_errmsg (ctf_errno (fp)));
98 
99   if ((ptrtype = ctf_add_pointer (fp, CTF_ADD_ROOT, type)) == CTF_ERR)
100     fprintf (stderr, "Cannot add pointer to ctf_opened dict: %s\n", ctf_errmsg (ctf_errno (fp)));
101 
102   unlink ("tmpdir/two");
103 
104   if ((foo = open ("tmpdir/two", O_CREAT | O_TRUNC | O_WRONLY, 0666)) < 0)
105     goto write_stderr;
106   if (ctf_compress_write (fp, foo) < 0)
107     goto write_err;
108   close (foo);
109 
110   b = read_file ("tmpdir/two", &b_len);
111 
112   if (a_len == b_len && memcmp (a, b, b_len) == 0)
113     {
114       fprintf (stderr, "compress_writes after adding types does not change the dict\n");
115       return 1;
116     }
117 
118   free (a);
119   free (b);
120 
121   if ((ctf_b = ctf_open ("tmpdir/two", NULL, &err)) == NULL)
122     goto open_err;
123   if ((fp_b = ctf_dict_open (ctf_b, NULL, &err)) == NULL)
124     goto open_err;
125 
126   if (ctf_type_reference (fp_b, ptrtype) == CTF_ERR)
127     fprintf (stderr, "Lookup of pointer preserved across writeout failed: %s\n", ctf_errmsg (ctf_errno (fp_b)));
128 
129   if (ctf_type_reference (fp_b, ptrtype) != type)
130     fprintf (stderr, "Look up of newly-added type in serialized dict yields ID %lx, expected %lx\n", ctf_type_reference (fp_b, ptrtype), type);
131 
132   if (ctf_lookup_by_symbol_name (fp_b, "an_int") == CTF_ERR)
133     fprintf (stderr, "Lookup of symbol an_int failed: %s\n", ctf_errmsg (ctf_errno (fp_b)));
134 
135   ctf_dict_close (fp);
136   ctf_close (ctf);
137 
138   ctf_dict_close (fp_b);
139   ctf_close (ctf_b);
140 
141   printf ("All done.\n");
142   return 0;
143 
144  open_err:
145   fprintf (stderr, "%s: cannot open: %s\n", argv[0], ctf_errmsg (err));
146   return 1;
147  write_err:
148   fprintf (stderr, "%s: cannot write: %s\n", argv[0], ctf_errmsg (ctf_errno (fp)));
149   return 1;
150  write_stderr:
151   fprintf (stderr, "%s: cannot open for writing: %s\n", argv[0], strerror (errno));
152   return 1;
153  read_err:
154   fprintf (stderr, "%s: cannot read\n", argv[0]);
155   return 1;
156 }
157