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 /* Look up all the symbols by name and make sure that works. */
103 if (ctf_lookup_by_symbol_name (fp
, "data_a") != base2
)
104 goto lookup_syms_err
;
105 if (ctf_lookup_by_symbol_name (fp
, "data_b") != base3
)
106 goto lookup_syms_err
;
107 if (ctf_lookup_by_symbol_name (fp
, "data_c") != base
)
108 goto lookup_syms_err
;
109 if (ctf_lookup_by_symbol_name (fp
, "func_a") != func2
)
110 goto lookup_syms_err
;
111 if (ctf_lookup_by_symbol_name (fp
, "func_b") != func3
)
112 goto lookup_syms_err
;
113 if (ctf_lookup_by_symbol_name (fp
, "func_c") != func
)
114 goto lookup_syms_err
;
116 /* Possibly report some but not all of the symbols, as if we are a linker (no
117 real program would do this without using the ctf_link APIs, but it's not
118 *prohibited*, just useless, and if they do we don't want things to
119 break. In particular we want all the symbols written out, reported or no,
120 ignoring the reported symbol set entirely.) */
124 sym
.st_nameidx_set
= 0;
126 sym
.st_shndx
= 404; /* Arbitrary, not SHN_UNDEF or SHN_EXTABS. */
127 sym
.st_value
= 404; /* Arbitrary, nonzero. */
129 /* STT_OBJECT: 1. Don't rely on the #define being visible: this may be a
131 if (report_sym (fp
, &sym
, "data_c", 2, 1) < 0 ||
132 report_sym (fp
, &sym
, "data_a", 3, 1) < 0)
136 if (report_sym (fp
, &sym
, "func_c", 4, 2) < 0 ||
137 report_sym (fp
, &sym
, "func_a", 5, 2) < 0)
140 /* Look up all the symbols by name now we have reported symbols. */
142 if (ctf_lookup_by_symbol_name (fp
, "data_a") != base2
)
143 goto lookup_syms_err
;
144 if (ctf_lookup_by_symbol_name (fp
, "data_b") != base3
)
145 goto lookup_syms_err
;
146 if (ctf_lookup_by_symbol_name (fp
, "data_c") != base
)
147 goto lookup_syms_err
;
148 if (ctf_lookup_by_symbol_name (fp
, "func_a") != func2
)
149 goto lookup_syms_err
;
150 if (ctf_lookup_by_symbol_name (fp
, "func_b") != func3
)
151 goto lookup_syms_err
;
152 if (ctf_lookup_by_symbol_name (fp
, "func_c") != func
)
153 goto lookup_syms_err
;
156 /* Write out, to memory. */
158 if ((buf
= ctf_write_mem (fp
, &bufsiz
, 4096)) == NULL
)
163 if ((fp
= ctf_simple_open ((const char *) buf
, bufsiz
, NULL
, 0, 0, NULL
,
167 /* Verify symbol order against the order we expect if this dict is sorted and
170 struct ctf_symtype_expected
175 struct ctf_symtype_expected expected_obj
[] = { { "data_a", base2
},
177 { "data_c", base
}, NULL
};
178 struct ctf_symtype_expected expected_func
[] = { { "func_a", func2
},
180 { "func_c", func
}, NULL
};
181 expected
= expected_obj
;
183 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 0)) != CTF_ERR
)
185 if (expected
== NULL
)
186 goto expected_overshoot_err
;
187 if (symtype
!= expected
->id
|| strcmp (symname
, expected
->name
) != 0)
188 goto expected_compar_err
;
189 printf ("Seen: %s\n", symname
);
193 expected
= expected_func
;
194 while ((symtype
= ctf_symbol_next (fp
, &i
, &symname
, 1)) != CTF_ERR
)
196 if (expected
== NULL
)
197 goto expected_overshoot_err
;
198 if (symtype
!= expected
->id
|| strcmp (symname
, expected
->name
) != 0)
199 goto expected_compar_err
;
200 printf ("Seen: %s\n", symname
);
209 fprintf (stderr
, "Creation failed: %s\n", ctf_errmsg (err
));
212 fprintf (stderr
, "Reopen failed: %s\n", ctf_errmsg (err
));
215 fprintf (stderr
, "Cannot create types: %s\n", ctf_errmsg (ctf_errno (fp
)));
218 fprintf (stderr
, "Cannot create syms: %s\n", ctf_errmsg (ctf_errno (fp
)));
221 fprintf (stderr
, "Dynamic iteration comparison failure: %s "
222 "(reported type: %lx)\n", symname
, symtype
);
225 fprintf (stderr
, "Cannot iterate: %s\n", ctf_errmsg (ctf_errno (fp
)));
228 fprintf (stderr
, "Cannot report symbol: %s\n", ctf_errmsg (ctf_errno (fp
)));
231 fprintf (stderr
, "Cannot write out: %s\n", ctf_errmsg (ctf_errno (fp
)));
233 expected_overshoot_err
:
234 fprintf (stderr
, "Too many symbols in post-writeout comparison\n");
237 fprintf (stderr
, "Explicit lookup of symbols by name failed: %s\n",
238 ctf_errmsg (ctf_errno (fp
)));
241 fprintf (stderr
, "Non-dynamic iteration comparison failure: %s "
242 "(type %lx): expected %s (type %lx)\n", symname
, symtype
,
243 expected
->name
, expected
->id
);
248 main (int argc
, char *argv
[])
250 try_maybe_reporting (0);
251 try_maybe_reporting (1);