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.
This commit is contained in:
Eugene Syromyatnikov 2018-05-07 08:06:14 +02:00 committed by Dmitry V. Levin
parent eb2c0b8bdf
commit 30fe991db8
2 changed files with 90 additions and 29 deletions

69
defs.h
View File

@ -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);

50
util.c
View File

@ -44,6 +44,7 @@
#include <sys/uio.h>
#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;