xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/libctf-writable/parent-child-dtd-crash-lib.c (revision c9055873d0546e63388f027d3d7f85381cde0545)
1*c9055873Schristos /* Make sure we do various things right that involve DTD lookups of parents
2*c9055873Schristos    from the perspective of children.  */
3*c9055873Schristos 
4*c9055873Schristos #include <ctf-api.h>
5*c9055873Schristos #include <stdio.h>
6*c9055873Schristos #include <stdlib.h>
7*c9055873Schristos #include <string.h>
8*c9055873Schristos 
9*c9055873Schristos enum crash_method { ADD_STRUCT, ADD_UNION, ADD_MEMBER_OFFSET, ADD_MEMBER_ENCODED, ADD_ENUM, ADD_ENUMERATOR, SET_ARRAY };
10*c9055873Schristos 
11*c9055873Schristos void
12*c9055873Schristos dtd_crash (enum crash_method method, int parent_bigger)
13*c9055873Schristos {
14*c9055873Schristos   ctf_dict_t *pfp, *cfp;
15*c9055873Schristos   ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) };
16*c9055873Schristos   ctf_id_t ptype, ftype, stype, foo;
17*c9055873Schristos   int forward_kind = CTF_K_STRUCT;
18*c9055873Schristos   size_t i;
19*c9055873Schristos   int err;
20*c9055873Schristos 
21*c9055873Schristos   /* Maybe make the relevant type IDs in the parent much bigger than those
22*c9055873Schristos      in the child, or maybe vice versa.  */
23*c9055873Schristos 
24*c9055873Schristos   if ((pfp = ctf_create (&err)) == NULL)
25*c9055873Schristos     goto create_err;
26*c9055873Schristos 
27*c9055873Schristos   if (parent_bigger)
28*c9055873Schristos     {
29*c9055873Schristos       if ((foo = ctf_add_integer (pfp, CTF_ADD_NONROOT, "blah", &e)) == CTF_ERR)
30*c9055873Schristos 	goto create_parent;
31*c9055873Schristos 
32*c9055873Schristos       for (i = 0; i < 4096; i++)
33*c9055873Schristos 	if (ctf_add_pointer (pfp, CTF_ADD_NONROOT, foo) == CTF_ERR)
34*c9055873Schristos 	  goto create_parent;
35*c9055873Schristos     }
36*c9055873Schristos 
37*c9055873Schristos   if ((ptype = ctf_add_integer (pfp, CTF_ADD_NONROOT, "int", &e)) == CTF_ERR)
38*c9055873Schristos     goto create_parent;
39*c9055873Schristos 
40*c9055873Schristos   /* Add a forward to a struct, union, or enum (depending on the method) in
41*c9055873Schristos      the parent, so we can try to replace it in the child and see what
42*c9055873Schristos      happens.  (Most of them are structs, or it doesn't matter, as for
43*c9055873Schristos      SET_ARRAY; so we do that by default.)  */
44*c9055873Schristos 
45*c9055873Schristos   switch (method)
46*c9055873Schristos     {
47*c9055873Schristos     case ADD_UNION:
48*c9055873Schristos       forward_kind = CTF_K_UNION;
49*c9055873Schristos       break;
50*c9055873Schristos     case ADD_ENUM:
51*c9055873Schristos     case ADD_ENUMERATOR:
52*c9055873Schristos       forward_kind = CTF_K_ENUM;
53*c9055873Schristos       break;
54*c9055873Schristos       /* Placate clang.  */
55*c9055873Schristos     default:
56*c9055873Schristos       break;
57*c9055873Schristos     }
58*c9055873Schristos 
59*c9055873Schristos   if ((ftype = ctf_add_forward (pfp, CTF_ADD_ROOT, "foo", forward_kind)) == CTF_ERR)
60*c9055873Schristos     goto create_parent;
61*c9055873Schristos 
62*c9055873Schristos   if ((cfp = ctf_create (&err)) == NULL)
63*c9055873Schristos     goto create_err;
64*c9055873Schristos 
65*c9055873Schristos   if (ctf_import (cfp, pfp) < 0)
66*c9055873Schristos     goto create_child;
67*c9055873Schristos 
68*c9055873Schristos   if (!parent_bigger)
69*c9055873Schristos     {
70*c9055873Schristos       if ((foo = ctf_add_integer (pfp, CTF_ADD_NONROOT, "blah", &e)) == CTF_ERR)
71*c9055873Schristos 	goto create_parent;
72*c9055873Schristos 
73*c9055873Schristos       for (i = 0; i < 4096; i++)
74*c9055873Schristos 	if (ctf_add_pointer (pfp, CTF_ADD_NONROOT, foo) == CTF_ERR)
75*c9055873Schristos 	  goto create_parent;
76*c9055873Schristos     }
77*c9055873Schristos 
78*c9055873Schristos   switch (method)
79*c9055873Schristos     {
80*c9055873Schristos       /* These try to replace a forward, and should not do so if we're
81*c9055873Schristos 	 adding in the child and it's in the parent.  */
82*c9055873Schristos     case ADD_STRUCT:
83*c9055873Schristos       if ((stype = ctf_add_struct_sized (cfp, CTF_ADD_ROOT, "foo", 1024)) == CTF_ERR)
84*c9055873Schristos 	goto create_child;
85*c9055873Schristos       if (stype == ftype)
86*c9055873Schristos 	fprintf (stderr, "Forward-promotion spotted!\n");
87*c9055873Schristos       break;
88*c9055873Schristos 
89*c9055873Schristos     case ADD_UNION:
90*c9055873Schristos       if ((stype = ctf_add_union_sized (cfp, CTF_ADD_ROOT, "foo", 1024)) == CTF_ERR)
91*c9055873Schristos 	goto create_child;
92*c9055873Schristos       if (stype == ftype)
93*c9055873Schristos 	fprintf (stderr, "Forward-promotion spotted!\n");
94*c9055873Schristos       break;
95*c9055873Schristos 
96*c9055873Schristos     case ADD_ENUM:
97*c9055873Schristos       if ((stype = ctf_add_enum (cfp, CTF_ADD_ROOT, "foo")) == CTF_ERR)
98*c9055873Schristos 	goto create_child;
99*c9055873Schristos       if (stype == ftype)
100*c9055873Schristos 	fprintf (stderr, "Forward-promotion spotted!\n");
101*c9055873Schristos       break;
102*c9055873Schristos 
103*c9055873Schristos       /* These try to look up the struct/union/enum we're adding to: make
104*c9055873Schristos 	 sure this works from the perspective of the child if the type is in
105*c9055873Schristos 	 the parent.  Also make sure that addition of child types to parent
106*c9055873Schristos 	 types this way is prohibited, and that addition of parent types to
107*c9055873Schristos 	 parent types is allowed.  */
108*c9055873Schristos     case ADD_MEMBER_OFFSET:
109*c9055873Schristos       {
110*c9055873Schristos 	ctf_id_t ctype;
111*c9055873Schristos 
112*c9055873Schristos 	if ((stype = ctf_add_struct (pfp, CTF_ADD_ROOT, "bar")) == CTF_ERR)
113*c9055873Schristos 	  goto create_child;
114*c9055873Schristos 
115*c9055873Schristos 	if ((ctype = ctf_add_integer (cfp, CTF_ADD_NONROOT, "xyzzy", &e)) == CTF_ERR)
116*c9055873Schristos 	  goto create_child;
117*c9055873Schristos 
118*c9055873Schristos 	if (ctf_add_member_offset (cfp, stype, "member", ptype, 5) == CTF_ERR)
119*c9055873Schristos 	  goto create_child;
120*c9055873Schristos 
121*c9055873Schristos 	if (ctf_add_member_offset (cfp, stype, "xyzzy", ctype, 4) != CTF_ERR)
122*c9055873Schristos 	  fprintf (stderr, "Addition of child type to parent via child unexpectedly succeeded\n");
123*c9055873Schristos 	else if (ctf_errno (cfp) == 0)
124*c9055873Schristos 	  fprintf (stderr, "got error from ctype addition to parent struct, but no error found on child\n");
125*c9055873Schristos 
126*c9055873Schristos 	break;
127*c9055873Schristos       }
128*c9055873Schristos 
129*c9055873Schristos     case ADD_ENUMERATOR:
130*c9055873Schristos       if ((stype = ctf_add_enum (pfp, CTF_ADD_ROOT, "bar")) == CTF_ERR)
131*c9055873Schristos 	goto create_parent;
132*c9055873Schristos 
133*c9055873Schristos       if (ctf_add_enumerator (cfp, stype, "FOO", 0) == CTF_ERR)
134*c9055873Schristos 	goto create_child;
135*c9055873Schristos       break;
136*c9055873Schristos 
137*c9055873Schristos       /* This tries to look up the member type we're adding, and goes wrong
138*c9055873Schristos 	 if the struct is in the child and the member type is in the parent.  */
139*c9055873Schristos     case ADD_MEMBER_ENCODED:
140*c9055873Schristos       if ((stype = ctf_add_struct (cfp, CTF_ADD_ROOT, "foo")) == CTF_ERR)
141*c9055873Schristos 	goto create_child;
142*c9055873Schristos 
143*c9055873Schristos       if (ctf_add_member_encoded (cfp, stype, "cmember", ptype, 5, e) == CTF_ERR)
144*c9055873Schristos 	goto create_child;
145*c9055873Schristos       break;
146*c9055873Schristos 
147*c9055873Schristos       /* This tries to look up the array we're resetting the state of.  */
148*c9055873Schristos     case SET_ARRAY:
149*c9055873Schristos       {
150*c9055873Schristos 	ctf_arinfo_t ar;
151*c9055873Schristos 
152*c9055873Schristos 	ar.ctr_contents = ptype;
153*c9055873Schristos 	ar.ctr_index = ptype;
154*c9055873Schristos 	ar.ctr_nelems = 5;
155*c9055873Schristos 
156*c9055873Schristos 	if ((stype = ctf_add_array (pfp, CTF_ADD_ROOT, &ar)) == CTF_ERR)
157*c9055873Schristos 	  goto create_child;
158*c9055873Schristos 
159*c9055873Schristos 	if (ctf_set_array (cfp, stype, &ar) == CTF_ERR)
160*c9055873Schristos 	  goto create_child;
161*c9055873Schristos 	break;
162*c9055873Schristos       }
163*c9055873Schristos     }
164*c9055873Schristos 
165*c9055873Schristos   ctf_dict_close (cfp);
166*c9055873Schristos   ctf_dict_close (pfp);
167*c9055873Schristos 
168*c9055873Schristos   return;
169*c9055873Schristos 
170*c9055873Schristos  create_err:
171*c9055873Schristos   fprintf (stderr, "Creation failed: %s\n", ctf_errmsg (err));
172*c9055873Schristos   exit (1);
173*c9055873Schristos  create_parent:
174*c9055873Schristos   fprintf (stderr, "Cannot create parent type: %s\n", ctf_errmsg (ctf_errno (pfp)));
175*c9055873Schristos   exit (1);
176*c9055873Schristos  create_child:
177*c9055873Schristos   fprintf (stderr, "Cannot create child type: %s\n", ctf_errmsg (ctf_errno (cfp)));
178*c9055873Schristos   exit (1);
179*c9055873Schristos }
180