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