From 30fe991db81d27dcab8ea71bdacb0682a67da860 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Mon, 7 May 2018 08:06:14 +0200 Subject: [PATCH] print_array: add support for printing array indices * defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants. (tfetch_mem_fn, print_fn): New typedefs. (enum print_array_flag_bits, enum print_array_flags): New enumerations. (print_array_ex): Rename from print_array, add flags, index_xlat, index_xlat_size, and index_dflt arguments. (print_array): New static inline function, a thin wrapper around print_array_ex. util.c: Include "xlat.h". (print_array): Rename to print_array_ex, add flags, index_xlat, index_xlat_size, and index_dflt arguments. Print array indices according to the style settings specified by flags if PAF_PRINT_INDICES is set. --- defs.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++------------ util.c | 50 +++++++++++++++++++++++++++++------------- 2 files changed, 90 insertions(+), 29 deletions(-) diff --git a/defs.h b/defs.h index becacf69..1fb8b17b 100644 --- a/defs.h +++ b/defs.h @@ -640,6 +640,9 @@ printaddr(const kernel_ulong_t addr) #define XLAT_STYLE_FORMAT_SHIFT 2 #define XLAT_STYLE_FORMAT_MASK (3 << XLAT_STYLE_FORMAT_SHIFT) +#define XLAT_STYLE_SPEC_BITS (XLAT_STYLE_FORMAT_SHIFT + 2) +#define XLAT_STYLE_MASK ((1 << XLAT_STYLE_SPEC_BITS) - 1) + #define xlat_verbose(style_) ((style_) & XLAT_STYLE_VERBOSITY_MASK) #define xlat_format(style_) ((style_) & XLAT_STYLE_FORMAT_MASK) @@ -788,21 +791,59 @@ extern bool print_uint32_array_member(struct tcb *, void *elem_buf, extern bool print_uint64_array_member(struct tcb *, void *elem_buf, size_t elem_size, void *data); +typedef bool (*tfetch_mem_fn)(struct tcb *, kernel_ulong_t addr, + unsigned int size, void *dest); +typedef bool (*print_fn)(struct tcb *, void *elem_buf, + size_t elem_size, void *opaque_data); + +enum print_array_flag_bits { + PAF_PRINT_INDICES_BIT = XLAT_STYLE_SPEC_BITS + 1, + PAF_INDEX_XLAT_SORTED_BIT, + PAF_INDEX_XLAT_VALUE_INDEXED_BIT, +}; + +#define FLAG_(name_) name_ = 1 << name_##_BIT + +enum print_array_flags { + FLAG_(PAF_PRINT_INDICES), + FLAG_(PAF_INDEX_XLAT_SORTED), + FLAG_(PAF_INDEX_XLAT_VALUE_INDEXED), +}; + +#undef FLAG_ + +/** + * @param flags Combination of xlat style settings and additional flags from + * enum print_array_flags. + */ extern bool -print_array(struct tcb *, - kernel_ulong_t start_addr, - size_t nmemb, - void *elem_buf, - size_t elem_size, - bool (*tfetch_mem_func)(struct tcb *, - kernel_ulong_t addr, - unsigned int len, - void *laddr), - bool (*print_func)(struct tcb *, - void *elem_buf, - size_t elem_size, - void *opaque_data), - void *opaque_data); +print_array_ex(struct tcb *, + kernel_ulong_t start_addr, + size_t nmemb, + void *elem_buf, + size_t elem_size, + tfetch_mem_fn tfetch_mem_func, + print_fn print_func, + void *opaque_data, + unsigned int flags, + const struct xlat *index_xlat, + size_t index_xlat_size, + const char *index_dflt); + +static inline bool +print_array(struct tcb *const tcp, + const kernel_ulong_t start_addr, + const size_t nmemb, + void *const elem_buf, + const size_t elem_size, + tfetch_mem_fn tfetch_mem_func, + print_fn print_func, + void *const opaque_data) +{ + return print_array_ex(tcp, start_addr, nmemb, elem_buf, elem_size, + tfetch_mem_func, print_func, opaque_data, + 0, NULL, 0, NULL); +} extern kernel_ulong_t * fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args); diff --git a/util.c b/util.c index 5a0eb9ec..035f57bf 100644 --- a/util.c +++ b/util.c @@ -44,6 +44,7 @@ #include #include "largefile_wrappers.h" +#include "xlat.h" #include "xstring.h" int @@ -1086,20 +1087,18 @@ print_uint64_array_member(struct tcb *tcp, void *elem_buf, size_t elem_size, * at least once. */ bool -print_array(struct tcb *const tcp, - const kernel_ulong_t start_addr, - const size_t nmemb, - void *const elem_buf, - const size_t elem_size, - bool (*const tfetch_mem_func)(struct tcb *, - kernel_ulong_t addr, - unsigned int len, - void *laddr), - bool (*const print_func)(struct tcb *, - void *elem_buf, - size_t elem_size, - void *opaque_data), - void *const opaque_data) +print_array_ex(struct tcb *const tcp, + const kernel_ulong_t start_addr, + const size_t nmemb, + void *const elem_buf, + const size_t elem_size, + tfetch_mem_fn tfetch_mem_func, + print_fn print_func, + void *const opaque_data, + unsigned int flags, + const struct xlat *index_xlat, + size_t index_xlat_size, + const char *index_dflt) { if (!start_addr) { tprints("NULL"); @@ -1123,8 +1122,10 @@ print_array(struct tcb *const tcp, (abbrev(tcp) && max_strlen < nmemb) ? start_addr + elem_size * max_strlen : end_addr; kernel_ulong_t cur; + kernel_ulong_t idx = 0; + enum xlat_style xlat_style = flags & XLAT_STYLE_MASK; - for (cur = start_addr; cur < end_addr; cur += elem_size) { + for (cur = start_addr; cur < end_addr; cur += elem_size, idx++) { if (cur != start_addr) tprints(", "); @@ -1147,6 +1148,25 @@ print_array(struct tcb *const tcp, break; } + if (flags & PAF_PRINT_INDICES) { + tprints("["); + + if (!index_xlat) { + print_xlat_ex(idx, NULL, xlat_style); + } else if (flags & PAF_INDEX_XLAT_VALUE_INDEXED) { + printxval_indexn_ex(index_xlat, + index_xlat_size, idx, + index_dflt, xlat_style); + } else { + printxvals_ex(idx, index_dflt, xlat_style, + (flags & PAF_INDEX_XLAT_SORTED) + && idx ? NULL : index_xlat, + NULL); + } + + tprints("] = "); + } + if (!print_func(tcp, elem_buf, elem_size, opaque_data)) { cur = end_addr; break; -- 2.40.0