2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999-2018 The strace developers.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 static inline enum xlat_style
37 get_xlat_style(enum xlat_style style)
39 if (xlat_verbose(style) == XLAT_STYLE_DEFAULT)
40 return style | xlat_verbosity;
45 static inline const char *
46 sprint_xlat_val(uint64_t val, enum xlat_style style)
48 static char buf[sizeof(val) * 3];
50 switch (xlat_format(style)) {
51 case XLAT_STYLE_FMT_D:
52 xsprintf(buf, "%" PRId64, val);
55 case XLAT_STYLE_FMT_U:
56 xsprintf(buf, "%" PRIu64, val);
59 case XLAT_STYLE_FMT_X:
60 xsprintf(buf, "%#" PRIx64, val);
68 print_xlat_val(uint64_t val, enum xlat_style style)
70 tprints(sprint_xlat_val(val, style));
74 xlookup(const struct xlat *xlat, const uint64_t val)
76 for (; xlat->str != NULL; xlat++)
83 xlat_bsearch_compare(const void *a, const void *b)
85 const uint64_t val1 = *(const uint64_t *) a;
86 const uint64_t val2 = ((const struct xlat *) b)->val;
87 return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
91 xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
93 const struct xlat *e =
94 bsearch((const void *) &val,
95 xlat, nmemb, sizeof(*xlat), xlat_bsearch_compare);
97 return e ? e->str : NULL;
101 * Print entry in struct xlat table, if there.
103 * @param val Value to search a literal representation for.
104 * @param dflt String (abbreviated in comment syntax) which should be emitted
105 * if no appropriate xlat value has been found.
106 * @param style Style in which xlat value should be printed.
107 * @param xlat (And the following arguments) Pointers to arrays of xlat values.
108 * The last argument should be NULL.
109 * @return 1 if appropriate xlat value has been found, 0 otherwise.
112 printxvals_ex(const uint64_t val, const char *dflt, enum xlat_style style,
113 const struct xlat *xlat, ...)
115 style = get_xlat_style(style);
117 if (xlat_verbose(style) == XLAT_STYLE_RAW) {
118 print_xlat_val(val, style);
124 va_start(args, xlat);
125 for (; xlat; xlat = va_arg(args, const struct xlat *)) {
126 const char *str = xlookup(xlat, val);
129 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
130 print_xlat_val(val, style);
131 tprints_comment(str);
140 /* No hits -- print raw # instead. */
141 print_xlat_val(val, style);
142 tprints_comment(dflt);
150 sprintxval_ex(char *const buf, const size_t size, const struct xlat *const x,
151 const unsigned int val, const char *const dflt,
152 enum xlat_style style)
154 style = get_xlat_style(style);
156 if (xlat_verbose(style) == XLAT_STYLE_RAW)
157 return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
159 const char *const str = xlookup(x, val);
162 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
163 return xsnprintf(buf, size, "%s /* %s */",
164 sprint_xlat_val(val, style), str);
166 return xsnprintf(buf, size, "%s", str);
169 return xsnprintf(buf, size, "%s /* %s */",
170 sprint_xlat_val(val, style), dflt);
172 return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
176 * Print entry in sorted struct xlat table, if it is there.
178 * @param xlat Pointer to an array of xlat values (not terminated with
180 * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
181 * if array is declared in the unit's scope and not
182 * terminated with XLAT_END).
183 * @param val Value to search literal representation for.
184 * @param dflt String (abbreviated in comment syntax) which should be
185 * emitted if no appropriate xlat value has been found.
186 * @param style Style in which xlat value should be printed.
187 * @param fn Search function.
188 * @return 1 if appropriate xlat value has been found, 0
192 printxval_sized(const struct xlat *xlat, size_t xlat_size, uint64_t val,
193 const char *dflt, enum xlat_style style,
194 const char *(* fn)(const struct xlat *, size_t, uint64_t))
196 style = get_xlat_style(style);
198 if (xlat_verbose(style) == XLAT_STYLE_RAW) {
199 print_xlat_val(val, style);
203 const char *s = fn(xlat, xlat_size, val);
206 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
207 print_xlat_val(val, style);
215 print_xlat_val(val, style);
216 tprints_comment(dflt);
222 printxval_searchn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
223 const char *dflt, enum xlat_style style)
225 return printxval_sized(xlat, xlat_size, val, dflt, style,
230 xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val)
235 if (val != xlat[val].val) {
236 error_func_msg("Unexpected xlat value %" PRIu64
237 " at index %" PRIu64,
242 return xlat[val].str;
246 printxval_indexn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
247 const char *dflt, enum xlat_style style)
249 return printxval_sized(xlat, xlat_size, val, dflt, style, xlat_idx);
253 * Interpret `xlat' as an array of flags.
254 * Print to static string the entries whose bits are on in `flags'
255 * Return static string. If 0 is provided as flags, and there is no flag that
256 * has the value of 0 (it should be the first in xlat table), return NULL.
259 * +------------+------------+---------+------------+
260 * | flags != 0 | xlat found | style | output |
261 * +------------+------------+---------+------------+
262 * | false | (any) | raw | <none> |
263 * | true | (any) | raw | VAL |
264 * +------------+------------+---------+------------+
265 * | false | false | abbrev | <none> |
266 * | true | false | abbrev | VAL |
267 * | (any) | true | abbrev | XLAT |
268 * +------------+------------+---------+------------+
269 * | false | false | verbose | <none> |
270 * | true | false | verbose | VAL |
271 * | (any) | true | verbose | VAL (XLAT) |
272 * +------------+------------+---------+------------+
275 sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
276 enum xlat_style style)
278 static char outstr[1024];
282 outptr = stpcpy(outstr, prefix);
283 style = get_xlat_style(style);
285 if (xlat_verbose(style) == XLAT_STYLE_RAW) {
289 outptr = xappendstr(outstr, outptr, "%s",
290 sprint_xlat_val(flags, style));
295 if (flags == 0 && xlat->val == 0 && xlat->str) {
296 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
297 outptr = xappendstr(outstr, outptr, "0 /* %s */",
300 strcpy(outptr, xlat->str);
306 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE && flags)
307 outptr = xappendstr(outstr, outptr, "%s",
308 sprint_xlat_val(flags, style));
310 for (; flags && xlat->str; xlat++) {
311 if (xlat->val && (flags & xlat->val) == xlat->val) {
314 else if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
315 outptr = stpcpy(outptr, " /* ");
317 outptr = stpcpy(outptr, xlat->str);
326 if (found || xlat_verbose(style) != XLAT_STYLE_VERBOSE)
327 outptr = xappendstr(outstr, outptr, "%s",
328 sprint_xlat_val(flags, style));
334 if (found && xlat_verbose(style) == XLAT_STYLE_VERBOSE)
335 outptr = stpcpy(outptr, " */");
341 * Print flags from multiple xlat tables.
344 * +------------+--------------+------------+---------+------------+
345 * | flags != 0 | dflt != NULL | xlat found | style | output |
346 * +------------+--------------+------------+---------+------------+
347 * | false | false | (any) | raw | <none> |
348 * | false | true | (any) | raw | VAL |
349 * | true | (any) | (any) | raw | VAL |
350 * +------------+--------------+------------+---------+------------+
351 * | false | false | false | abbrev | <none> |
352 * | false | true | false | abbrev | VAL |
353 * | true | false | false | abbrev | VAL |
354 * | true | true | false | abbrev | VAL (DFLT) |
355 * | (any) | (any) | true | abbrev | XLAT |
356 * +------------+--------------+------------+---------+------------+
357 * | false | false | false | verbose | <none> |
358 * | false | true | false | verbose | VAL |
359 * | true | false | false | verbose | VAL |
360 * | true | true | false | verbose | VAL (DFLT) |
361 * | (any) | (any) | true | verbose | VAL (XLAT) |
362 * +------------+--------------+------------+---------+------------+
365 printflags_ex(uint64_t flags, const char *dflt, enum xlat_style style,
366 const struct xlat *xlat, ...)
368 style = get_xlat_style(style);
370 if (xlat_verbose(style) == XLAT_STYLE_RAW) {
372 print_xlat_val(flags, style);
379 const char *init_sep = "";
383 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
386 print_xlat_val(flags, style);
389 va_start(args, xlat);
390 for (; xlat; xlat = va_arg(args, const struct xlat *)) {
391 for (; (flags || !n) && xlat->str; ++xlat) {
392 if ((flags == xlat->val) ||
393 (xlat->val && (flags & xlat->val) == xlat->val)) {
394 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE
398 (n++ ? "|" : init_sep), xlat->str);
410 print_xlat_val(flags, style);
414 if (xlat_verbose(style) == XLAT_STYLE_VERBOSE)
418 if (xlat_verbose(style) != XLAT_STYLE_VERBOSE)
419 print_xlat_val(flags, style);
420 tprints_comment(dflt);
431 print_xlat_ex(const uint64_t val, const char *str, enum xlat_style style)
433 style = get_xlat_style(style);
435 switch (xlat_verbose(style)) {
436 case XLAT_STYLE_ABBREV:
441 ATTRIBUTE_FALLTHROUGH;
444 print_xlat_val(val, style);
448 error_func_msg("Unexpected style value of %#x", style);
449 ATTRIBUTE_FALLTHROUGH;
451 case XLAT_STYLE_VERBOSE:
452 print_xlat_val(val, style);
453 tprints_comment(str);