1 /* Make sure that writing out a dict with a symtypetab without going via
2 ctf_link_write (as a compiler might do to generate input destined for a
3 linker) always writes out a complete indexed, sorted symtypetab, ignoring the
4 set of symbols reported (if any). Also a test of dynamic dict sym
13 report_sym (ctf_dict_t
*fp
, ctf_link_sym_t
*sym
, const char *name
,
14 uint32_t idx
, uint32_t st_type
)
18 sym
->st_type
= st_type
;
19 return ctf_link_add_linker_symbol (fp
, sym
);
23 try_maybe_reporting (int report
)
26 ctf_id_t func
, func2
, func3
, base
, base2
, base3
;
27 ctf_encoding_t e
= { CTF_INT_SIGNED
, 0, sizeof (long) };
37 if ((fp
= ctf_create (&err
)) == NULL
)
40 /* Add a couple of sets of types to hang symbols off. We use multiple
41 identical types so we can distinguish between distinct func / data symbols
44 if (((base
= ctf_add_integer (fp
, CTF_ADD_ROOT
, "long int", &e
)) == CTF_ERR
) ||
45 ((base2
= ctf_add_integer (fp
, CTF_ADD_ROOT
, "long int", &e
)) == CTF_ERR
) ||
46 ((base3
= ctf_add_integer (fp
, CTF_ADD_ROOT
, "long int", &e
)) == CTF_ERR
))
47 goto create_types_err
;
52 if (((func
= ctf_add_function (fp
, CTF_ADD_ROOT
, &fi
, &dummy
)) == CTF_ERR
) ||
53 ((func2
= ctf_add_function (fp
, CTF_ADD_ROOT
, &fi
, &dummy
)) == CTF_ERR
) ||
54 ((func3
= ctf_add_function (fp
, CTF_ADD_ROOT
, &fi
, &dummy
)) == CTF_ERR
))
55 goto create_types_err
;
57 /* Add some function and data symbols. We intentionally add the symbols in
58 near-inverse order by symbol name, so that we can tell whether the
59 (necessarily indexed) section was sorted (since the sort is always in
60 lexicographical sort ordef by name). */
61 if ((ctf_add_objt_sym (fp
, "data_c", base
) < 0) ||
62 (ctf_add_objt_sym (fp
, "data_a", base2
) < 0) ||
63 (ctf_add_objt_sym (fp
, "data_b", base3
) < 0))
66 if ((ctf_add_func_sym (fp
, "func_c", func
) < 0) ||
67 (ctf_add_func_sym (fp
, "func_a", func2
) < 0) ||
68 (ctf_add_func_sym (fp
, "func_b", func3
) < 0))
71 /* Make sure we can iterate over them in a dynamic dict and that they have the
72 right types. We don't care about their order at this stage, which makes
73 the validation here a bit more verbose than it is below. */
75 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 0)) != CTF_ERR
)
77 if (symtype
== base
&& strcmp (symname
, "data_c") == 0)
79 if (symtype
== base2
&& strcmp (symname
, "data_a") == 0)
81 if (symtype
== base3
&& strcmp (symname
, "data_b") == 0)
85 if (ctf_errno (fp
) != ECTF_NEXT_END
)
88 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 1)) != CTF_ERR
)
90 if (symtype
== func
&& strcmp (symname
, "func_c") == 0)
92 if (symtype
== func2
&& strcmp (symname
, "func_a") == 0)
94 if (symtype
== func3
&& strcmp (symname
, "func_b") == 0)
98 if (ctf_errno (fp
) != ECTF_NEXT_END
)
101 /* Possibly report some but not all of the symbols, as if we are a linker (no
102 real program would do this without using the ctf_link APIs, but it's not
103 *prohibited*, just useless, and if they do we don't want things to
104 break. In particular we want all the symbols written out, reported or no,
105 ignoring the reported symbol set entirely.) */
109 sym
.st_nameidx_set
= 0;
111 sym
.st_shndx
= 404; /* Arbitrary, not SHN_UNDEF or SHN_EXTABS. */
112 sym
.st_value
= 404; /* Arbitrary, nonzero. */
114 /* STT_OBJECT: 1. Don't rely on the #define being visible: this may be a
116 if (report_sym (fp
, &sym
, "data_c", 2, 1) < 0 ||
117 report_sym (fp
, &sym
, "data_a", 3, 1) < 0)
121 if (report_sym (fp
, &sym
, "func_c", 4, 2) < 0 ||
122 report_sym (fp
, &sym
, "func_a", 5, 2) < 0)
126 /* Write out, to memory. */
128 if ((buf
= ctf_write_mem (fp
, &bufsiz
, 4096)) == NULL
)
133 if ((fp
= ctf_simple_open ((const char *) buf
, bufsiz
, NULL
, 0, 0, NULL
,
137 /* Verify symbol order against the order we expect if this dict is sorted and
140 struct ctf_symtype_expected
145 struct ctf_symtype_expected expected_obj
[] = { { "data_a", base2
},
147 { "data_c", base
}, NULL
};
148 struct ctf_symtype_expected expected_func
[] = { { "func_a", func2
},
150 { "func_c", func
}, NULL
};
151 expected
= expected_obj
;
153 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 0)) != CTF_ERR
)
155 if (expected
== NULL
)
156 goto expected_overshoot_err
;
157 if (symtype
!= expected
->id
|| strcmp (symname
, expected
->name
) != 0)
158 goto expected_compar_err
;
159 printf ("Seen: %s\n", symname
);
163 expected
= expected_func
;
164 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 1)) != CTF_ERR
)
166 if (expected
== NULL
)
167 goto expected_overshoot_err
;
168 if (symtype
!= expected
->id
|| strcmp (symname
, expected
->name
) != 0)
169 goto expected_compar_err
;
170 printf ("Seen: %s\n", symname
);
179 fprintf (stderr
, "Creation failed: %s\n", ctf_errmsg (err
));
182 fprintf (stderr
, "Reopen failed: %s\n", ctf_errmsg (err
));
185 fprintf (stderr
, "Cannot create types: %s\n", ctf_errmsg (ctf_errno (fp
)));
188 fprintf (stderr
, "Cannot create syms: %s\n", ctf_errmsg (ctf_errno (fp
)));
191 fprintf (stderr
, "Dynamic iteration comparison failure: %s "
192 "(reported type: %lx)\n", symname
, symtype
);
195 fprintf (stderr
, "Cannot iterate: %s\n", ctf_errmsg (ctf_errno (fp
)));
198 fprintf (stderr
, "Cannot report symbol: %s\n", ctf_errmsg (ctf_errno (fp
)));
201 fprintf (stderr
, "Cannot write out: %s\n", ctf_errmsg (ctf_errno (fp
)));
203 expected_overshoot_err
:
204 fprintf (stderr
, "Too many symbols in post-writeout comparison\n");
207 fprintf (stderr
, "Non-dynamic iteration comparison failure: %s "
208 "(type %lx): expected %s (type %lx)\n", symname
, symtype
,
209 expected
->name
, expected
->id
);
214 main (int argc
, char *argv
[])
216 try_maybe_reporting (0);
217 try_maybe_reporting (1);