[IOCB_CMD_PWRITEV] = SUB_VECTOR,
};
- printxval_indexn_ex(ARRSZ_PAIR(aio_cmds) - 1, cmd, "IOCB_CMD_???",
- XLAT_STYLE_FMT_U);
+ printxval_ex(aio_cmds, cmd, "IOCB_CMD_???", XLAT_STYLE_FMT_U);
return cmd < ARRAY_SIZE(subs) ? subs[cmd] : SUB_NONE;
}
/* We can't use PRINT_FIELD_XVAL on bit fields */
tprints(", dst_reg=");
- printxval_index(ebpf_regs, insn->dst_reg, "BPF_REG_???");
+ printxval(ebpf_regs, insn->dst_reg, "BPF_REG_???");
tprints(", src_reg=");
- printxval_index(ebpf_regs, insn->src_reg, "BPF_REG_???");
+ printxval(ebpf_regs, insn->src_reg, "BPF_REG_???");
PRINT_FIELD_D(", ", *insn, off);
PRINT_FIELD_X(", ", *insn, imm);
BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
{
- PRINT_FIELD_XVAL_INDEX("{", attr, map_type, bpf_map_types,
- "BPF_MAP_TYPE_???");
+ PRINT_FIELD_XVAL("{", attr, map_type, bpf_map_types,
+ "BPF_MAP_TYPE_???");
PRINT_FIELD_U(", ", attr, key_size);
PRINT_FIELD_U(", ", attr, value_size);
PRINT_FIELD_U(", ", attr, max_entries);
PRINT_FIELD_FD("{", attr, map_fd, tcp);
PRINT_FIELD_ADDR64(", ", attr, key);
PRINT_FIELD_ADDR64(", ", attr, value);
- PRINT_FIELD_XVAL_INDEX(", ", attr, flags, bpf_map_update_elem_flags,
- "BPF_???");
+ PRINT_FIELD_XVAL(", ", attr, flags, bpf_map_update_elem_flags,
+ "BPF_???");
}
END_BPF_CMD_DECODER(RVAL_DECODED)
BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
{
- PRINT_FIELD_XVAL_INDEX("{", attr, prog_type, bpf_prog_types,
- "BPF_PROG_TYPE_???");
+ PRINT_FIELD_XVAL("{", attr, prog_type, bpf_prog_types,
+ "BPF_PROG_TYPE_???");
PRINT_FIELD_U(", ", attr, insn_cnt);
tprints(", insns=");
print_ebpf_prog(tcp, attr.insns, attr.insn_cnt);
{
PRINT_FIELD_FD("{", attr, target_fd, tcp);
PRINT_FIELD_FD(", ", attr, attach_bpf_fd, tcp);
- PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
- "BPF_???");
+ PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
"BPF_F_???");
}
BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
{
PRINT_FIELD_FD("{", attr, target_fd, tcp);
- PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
- "BPF_???");
+ PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
}
END_BPF_CMD_DECODER(RVAL_DECODED)
if (entering(tcp)) {
PRINT_FIELD_FD("{query={", attr, target_fd, tcp);
- PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
- "BPF_???");
+ PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type,
+ "BPF_???");
PRINT_FIELD_FLAGS(", ", attr, query_flags, bpf_query_flags,
"BPF_F_QUERY_???");
PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
print_big_u64_addr(attr.buf);
printstr_ex(tcp, attr.buf, buf_len, QUOTE_0_TERMINATED);
PRINT_FIELD_U(", ", attr, prog_id);
- PRINT_FIELD_XVAL_INDEX(", ", attr, fd_type, bpf_task_fd_type,
- "BPF_FD_TYPE_???");
+ PRINT_FIELD_XVAL(", ", attr, fd_type, bpf_task_fd_type,
+ "BPF_FD_TYPE_???");
PRINT_FIELD_X(", ", attr, probe_offset);
PRINT_FIELD_X(", ", attr, probe_addr);
int rc = RVAL_DECODED;
if (entering(tcp)) {
- printxval_index(bpf_commands, cmd, "BPF_???");
+ printxval(bpf_commands, cmd, "BPF_???");
tprints(", ");
}
const struct xlat *mode = extended ? ebpf_mode : bpf_mode;
uint16_t i = code & ~BPF_CLASS(code);
- if (extended)
- printxval_index(ebpf_class, BPF_CLASS(code), "BPF_???");
- else
- printxval_index(bpf_class, BPF_CLASS(code), "BPF_???");
+ printxval(extended ? ebpf_class : bpf_class, BPF_CLASS(code),
+ "BPF_???");
switch (BPF_CLASS(code)) {
case BPF_ST:
case BPF_STX:
# include "xlat.h"
extern const struct xlat addrfams[];
-
-/** Protocol hardware identifiers array, sorted, defined in sockaddr.c. */
extern const struct xlat arp_hardware_types[];
-/** Protocol hardware identifiers array size without terminating record. */
-extern const size_t arp_hardware_types_size;
-
extern const struct xlat at_flags[];
extern const struct xlat clocknames[];
extern const struct xlat dirent_types[];
-
-/** Ethernet protocols list, sorted, defined in sockaddr.c. */
extern const struct xlat ethernet_protocols[];
-/** Ethernet protocols array size without terminating record. */
-extern const size_t ethernet_protocols_size;
-
-/** IP protocols list, sorted, defined in net.c. */
extern const struct xlat inet_protocols[];
-/** IP protocols array size without terminating record. */
-extern const size_t inet_protocols_size;
-
extern const struct xlat evdev_abs[];
-/** Number of elements in evdev_abs array without the terminating record. */
-extern const size_t evdev_abs_size;
-
extern const struct xlat audit_arch[];
extern const struct xlat evdev_ev[];
extern const struct xlat iffflags[];
extern enum sock_proto getfdproto(struct tcb *, int);
extern const char *xlookup(const struct xlat *, const uint64_t);
-extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
-extern const char *xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val);
+extern const char *xlookup_le(const struct xlat *, uint64_t *);
struct dyxlat;
struct dyxlat *dyxlat_alloc(size_t nmemb);
ATTRIBUTE_SENTINEL;
# define printxvals(val_, dflt_, ...) \
printxvals_ex((val_), (dflt_), XLAT_STYLE_DEFAULT, __VA_ARGS__)
-
-extern int printxval_searchn_ex(const struct xlat *, size_t xlat_size,
- uint64_t val, const char *dflt,
- enum xlat_style);
-
-static inline int
-printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt)
-{
- return printxval_searchn_ex(xlat, xlat_size, val, dflt,
- XLAT_STYLE_DEFAULT);
-}
-
-/**
- * Wrapper around printxval_searchn that passes ARRAY_SIZE - 1
- * as the array size, as all arrays are XLAT_END-terminated and
- * printxval_searchn expects a size without the terminating record.
- */
-# define printxval_search(xlat__, val__, dflt__) \
- printxval_searchn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
-# define printxval_search_ex(xlat__, val__, dflt__, style__) \
- printxval_searchn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
- (dflt__), (style__))
-
-extern int printxval_indexn_ex(const struct xlat *, size_t xlat_size,
- uint64_t val, const char *dflt, enum xlat_style);
-
-static inline int
-printxval_indexn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt)
-{
- return printxval_indexn_ex(xlat, xlat_size, val, dflt,
- XLAT_STYLE_DEFAULT);
-}
-
-# define printxval_index(xlat__, val__, dflt__) \
- printxval_indexn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
-# define printxval_index_ex(xlat__, val__, dflt__, style__) \
- printxval_indexn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
- (dflt__), (style__))
+# define printxval_ex(xlat_, val_, dflt_, style_) \
+ printxvals_ex((val_), (dflt_), (style_), (xlat_), NULL)
extern int sprintxval_ex(char *buf, size_t size, const struct xlat *,
unsigned int val, const char *dflt, enum xlat_style);
return sprintxval_ex(buf, size, xlat, val, dflt, XLAT_STYLE_DEFAULT);
}
-extern void printxval_dispatch_ex(const struct xlat *, size_t xlat_size,
- uint64_t val, const char *dflt,
- enum xlat_type, enum xlat_style);
-static inline void
-printxval_dispatch(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt, enum xlat_type xt)
-{
- return printxval_dispatch_ex(xlat, xlat_size, val, dflt, xt,
- XLAT_STYLE_DEFAULT);
-}
-
enum xlat_style_private_flag_bits {
/* print_array */
PAF_PRINT_INDICES_BIT = XLAT_STYLE_SPEC_BITS + 1,
- PAF_INDEX_XLAT_SORTED_BIT,
- PAF_INDEX_XLAT_VALUE_INDEXED_BIT,
/* print_xlat */
PXF_DEFAULT_STR_BIT,
enum xlat_style_private_flags {
/* print_array */
FLAG_(PAF_PRINT_INDICES),
- FLAG_(PAF_INDEX_XLAT_SORTED),
- FLAG_(PAF_INDEX_XLAT_VALUE_INDEXED),
/* print_xlat */
FLAG_(PXF_DEFAULT_STR),
void *opaque_data,
unsigned int flags,
const struct xlat *index_xlat,
- size_t index_xlat_size,
const char *index_dflt);
static inline bool
{
return print_array_ex(tcp, start_addr, nmemb, elem_buf, elem_size,
tfetch_mem_func, print_func, opaque_data,
- 0, NULL, 0, NULL);
+ 0, NULL, NULL);
}
extern kernel_ulong_t *
#include "defs.h"
struct dyxlat {
- size_t used;
size_t allocated;
- struct xlat *xlat;
+ struct xlat xlat;
+ struct xlat_data *data;
};
-#define MARK_END(xlat) \
- do { \
- (xlat).val = 0; \
- (xlat).str = 0; \
- } while (0)
-
struct dyxlat *
dyxlat_alloc(const size_t nmemb)
{
struct dyxlat *const dyxlat = xmalloc(sizeof(*dyxlat));
- dyxlat->used = 1;
+ dyxlat->xlat.type = XT_NORMAL;
+ dyxlat->xlat.size = 0;
dyxlat->allocated = nmemb;
- dyxlat->xlat = xgrowarray(NULL, &dyxlat->allocated, sizeof(struct xlat));
- MARK_END(dyxlat->xlat[0]);
+ dyxlat->xlat.data = dyxlat->data = xgrowarray(NULL, &dyxlat->allocated,
+ sizeof(struct xlat_data));
return dyxlat;
}
{
size_t i;
- for (i = 0; i < dyxlat->used - 1; ++i) {
- free((void *) dyxlat->xlat[i].str);
- dyxlat->xlat[i].str = NULL;
+ for (i = 0; i < dyxlat->xlat.size; ++i) {
+ free((void *) dyxlat->data[i].str);
+ dyxlat->data[i].str = NULL;
}
- free(dyxlat->xlat);
- dyxlat->xlat = NULL;
+ free(dyxlat->data);
+ dyxlat->xlat.data = NULL;
free(dyxlat);
}
const struct xlat *
dyxlat_get(const struct dyxlat *const dyxlat)
{
- return dyxlat->xlat;
+ return &dyxlat->xlat;
}
void
{
size_t i;
- for (i = 0; i < dyxlat->used - 1; ++i) {
- if (dyxlat->xlat[i].val == val) {
- if (strncmp(dyxlat->xlat[i].str, str, len) == 0
- && dyxlat->xlat[i].str[len] == '\0')
+ for (i = 0; i < dyxlat->xlat.size; ++i) {
+ if (dyxlat->data[i].val == val) {
+ if (strncmp(dyxlat->data[i].str, str, len) == 0
+ && dyxlat->data[i].str[len] == '\0')
return;
- free((void *) dyxlat->xlat[i].str);
- dyxlat->xlat[i].str = xstrndup(str, len);
+ free((void *) dyxlat->data[i].str);
+ dyxlat->data[i].str = xstrndup(str, len);
return;
}
}
- if (dyxlat->used >= dyxlat->allocated)
- dyxlat->xlat = xgrowarray(dyxlat->xlat, &dyxlat->allocated,
- sizeof(struct xlat));
+ if (dyxlat->xlat.size >= dyxlat->allocated)
+ dyxlat->xlat.data = dyxlat->data =
+ xgrowarray(dyxlat->data, &dyxlat->allocated,
+ sizeof(struct xlat_data));
- dyxlat->xlat[dyxlat->used - 1].val = val;
- dyxlat->xlat[dyxlat->used - 1].str = xstrndup(str, len);
- MARK_END(dyxlat->xlat[dyxlat->used]);
- dyxlat->used++;
+ dyxlat->data[dyxlat->xlat.size].val = val;
+ dyxlat->data[dyxlat->xlat.size].str = xstrndup(str, len);
+ dyxlat->xlat.size++;
}
# define SYN_MAX 0xf
# endif
-const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
-
static int
abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
{
if (!umove_or_printaddr(tcp, arg, &keycode)) {
tprintf("[%u, ", keycode[0]);
- printxval_index(evdev_keycode, keycode[1], "KEY_???");
+ printxval(evdev_keycode, keycode[1], "KEY_???");
tprints("]");
}
unsigned int i;
tprintf("index=%" PRIu16 ", keycode=", ike.index);
- printxval_index(evdev_keycode, ike.keycode, "KEY_???");
+ printxval(evdev_keycode, ike.keycode, "KEY_???");
tprints(", scancode=[");
for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
if (i > 0)
}
static int
-decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
- const struct xlat decode_nr[], const unsigned int max_nr,
- const char *const dflt, size_t decode_nr_size, enum xlat_type xt)
+decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
+ const struct xlat *decode_nr, const unsigned int max_nr,
+ const char *const dflt)
{
tprints(", ");
if (i < 0) {
tprints(" 0 ");
} else {
- printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt);
+ printxval(decode_nr, i, dflt);
while ((i = next_set_bit(decoded_arg, i + 1, size_bits)) > 0) {
if (abbrev(tcp) && bit_displayed >= 3) {
break;
}
tprints(", ");
- printxval_dispatch(decode_nr, decode_nr_size, i, dflt,
- xt);
+ printxval(decode_nr, i, dflt);
bit_displayed++;
}
}
return RVAL_IOCTL_DECODED;
}
-# define decode_bitset(tcp_, arg_, decode_nr_, max_nr_, dflt_, xt_) \
- decode_bitset_((tcp_), (arg_), (decode_nr_), (max_nr_), \
- (dflt_), ARRAY_SIZE(decode_nr_) - 1, (xt_))
-
# ifdef EVIOCGMTSLOTS
static int
mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
switch (ev_nr) {
case 0:
return decode_bitset(tcp, arg, evdev_ev,
- EV_MAX, "EV_???", XT_SORTED);
+ EV_MAX, "EV_???");
case EV_KEY:
return decode_bitset(tcp, arg, evdev_keycode,
- KEY_MAX, "KEY_???", XT_INDEXED);
+ KEY_MAX, "KEY_???");
case EV_REL:
return decode_bitset(tcp, arg, evdev_relative_axes,
- REL_MAX, "REL_???", XT_INDEXED);
+ REL_MAX, "REL_???");
case EV_ABS:
return decode_bitset(tcp, arg, evdev_abs,
- ABS_MAX, "ABS_???", XT_INDEXED);
+ ABS_MAX, "ABS_???");
case EV_MSC:
return decode_bitset(tcp, arg, evdev_misc,
- MSC_MAX, "MSC_???", XT_INDEXED);
+ MSC_MAX, "MSC_???");
case EV_SW:
return decode_bitset(tcp, arg, evdev_switch,
- SW_MAX, "SW_???", XT_INDEXED);
+ SW_MAX, "SW_???");
case EV_LED:
return decode_bitset(tcp, arg, evdev_leds,
- LED_MAX, "LED_???", XT_INDEXED);
+ LED_MAX, "LED_???");
case EV_SND:
return decode_bitset(tcp, arg, evdev_snd,
- SND_MAX, "SND_???", XT_INDEXED);
+ SND_MAX, "SND_???");
case EV_REP:
return decode_bitset(tcp, arg, evdev_autorepeat,
- REP_MAX, "REP_???", XT_INDEXED);
+ REP_MAX, "REP_???");
case EV_FF:
return decode_bitset(tcp, arg, evdev_ff_types,
- FF_MAX, "FF_???", XT_SORTED);
+ FF_MAX, "FF_???");
case EV_PWR:
tprints(", ");
printnum_int(tcp, arg, "%d");
return RVAL_IOCTL_DECODED;
case EV_FF_STATUS:
return decode_bitset(tcp, arg, evdev_ff_status,
- FF_STATUS_MAX, "FF_STATUS_???",
- XT_INDEXED);
+ FF_STATUS_MAX, "FF_STATUS_???");
default:
tprints(", ");
printaddr(arg);
# ifdef EVIOCGPROP
case _IOC_NR(EVIOCGPROP(0)):
return decode_bitset(tcp, arg, evdev_prop,
- INPUT_PROP_MAX, "PROP_???",
- XT_INDEXED);
+ INPUT_PROP_MAX, "PROP_???");
# endif
case _IOC_NR(EVIOCGSND(0)):
return decode_bitset(tcp, arg, evdev_snd,
- SND_MAX, "SND_???", XT_INDEXED);
+ SND_MAX, "SND_???");
# ifdef EVIOCGSW
case _IOC_NR(EVIOCGSW(0)):
return decode_bitset(tcp, arg, evdev_switch,
- SW_MAX, "SW_???", XT_INDEXED);
+ SW_MAX, "SW_???");
# endif
case _IOC_NR(EVIOCGKEY(0)):
return decode_bitset(tcp, arg, evdev_keycode,
- KEY_MAX, "KEY_???", XT_INDEXED);
+ KEY_MAX, "KEY_???");
case _IOC_NR(EVIOCGLED(0)):
return decode_bitset(tcp, arg, evdev_leds,
- LED_MAX, "LED_???", XT_INDEXED);
+ LED_MAX, "LED_???");
}
/* multi-number fixed-length commands */
printfd(tcp, fs_fd);
tprints(", ");
- printxval_index(fsconfig_cmds, cmd, "FSCONFIG_???");
+ printxval(fsconfig_cmds, cmd, "FSCONFIG_???");
tprints(", ");
switch (cmd) {
if (_IOC_DIR(code) == _IOC_WRITE) {
if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
tprints("EVIOCSABS(");
- printxval_indexn(evdev_abs, evdev_abs_size, nr - 0xc0,
- "ABS_???");
+ printxval(evdev_abs, nr - 0xc0, "ABS_???");
tprints(")");
return 1;
}
return 1;
} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
tprints("EVIOCGABS(");
- printxval_indexn(evdev_abs, evdev_abs_size, nr - 0x40,
- "ABS_???");
+ printxval(evdev_abs, nr - 0x40, "ABS_???");
tprints(")");
return 1;
}
const kernel_ulong_t arg)
{
tprints(", ");
- printxval_index(kvm_cap, arg, "KVM_CAP_???");
+ printxval64(kvm_cap, arg, "KVM_CAP_???");
return RVAL_IOCTL_DECODED;
}
if (umove(tcp, info->mmap_addr, &vcpu_run_struct) < 0)
return;
- tcp->auxstr = xlat_idx(kvm_exit_reason, ARRAY_SIZE(kvm_exit_reason) - 1,
- vcpu_run_struct.exit_reason);
+ tcp->auxstr = xlookup(kvm_exit_reason, vcpu_run_struct.exit_reason);
if (!tcp->auxstr)
tcp->auxstr = "KVM_EXIT_???";
}
switch (tcp->u_arg[0]) {
case AF_INET:
case AF_INET6:
- printxval_search(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
+ printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
break;
case AF_AX25:
/* Those are not available in public headers. */
- printxval_searchn_ex(ARRSZ_PAIR(ax25_protocols) - 1,
- tcp->u_arg[2], "AX25_P_???",
- XLAT_STYLE_VERBOSE);
+ printxval_ex(ax25_protocols, tcp->u_arg[2], "AX25_P_???",
+ XLAT_STYLE_VERBOSE);
break;
case AF_NETLINK:
case AF_PACKET:
tprints("htons(");
- printxval_searchn(ethernet_protocols, ethernet_protocols_size,
- ntohs(tcp->u_arg[2]), "ETH_P_???");
+ printxval(ethernet_protocols, ntohs(tcp->u_arg[2]),
+ "ETH_P_???");
tprints(")");
break;
case AF_IRDA:
- printxval_index(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
+ printxval(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
break;
case AF_CAN:
- printxval_index(can_protocols, tcp->u_arg[2], "CAN_???");
+ printxval(can_protocols, tcp->u_arg[2], "CAN_???");
break;
case AF_BLUETOOTH:
- printxval_index(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
+ printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
break;
case AF_RXRPC:
break;
case AF_PHONET:
- printxval_index(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
+ printxval(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
break;
case AF_CAIF:
- printxval_index(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
+ printxval(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
break;
case AF_NFC:
- printxval_index(nfc_protocols, tcp->u_arg[2],
- "NFC_SOCKPROTO_???");
+ printxval(nfc_protocols, tcp->u_arg[2], "NFC_SOCKPROTO_???");
break;
case AF_KCM:
- printxval_index(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
+ printxval(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
break;
case AF_SMC:
- printxval_index(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
+ printxval(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
break;
default:
{
printfd(tcp, fd);
tprints(", ");
- printxval_search(socketlayers, level, "SOL_??");
+ printxval(socketlayers, level, "SOL_??");
tprints(", ");
switch (level) {
printxval(sock_ipx_options, name, "IPX_???");
break;
case SOL_AX25:
- printxval_search(sock_ax25_options, name, "AX25_???");
+ printxval(sock_ax25_options, name, "AX25_???");
break;
case SOL_PACKET:
printxval(sock_packet_options, name, "PACKET_???");
break;
case SOL_TCP:
- printxval_index(sock_tcp_options, name, "TCP_???");
+ printxval(sock_tcp_options, name, "TCP_???");
break;
case SOL_SCTP:
printxval(sock_sctp_options, name, "SCTP_???");
printxval(sock_udp_options, name, "UDP_???");
break;
case SOL_IRDA:
- printxval_index(sock_irda_options, name, "IRLMP_???");
+ printxval(sock_irda_options, name, "IRLMP_???");
break;
case SOL_LLC:
- printxval_index(sock_llc_options, name, "LLC_OPT_???");
+ printxval(sock_llc_options, name, "LLC_OPT_???");
break;
case SOL_DCCP:
- printxval_search(sock_dccp_options, name, "DCCP_SOCKOPT_???");
+ printxval(sock_dccp_options, name, "DCCP_SOCKOPT_???");
break;
case SOL_TIPC:
- printxval_search(sock_tipc_options, name, "TIPC_???");
+ printxval(sock_tipc_options, name, "TIPC_???");
break;
case SOL_RXRPC:
- printxval_index(sock_rxrpc_options, name, "RXRPC_???");
+ printxval(sock_rxrpc_options, name, "RXRPC_???");
break;
case SOL_PPPOL2TP:
- printxval_index(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
+ printxval(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
break;
case SOL_BLUETOOTH:
- printxval_search(sock_bluetooth_options, name, "BT_???");
+ printxval(sock_bluetooth_options, name, "BT_???");
break;
case SOL_PNPIPE:
printxval(sock_pnp_options, name, "PNPIPE_???");
break;
case SOL_RDS:
- printxval_search(sock_rds_options, name, "RDS_???");
+ printxval(sock_rds_options, name, "RDS_???");
break;
case SOL_IUCV:
printxval(sock_iucv_options, name, "SO_???");
printxval(sock_caif_options, name, "CAIFSO_???");
break;
case SOL_ALG:
- printxval_index(sock_alg_options, name, "ALG_???");
+ printxval(sock_alg_options, name, "ALG_???");
break;
case SOL_NFC:
- printxval_index(sock_nfcllcp_options, name, "NFC_LLCP_???");
+ printxval(sock_nfcllcp_options, name, "NFC_LLCP_???");
break;
case SOL_KCM:
printxval(sock_kcm_options, name, "KCM_???");
printxval(sock_tls_options, name, "TLS_???");
break;
case SOL_XDP:
- printxval_index(sock_xdp_options, name, "XDP_???");
+ printxval(sock_xdp_options, name, "XDP_???");
break;
/* Other SOL_* protocol levels still need work. */
if (nl_details == details)
return -1;
- const struct xlat *xlats = netlink_protocols;
- for (; xlats->str; ++xlats) {
- const char *name = STR_STRIP_PREFIX(xlats->str, "NETLINK_");
+ const struct xlat_data *xlats = netlink_protocols->data;
+ for (uint32_t idx = 0; idx < netlink_protocols->size; idx++) {
+ if (!netlink_protocols->data[idx].str)
+ continue;
+
+ const char *name = STR_STRIP_PREFIX(xlats[idx].str, "NETLINK_");
if (!strncmp(nl_details, name, strlen(name)))
- return xlats->val;
+ return xlats[idx].val;
}
if (*nl_details >= '0' && *nl_details <= '9')
(char *) &msg + offset)) {
PRINT_FIELD_XVAL("", msg, pdiag_type,
socktypes, "SOCK_???");
- PRINT_FIELD_XVAL_SORTED_SIZED(", ", msg, pdiag_num,
- ethernet_protocols,
- ethernet_protocols_size,
- "ETH_P_???");
+ PRINT_FIELD_XVAL(", ", msg, pdiag_num,
+ ethernet_protocols, "ETH_P_???");
PRINT_FIELD_U(", ", msg, pdiag_ino);
PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
decode_nla = true;
const void *const opaque_data)
{
const struct decode_nla_xlat_opts opts = {
- ARRSZ_PAIR(sock_shutdown_flags) - 1, "???_SHUTDOWN",
+ sock_shutdown_flags, "???_SHUTDOWN",
.size = 1,
};
* net/smc/smc_clc.h
*/
tprints("{reason=");
- printxval_search_ex(smc_decl_codes, fb.reason,
- "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
+ printxval_ex(smc_decl_codes, fb.reason, "SMC_CLC_DECL_???",
+ XLAT_STYLE_VERBOSE);
tprints(", peer_diagnosis=");
- printxval_search_ex(smc_decl_codes, fb.peer_diagnosis,
- "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
+ printxval_ex(smc_decl_codes, fb.peer_diagnosis, "SMC_CLC_DECL_???",
+ XLAT_STYLE_VERBOSE);
tprints("}");
return true;
(void *) &msg + offset)) {
PRINT_FIELD_XVAL("", msg, diag_state,
smc_states, "SMC_???");
- PRINT_FIELD_XVAL_INDEX(", ", msg, diag_fallback,
- smc_diag_mode,
- "SMC_DIAG_MODE_???");
+ PRINT_FIELD_XVAL(", ", msg, diag_fallback,
+ smc_diag_mode, "SMC_DIAG_MODE_???");
PRINT_FIELD_U(", ", msg, diag_shutdown);
/*
* AF_SMC protocol family socket handler
unsigned int count = 0;
print_array_ex(tcp, addr, nmemb, &mem, sizeof(mem),
tfetch_mem, print_uint32_array_member, &count,
- PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
- | XLAT_STYLE_FMT_U,
- ARRSZ_PAIR(netlink_sk_meminfo_indices) - 1,
- "SK_MEMINFO_???");
+ PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+ netlink_sk_meminfo_indices, "SK_MEMINFO_???");
return true;
}
data.val = opts->process_fn(data.val);
if (opts->prefix)
tprints(opts->prefix);
- printxval_dispatch_ex(opts->xlat, opts->xlat_size, data.val,
- opts->dflt, opts->xt, opts->style);
+ printxval_ex(opts->xlat, data.val, opts->dflt, opts->style);
if (opts->suffix)
tprints(opts->suffix);
}
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
+ static const struct decode_nla_xlat_opts opts = {
.xlat = ethernet_protocols,
- .xlat_size = ethernet_protocols_size,
.dflt = "ETHER_P_???",
- .xt = XT_SORTED,
.prefix = "htons(",
.suffix = ")",
.size = 2,
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
+ static const struct decode_nla_xlat_opts opts = {
.xlat = inet_protocols,
- .xlat_size = inet_protocols_size,
- .xt = XT_SORTED,
.dflt = "IPPROTO_???",
.size = 1,
};
const size_t bytes_offs = is_bigendian ? sizeof(data) - len : 0;
- if (opts->xt == XT_INDEXED)
- error_func_msg("indexed xlats are currently incompatible with "
- "printflags");
-
if (!umoven_or_printaddr(tcp, addr, len, data.bytes + bytes_offs)) {
if (opts->process_fn)
data.flags = opts->process_fn(data.flags);
struct decode_nla_xlat_opts {
const struct xlat *xlat;
- size_t xlat_size; /* is not needed for XT_NORMAL */
const char *dflt;
- enum xlat_type xt;
enum xlat_style style;
const char *prefix;
const char *suffix;
(xlat_), NULL); \
} while (0)
-# define PRINT_FIELD_XVAL_SORTED_SIZED(prefix_, where_, field_, xlat_, \
- xlat_size_, dflt_) \
- do { \
- STRACE_PRINTF("%s%s=", (prefix_), #field_); \
- printxval_searchn((xlat_), (xlat_size_), \
- zero_extend_signed_to_ull((where_).field_), \
- (dflt_)); \
- } while (0)
-
-# define PRINT_FIELD_XVAL_INDEX(prefix_, where_, field_, xlat_, dflt_) \
- do { \
- STRACE_PRINTF("%s%s=", (prefix_), #field_); \
- printxval_index((xlat_), \
- zero_extend_signed_to_ull((where_).field_), \
- (dflt_)); \
- } while (0)
-
/*
* Generic "ID" printing. ID is considered unsigned except for the special value
* of -1.
print_statfs_type(const char *const prefix, const unsigned long long magic)
{
tprints(prefix);
- printxval_search(fsmagic, magic, NULL);
+ printxval(fsmagic, magic, NULL);
}
#if defined HAVE_STRUCT_STATFS_F_FLAGS || defined HAVE_STRUCT_STATFS64_F_FLAGS
#define uoff(member) offsetof(struct user, member)
#define XLAT_UOFF(member) { uoff(member), "offsetof(struct user, " #member ")" }
-static const struct xlat struct_user_offsets[] = {
+static const struct xlat_data struct_user_offsets_data[] = {
#include "userent.h"
XLAT_END
};
+static const struct xlat struct_user_offsets = {
+ .type = XT_SORTED,
+ .size = ARRAY_SIZE(struct_user_offsets_data) - 1,
+ .data = struct_user_offsets_data,
+};
+
static void
print_user_offset_addr(const kernel_ulong_t addr)
{
- bool no_str = false;
- const struct xlat *x;
+ const uint64_t last_user_offset = struct_user_offsets.size ?
+ struct_user_offsets.data[struct_user_offsets.size - 1].val : 0;
- for (x = struct_user_offsets; x->str; ++x) {
- if (x->val >= addr)
- break;
- }
+ uint64_t base_addr = addr;
+ const char *str = xlookup_le(&struct_user_offsets, &base_addr);
- if (!x->str || (x == struct_user_offsets && x->val > addr))
- no_str = true;
- if (no_str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
+ /* We don't want to pretty print addresses beyond struct user */
+ if (addr > base_addr && base_addr == last_user_offset)
+ str = NULL;
+
+ if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
printaddr(addr);
- if (no_str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
+ if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
return;
if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
tprints(" /* ");
- if (x->val > addr) {
- --x;
+ if (base_addr == addr)
+ tprints(str);
+ else
tprintf("%s + %" PRI_klu,
- x->str, addr - (kernel_ulong_t) x->val);
- } else {
- tprints(x->str);
- }
+ str, addr - (kernel_ulong_t) base_addr);
if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
tprints(" */");
return;
}
- PRINT_FIELD_XVAL_INDEX("{", info, op, ptrace_syscall_info_op,
- "PTRACE_SYSCALL_INFO_???");
+ PRINT_FIELD_XVAL("{", info, op, ptrace_syscall_info_op,
+ "PTRACE_SYSCALL_INFO_???");
if (fetch_size < offsetofend(struct ptrace_syscall_info, arch))
goto printed;
PRINT_FIELD_XVAL(", ", info, arch, audit_arch, "AUDIT_ARCH_???");
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
+ static const struct decode_nla_xlat_opts opts = {
.xlat = tun_device_types,
- .xlat_size = ARRAY_SIZE(tun_device_types) - 1,
- .xt = XT_INDEXED,
.dflt = "IFF_???",
.size = 1,
};
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
+ static const struct decode_nla_xlat_opts opts = {
.xlat = rtnl_ifla_xdp_attached_mode,
- .xlat_size = ARRAY_SIZE(rtnl_ifla_xdp_attached_mode) - 1,
- .xt = XT_INDEXED,
.dflt = "XDP_ATTACHED_???",
.size = 1,
};
print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
tfetch_mem, print_int32_array_member, NULL,
- PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
- | XLAT_STYLE_FMT_D,
- ARRSZ_PAIR(inet_devconf_indices) - 1,
- "IPV4_DEVCONF_???");
+ PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
+ inet_devconf_indices, "IPV4_DEVCONF_???");
return true;
}
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
- ARRSZ_PAIR(inet6_if_flags) - 1, "IF_???",
+ static const struct decode_nla_xlat_opts opts = {
+ inet6_if_flags, "IF_???",
.size = 4,
};
print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
tfetch_mem, print_int32_array_member, NULL,
- PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
- | XLAT_STYLE_FMT_D,
- ARRSZ_PAIR(inet6_devconf_indices) - 1,
- "DEVCONF_???");
+ PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
+ inet6_devconf_indices, "DEVCONF_???");
return true;
}
print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
tfetch_mem, print_uint64_array_member, NULL,
- PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
- | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_ip_stats) - 1,
- "IPSTATS_MIB_???");
+ PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+ snmp_ip_stats, "IPSTATS_MIB_???");
return true;
}
print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
tfetch_mem, print_uint64_array_member, NULL,
- PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
- | XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_icmp6_stats) - 1,
- "ICMP6_MIB_???");
+ PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
+ snmp_icmp6_stats, "ICMP6_MIB_???");
return true;
}
const unsigned int len,
const void *const opaque_data)
{
- const struct decode_nla_xlat_opts opts = {
- ARRSZ_PAIR(in6_addr_gen_mode) - 1, "IN6_ADDR_GEN_MODE_???",
- .xt = XT_INDEXED,
+ static const struct decode_nla_xlat_opts opts = {
+ in6_addr_gen_mode, "IN6_ADDR_GEN_MODE_???",
.size = 1,
};
if (!umoven_or_printaddr(tcp, addr + offset,
sizeof(ifinfo) - offset,
(char *) &ifinfo + offset)) {
- PRINT_FIELD_XVAL_SORTED_SIZED("", ifinfo, ifi_type,
- arp_hardware_types,
- arp_hardware_types_size,
- "ARPHRD_???");
+ PRINT_FIELD_XVAL("", ifinfo, ifi_type,
+ arp_hardware_types, "ARPHRD_???");
PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
iffflags, "IFF_???");
if (len < sizeof(num))
return false;
if (!umove_or_printaddr(tcp, addr, &num))
- printxval_search(routing_protocols, num, "RTPROT_???");
+ printxval(routing_protocols, num, "RTPROT_???");
return true;
}
break;
case SIOCSIFHWADDR:
case SIOCGIFHWADDR: {
- PRINT_FIELD_XVAL_SORTED_SIZED("ifr_hwaddr={", ifr->ifr_hwaddr,
- sa_family, arp_hardware_types,
- arp_hardware_types_size,
- "ARPHRD_???");
+ PRINT_FIELD_XVAL("ifr_hwaddr={", ifr->ifr_hwaddr, sa_family,
+ arp_hardware_types, "ARPHRD_???");
PRINT_FIELD_HWADDR_SZ(", ", ifr->ifr_hwaddr, sa_data,
sizeof(ifr->ifr_hwaddr.sa_data),
ifr->ifr_hwaddr.sa_family);
tprints(" /* ");
tprints("htons(");
- printxval_search_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
- "ETH_P_???", XLAT_STYLE_ABBREV);
+ printxval_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
+ "ETH_P_???", XLAT_STYLE_ABBREV);
tprints(")");
if (x_style == XLAT_STYLE_VERBOSE)
print_sll_protocol(sa_ll);
PRINT_FIELD_IFINDEX(", ", *sa_ll, sll_ifindex);
tprints(", sll_hatype=");
- printxval_search(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
+ printxval(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
tprints(", sll_pkttype=");
- printxval_index(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
+ printxval(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
tprintf(", sll_halen=%u", sa_ll->sll_halen);
if (sa_ll->sll_halen) {
const unsigned int oob_halen =
const struct sockaddr_hci *const hci = buf;
tprintf("hci_dev=htobs(%hu), hci_channel=",
btohs(hci->hci_dev));
- printxval_index(hci_channels, hci->hci_channel,
- "HCI_CHANNEL_???");
+ printxval(hci_channels, hci->hci_channel, "HCI_CHANNEL_???");
break;
}
case sizeof(struct sockaddr_sco): {
if (addrlen == sizeof(struct sockaddr_l2)) {
tprints(", l2_bdaddr_type=");
- printxval_index(bdaddr_types, l2->l2_bdaddr_type,
- "BDADDR_???");
+ printxval(bdaddr_types, l2->l2_bdaddr_type,
+ "BDADDR_???");
}
break;
const struct sockaddr *const sa = buf;
tprints("{sa_family=");
- printxval_index(addrfams, sa->sa_family, "AF_???");
+ printxval(addrfams, sa->sa_family, "AF_???");
if (addrlen > (int) SIZEOF_SA_FAMILY) {
tprints(", ");
static const char *
xlookup(const struct xlat *xlat, const uint64_t val)
{
- for (; xlat->str != NULL; xlat++)
- if (xlat->val == val)
- return xlat->str;
+ for (size_t i = 0; i < xlat->size; i++)
+ if (xlat->data[i].val == val)
+ return xlat->data[i].str;
return NULL;
}
static void
btrfs_test_read_ioctls(void)
{
- static const struct xlat btrfs_read_cmd[] = {
+ static const struct xlat_data btrfs_read_cmd[] = {
XLAT(BTRFS_IOC_BALANCE_PROGRESS),
XLAT(BTRFS_IOC_FS_INFO),
XLAT(BTRFS_IOC_GET_FEATURES),
static const unsigned int magic = 0xdeadbeef;
static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL;
-static struct xlat block_argless[] = {
+static struct xlat_data block_argless[] = {
XLAT(BLKRRPART),
XLAT(BLKFLSBUF),
#ifdef BLKTRACESTART
#endif
}
-static struct xlat rtc_argless[] = {
+static struct xlat_data rtc_argless[] = {
XLAT(RTC_AIE_OFF),
XLAT(RTC_PIE_ON),
XLAT(RTC_PIE_OFF),
printflags(const struct xlat *xlat, unsigned long long flags,
const char *const dflt)
{
- if (flags == 0 && xlat->val == 0 && xlat->str) {
- fputs(xlat->str, stdout);
+ if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
+ fputs(xlat->data->str, stdout);
return 1;
}
int n;
+ size_t i = 0;
char sep = 0;
- for (n = 0; xlat->str; xlat++) {
- if (xlat->val && (flags & xlat->val) == xlat->val) {
+ const struct xlat_data *xd = xlat->data;
+ for (n = 0; i < xlat->size; xd++, i++) {
+ if (!xd->str)
+ continue;
+
+ if (xd->val && (flags & xd->val) == xd->val) {
if (sep)
putc(sep, stdout);
else
sep = '|';
- fputs(xlat->str, stdout);
- flags &= ~xlat->val;
+ fputs(xd->str, stdout);
+ flags &= ~xd->val;
n++;
}
}
printxval(const struct xlat *xlat, unsigned long long val,
const char *const dflt)
{
- for (; xlat->str; xlat++) {
- if (xlat->val == val) {
- fputs(xlat->str, stdout);
+ const struct xlat_data *xd = xlat->data;
+
+ for (size_t i = 0; i < xlat->size; i++, xd++) {
+ if (!xd->str)
+ continue;
+
+ if (xd->val == val) {
+ fputs(xd->str, stdout);
return 1;
}
}
unsigned long pid =
(unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
uint64_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
- const struct xlat *xlat;
+ const struct xlat_data *xlat;
+ size_t i = 0;
+
+ for (xlat = resources->data; i < resources->size; ++xlat, ++i) {
+ if (!xlat->str)
+ continue;
- for (xlat = resources; xlat->str; ++xlat) {
unsigned long res = 0xfacefeed00000000ULL | xlat->val;
long rc = syscall(__NR_prlimit64, pid, res, 0, rlimit);
if (rc)
main(void)
{
kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
- const struct xlat *xlat;
+ const struct xlat_data *xlat;
+ size_t i = 0;
+
+ for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
+ if (!xlat->str)
+ continue;
- for (xlat = resources; xlat->str; ++xlat) {
unsigned long res = 0xfacefeed00000000ULL | xlat->val;
long rc = syscall(__NR_setrlimit, res, 0);
# if XLAT_RAW
static const char *
xlookup_uint(const struct xlat *xlat, const unsigned int val)
{
- for (; xlat->str != NULL; xlat++)
- if (xlat->val == val)
- return xlat->str;
+ for (size_t i = 0; i < xlat->size; i++)
+ if (xlat->data[i].val == val)
+ return xlat->data[i].str;
return NULL;
}
int
main(void)
{
- assert((unsigned) sc_min == socketcalls[0].val);
- assert((unsigned) sc_max == socketcalls[ARRAY_SIZE(socketcalls) - 2].val);
+ assert((unsigned) sc_min == socketcalls->data[0].val);
+ assert((unsigned) sc_max == socketcalls->data[socketcalls->size - 1].val);
const unsigned long *const args = tail_alloc(sizeof(*args) * 6);
efault = tail_alloc(1) + 1;
main(void)
{
kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
- const struct xlat *xlat;
+ const struct xlat_data *xlat;
+ size_t i;
+
+ for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
+ if (!xlat->str)
+ continue;
- for (xlat = resources; xlat->str; ++xlat) {
unsigned long res = 0xfacefeed00000000ULL | xlat->val;
long rc = syscall(NR_GETRLIMIT, res, 0);
if (rc && ENOSYS == errno)
print_statfs_type(const char *const prefix, const unsigned int magic)
{
fputs(prefix, stdout);
- unsigned int i;
- for (i = 0; i < ARRAY_SIZE(fsmagic); ++i)
- if (magic == fsmagic[i].val) {
- fputs(fsmagic[i].str, stdout);
+ for (unsigned int i = 0; i < fsmagic->size; ++i)
+ if (magic == fsmagic->data[i].val) {
+ fputs(fsmagic->data[i].str, stdout);
return;
}
printf("%#x", magic);
SYS_FUNC(getitimer)
{
if (entering(tcp)) {
- printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
- "ITIMER_???");
+ printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
tprints(", ");
} else {
print_itimerval(tcp, tcp->u_arg[1]);
SYS_FUNC(osf_getitimer)
{
if (entering(tcp)) {
- printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
- "ITIMER_???");
+ printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
tprints(", ");
} else {
print_itimerval32(tcp, tcp->u_arg[1]);
SYS_FUNC(setitimer)
{
if (entering(tcp)) {
- printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
- "ITIMER_???");
+ printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
tprints(", ");
print_itimerval(tcp, tcp->u_arg[1]);
tprints(", ");
SYS_FUNC(osf_setitimer)
{
if (entering(tcp)) {
- printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
- "ITIMER_???");
+ printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
tprints(", ");
print_itimerval32(tcp, tcp->u_arg[1]);
tprints(", ");
{
if (print_tx(tcp, addr))
return 0;
- tcp->auxstr = xlat_idx(adjtimex_state, ARRAY_SIZE(adjtimex_state) - 1,
- (kernel_ulong_t) tcp->u_rval);
+ tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
return RVAL_STR;
}
"MAKE_THREAD_CPUCLOCK" :
"MAKE_PROCESS_CPUCLOCK",
CPUCLOCK_PID(clockid));
- printxval_index(cpuclocknames,
- (unsigned int) clockid & CLOCKFD_MASK,
- "CPUCLOCK_???");
+ printxval(cpuclocknames, clockid & CLOCKFD_MASK,
+ "CPUCLOCK_???");
tprints(")");
}
tprints(" */");
} else
#endif
- printxval_index(clocknames, clockid, "CLOCK_???");
+ printxval(clocknames, clockid, "CLOCK_???");
}
static int
void *const opaque_data,
unsigned int flags,
const struct xlat *index_xlat,
- size_t index_xlat_size,
const char *index_dflt)
{
if (!start_addr) {
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);
+ printxval_ex(idx ? NULL : index_xlat, idx,
+ index_dflt, xlat_style);
}
tprints("] = ");
tprints(sprint_xlat_val(val, style));
}
+static int
+xlat_bsearch_compare(const void *a, const void *b)
+{
+ const uint64_t val1 = *(const uint64_t *) a;
+ const uint64_t val2 = ((const struct xlat_data *) b)->val;
+ return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
+}
+
const char *
xlookup(const struct xlat *xlat, const uint64_t val)
{
- static const struct xlat *pos;
+ static const struct xlat *x;
+ static size_t idx;
+ const struct xlat_data *e;
- if (xlat)
- pos = xlat;
+ if (xlat) {
+ x = xlat;
+ idx = 0;
+ }
+
+ if (!x || !x->data)
+ return NULL;
+
+ switch (x->type) {
+ case XT_NORMAL:
+ for (; idx < x->size; idx++)
+ if (x->data[idx].val == val)
+ return x->data[idx].str;
+ break;
+
+ case XT_SORTED:
+ e = bsearch((const void *) &val,
+ x->data + idx,
+ x->size - idx,
+ sizeof(x->data[0]),
+ xlat_bsearch_compare);
+ if (e) {
+ idx = e - x->data;
+ return e->str;
+ }
+ break;
+
+ case XT_INDEXED:
+ if (val < x->size) {
+ if (val == x->data[val].val)
+ return x->data[val].str;
+ if (x->data[val].val == 0)
+ break; /* a hole in the index */
+ error_func_msg("Unexpected xlat value %" PRIu64
+ " at index %" PRIu64 " (str %s)",
+ x->data[val].val, val,
+ x->data[val].str);
+ }
+ break;
+
+ default:
+ error_func_msg("Invalid xlat type: %#x", x->type);
+ }
- for (; pos->str != NULL; pos++)
- if (pos->val == val)
- return pos->str;
return NULL;
}
-static int
-xlat_bsearch_compare(const void *a, const void *b)
+static const char *
+xlat_search_eq_or_less(const struct xlat *xlat, uint64_t *val)
{
- const uint64_t val1 = *(const uint64_t *) a;
- const uint64_t val2 = ((const struct xlat *) b)->val;
- return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
+ const struct xlat_data *base = xlat->data;
+ const struct xlat_data *cur = xlat->data;
+ size_t nmemb = xlat->size;
+
+ for (; nmemb > 0; nmemb >>= 1) {
+ cur = base + (nmemb >> 1);
+
+ if (*val == cur->val)
+ return cur->str;
+
+ if (*val > cur->val) {
+ base = cur + 1;
+ nmemb--;
+ }
+ }
+
+ if (*val < cur->val) {
+ if (cur > xlat->data)
+ cur--;
+ else
+ return NULL;
+ }
+
+ *val = cur->val;
+ return cur->str;
}
const char *
-xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
+xlookup_le(const struct xlat *xlat, uint64_t *val)
{
- static const struct xlat *pos;
- static size_t memb_left;
+ if (!xlat || !xlat->data)
+ return NULL;
- if (xlat) {
- pos = xlat;
- memb_left = nmemb;
+ switch (xlat->type) {
+ case XT_SORTED:
+ return xlat_search_eq_or_less(xlat, val);
+
+#if 0 /* enable when used */
+ case XT_NORMAL: {
+ uint64_t best_hit = 0;
+ const char *str = NULL;
+
+ for (size_t idx = 0; idx < xlat->size; idx++) {
+ if (xlat->data[idx].val == *val)
+ return xlat->data[idx].str;
+
+ if (xlat->data[idx].val < *val
+ && xlat->data[idx].val > best_hit) {
+ best_hit = xlat->data[idx].val;
+ str = xlat->data[idx].str;
+ }
+ }
+
+ *val = best_hit;
+ return str;
}
- const struct xlat *e =
- bsearch((const void *) &val,
- pos, memb_left, sizeof(*pos), xlat_bsearch_compare);
+ case XT_INDEXED: {
+ size_t idx = *val;
- if (e) {
- memb_left -= e - pos;
- return e->str;
- } else {
+ if (idx >= xlat->size) {
+ if (!xlat->size)
+ return NULL;
+
+ idx = xlat->size - 1;
+ }
+
+ do {
+ if (idx == xlat->data[idx].val && xlat->data[idx].str) {
+ *val = idx;
+ return xlat->data[idx].str;
+ }
+ if (xlat->data[idx].val == 0)
+ continue; /* a hole in the index */
+ error_func_msg("Unexpected xlat value %" PRIu64
+ " at index %zu (str %s)",
+ xlat->data[idx].val, idx,
+ xlat->data[idx].str);
+ } while (idx--);
return NULL;
}
+#endif
+
+ default:
+ error_func_msg("Invalid xlat type: %#x", xlat->type);
+ }
+
+ return NULL;
}
/**
return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
}
-/**
- * Print entry in sorted struct xlat table, if it is there.
- *
- * @param xlat Pointer to an array of xlat values (not terminated with
- * XLAT_END).
- * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
- * if array is declared in the unit's scope and not
- * terminated with XLAT_END).
- * @param val Value to search literal representation for.
- * @param dflt String (abbreviated in comment syntax) which should be
- * emitted if no appropriate xlat value has been found.
- * @param style Style in which xlat value should be printed.
- * @param fn Search function.
- * @return 1 if appropriate xlat value has been found, 0
- * otherwise.
- */
-static int
-printxval_sized(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt, enum xlat_style style,
- const char *(* fn)(const struct xlat *, size_t, uint64_t))
-{
- style = get_xlat_style(style);
-
- if (xlat_verbose(style) == XLAT_STYLE_RAW) {
- print_xlat_val(val, style);
- return 0;
- }
-
- const char *s = fn(xlat, xlat_size, val);
-
- if (s) {
- if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
- print_xlat_val(val, style);
- tprints_comment(s);
- } else {
- tprints(s);
- }
- return 1;
- }
-
- print_xlat_val(val, style);
- tprints_comment(dflt);
-
- return 0;
-}
-
-int
-printxval_searchn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt, enum xlat_style style)
-{
- return printxval_sized(xlat, xlat_size, val, dflt, style,
- xlat_search);
-}
-
-const char *
-xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val)
-{
- static const struct xlat *pos;
- static size_t memb_left;
-
- if (xlat) {
- pos = xlat;
- memb_left = nmemb;
- }
-
- if (val >= memb_left)
- return NULL;
-
- if (val != pos[val].val) {
- if (pos[val].val == 0)
- return NULL; /* a hole in the index */
-
- error_func_msg("Unexpected xlat value %" PRIu64
- " at index %" PRIu64,
- pos[val].val, val);
- return NULL;
- }
-
- return pos[val].str;
-}
-
-int
-printxval_indexn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt, enum xlat_style style)
-{
- return printxval_sized(xlat, xlat_size, val, dflt, style, xlat_idx);
-}
-
/*
* Interpret `xlat' as an array of flags.
* Print to static string the entries whose bits are on in `flags'
return outstr;
}
- if (flags == 0 && xlat->val == 0 && xlat->str) {
+ if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
if (sep)
*outptr++ = sep;
if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
outptr = xappendstr(outstr, outptr, "0 /* %s */",
- xlat->str);
+ xlat->data->str);
} else {
- strcpy(outptr, xlat->str);
+ strcpy(outptr, xlat->data->str);
}
return outstr;
sprint_xlat_val(flags, style));
}
- for (; flags && xlat->str; xlat++) {
- if (xlat->val && (flags & xlat->val) == xlat->val) {
+ for (size_t idx = 0; flags && idx < xlat->size; idx++) {
+ if (xlat->data[idx].val && xlat->data[idx].str
+ && (flags & xlat->data[idx].val) == xlat->data[idx].val) {
if (sep) {
*outptr++ = sep;
} else if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
outptr = stpcpy(outptr, " /* ");
}
- outptr = stpcpy(outptr, xlat->str);
+ outptr = stpcpy(outptr, xlat->data[idx].str);
found = 1;
sep = '|';
- flags &= ~xlat->val;
+ flags &= ~xlat->data[idx].val;
}
}
va_start(args, xlat);
for (; xlat; xlat = va_arg(args, const struct xlat *)) {
- for (; (flags || !n) && xlat->str; ++xlat) {
- if ((flags == xlat->val) ||
- (xlat->val && (flags & xlat->val) == xlat->val)) {
+ for (size_t idx = 0; (flags || !n) && idx < xlat->size; ++idx) {
+ uint64_t v = xlat->data[idx].val;
+ if (xlat->data[idx].str
+ && ((flags == v) || (v && (flags & v) == v))) {
if (xlat_verbose(style) == XLAT_STYLE_VERBOSE
&& !flags)
tprints("0");
tprintf("%s%s",
- (n++ ? "|" : init_sep), xlat->str);
- flags &= ~xlat->val;
+ (n++ ? "|" : init_sep),
+ xlat->data[idx].str);
+ flags &= ~v;
}
if (!flags)
break;
tprints_comment(str);
}
}
-
-void
-printxval_dispatch_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
- const char *dflt, enum xlat_type xt,
- enum xlat_style style)
-{
- switch (xt) {
- case XT_NORMAL:
- printxvals_ex(val, dflt, style, xlat, NULL);
- break;
-
- case XT_SORTED:
- printxval_searchn_ex(xlat, xlat_size, val, dflt, style);
- break;
-
- case XT_INDEXED:
- printxval_indexn_ex(xlat, xlat_size, val, dflt, style);
- break;
- }
-}
# define XLAT_STYLE_MASK ((1 << XLAT_STYLE_SPEC_BITS) - 1)
};
-struct xlat {
+struct xlat_data {
uint64_t val;
const char *str;
};
+struct xlat {
+ const struct xlat_data *data;
+ uint32_t size;
+ enum xlat_type type;
+};
+
# define XLAT(val) { (unsigned)(val), #val }
# define XLAT_PAIR(val, str) { (unsigned)(val), str }
# define XLAT_TYPE(type, val) { (type)(val), #val }
+#value_indexed
TPACKET_V1 0
TPACKET_V2 1
TPACKET_V3 2
-/* sort -k2,2g */
+#sorted sort -k2,2g
ARPHRD_NETROM 0
ARPHRD_ETHER 1
ARPHRD_EETHER 2
-/* sorted */
+#sorted
/* Those are pulled from include/net/ax25.h, they should be part of UAPI */
AX25_P_ROSE 0x01
AX25_P_VJCOMP 0x06 /* Compressed TCP/IP packet */
-/* sort -k2,2 */
+#sorted sort -k2,2
L2CAP_CID_SIGNALING 0x0001
L2CAP_CID_CONN_LESS 0x0002
L2CAP_CID_A2MP 0x0003
-/* sort -k2,2 */
+#sorted sort -k2,2
L2CAP_PSM_SDP 0x0001
L2CAP_PSM_RFCOMM 0x0003
L2CAP_PSM_3DSP 0x0021
-/* sort -k2,2 */
+#sorted sort -k2,2
ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
-/* sort -k2,2 */
+#sorted sort -k2,2
FF_RUMBLE 0x50
FF_PERIODIC 0x51
FF_CONSTANT 0x52
-/* sort -k2,2 */
+#sorted sort -k2,2
{ 0x0000002f, "QNX4_SUPER_MAGIC" },
{ 0x00000187, "AUTOFS_SUPER_MAGIC" },
{ 0x00001373, "DEVFS_SUPER_MAGIC" },
local mpers="${0%/*}/../mpers_xlat.h"
local decl="extern const struct xlat ${name}[];"
local in_defs= in_mpers=
+ local xlat_type="XT_NORMAL"
value_indexed=0
'#val_type '*)
# to be processed during 2nd pass
;;
+ '#sorted'|'#sorted '*)
+ xlat_type="XT_SORTED"
+ ;;
'#value_indexed')
value_indexed=1
+ xlat_type="XT_INDEXED"
;;
'#'*)
echo "${line}"
# else
- # if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
- static
- # endif
EOF
else
cat <<-EOF
# else
- static
EOF
fi
- echo "const struct xlat ${name}[] = {"
+ echo "static const struct xlat_data ${name}_xdata[] = {"
unconditional= val_type=
# 2nd pass: output everything.
'#unconditional')
unconditional=1
;;
+ '#sorted'|'#sorted '*)
+ ;;
'#value_indexed')
;;
'#val_type '*)
;;
esac
done < "${input}"
- echo ' XLAT_END'
+ echo '};'
+
+ if [ -n "$in_defs" ]; then
+ :
+ elif [ -n "$in_mpers" ]; then
+ cat <<-EOF
+ # if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
+ static
+ # endif
+ EOF
+ else
+ cat <<-EOF
+ static
+ EOF
+ fi
cat <<-EOF
- };
+ const struct xlat ${name}[1] = { {
+ .data = ${name}_xdata,
+ .size = ARRAY_SIZE(${name}_xdata),
+ .type = ${xlat_type},
+ } };
# endif /* !IN_MPERS */
-/* sort -k2,2n */
+#sorted sort -k2,2n
HW_BREAKPOINT_EMPTY 0
HW_BREAKPOINT_R 1
HW_BREAKPOINT_W 2
-/* sort -k4,4g */
+#sorted sort -k4,4g
IFF_UP (1 << 0)
IFF_BROADCAST (1 << 1)
IFF_DEBUG (1 << 2)
-/* sort -k2,2g */
+#sorted sort -k2,2g
IF_RS_SENT 0x10
IF_RA_RCVD 0x20
IF_RA_MANAGED 0x40
-/* sort -k2,2n */
+#sorted sort -k2,2n
IPPROTO_IP 0
IPPROTO_ICMP 1
IPPROTO_IGMP 2
-/* sort -k2,2g */
+#sorted sort -k2,2g
IPC_RMID 0
IPC_SET 1
IPC_STAT 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_COUNT_HW_CACHE_L1D 0
PERF_COUNT_HW_CACHE_L1I 1
PERF_COUNT_HW_CACHE_LL 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_COUNT_HW_CACHE_OP_READ 0
PERF_COUNT_HW_CACHE_OP_WRITE 1
PERF_COUNT_HW_CACHE_OP_PREFETCH 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_COUNT_HW_CACHE_RESULT_ACCESS 0
PERF_COUNT_HW_CACHE_RESULT_MISS 1
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_COUNT_HW_CPU_CYCLES 0
PERF_COUNT_HW_INSTRUCTIONS 1
PERF_COUNT_HW_CACHE_REFERENCES 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_COUNT_SW_CPU_CLOCK 0
PERF_COUNT_SW_TASK_CLOCK 1
PERF_COUNT_SW_PAGE_FAULTS 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
PERF_TYPE_HARDWARE 0
PERF_TYPE_SOFTWARE 1
PERF_TYPE_TRACEPOINT 2
-/* sort -k2,2n */
+#sorted sort -k2,2n
RTPROT_UNSPEC 0
RTPROT_REDIRECT 1
RTPROT_KERNEL 2
-/* sort -k2,2g */
+#sorted sort -k2,2g
IPC_RMID 0
IPC_SET 1
IPC_STAT 2
-/* sort -k2,2g */
+#sorted sort -k2,2g
IPC_RMID 0
IPC_SET 1
IPC_STAT 2
-/* sorted */
+#sorted
SMC_CLC_DECL_MEM 0x01010000
SMC_CLC_DECL_TIMEOUT_CL 0x02010000
SMC_CLC_DECL_TIMEOUT_AL 0x02020000
-/* sorted */
+#sorted
AX25_WINDOW 1
AX25_T1 2
AX25_N2 3
-/* sort -k2,2n */
+#sorted sort -k2,2n
BT_SECURITY 4
BT_DEFER_SETUP 7
BT_FLUSHABLE 8
-/* sort -k2,2n */
+#sorted sort -k2,2n
DCCP_SOCKOPT_PACKET_SIZE 1
DCCP_SOCKOPT_SERVICE 2
DCCP_SOCKOPT_CHANGE_L 3
-/* sort -k2,2n */
+#sorted sort -k2,2n
TIPC_IMPORTANCE 127
TIPC_SRC_DROPPABLE 128
TIPC_DEST_DROPPABLE 129
-/* sort -k2,2n */
+#sorted sort -k2,2n
SOL_IP 0
#if !(defined __alpha__ || defined __hppa__ || defined __mips__ || defined __sparc__)
SOL_SOCKET 1
-/* sort -k2,2 */
+#sorted sort -k2,2
V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */
V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */
V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
V4L2_SDR_FMT_PCU20BE v4l2_fourcc('P', 'C', '2', '0') /* planar complex u20be */
V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2') /* real u12le */
V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */