Browse Source

Add xlat description structure

Rename struct xlat to struct xlat_data and make struct xlat an xlat
descriptor that contains various information about xlat.
So far it's the type and the number of items.

As a result, xlookup/printxval now have enough information for handling
xlat depending on its type, so *index/*_search API is not needed any
longer.

* xlat.h (struct xlat_data): Rename from struct xlat.
(struct xlat): New type definition.
* xlat.c (xlat_search, printxval_sized, printxval_searchn_ex, xlat_idx,
printxval_indexn_ex, printxval_dispatch_ex): Remove.
(xlookup): Handle xlat_data based on xlat type.
(xlat_search_eq_or_less, xlookup_le): New functions.
(sprintflags_ex, printflags_ex): Update.
* xlat/gen.sh (gen_header): Add handling for #sorted, generate new
struct xlat descriptor.
* defs.h (arp_hardware_types_size, ethernet_protocols_size,
inet_protocols_size, evdev_abs_size, xlat_search, xlat_idx,
printxval_searchn_ex, printxval_searchn, printxval_search,
printxval_search_ex, printxval_indexn_ex, printxval_indexn,
printxval_index, printxval_index_ex, printxval_dispatch_ex,
printxval_dispatch): Remove.
(enum xlat_style_private_flag_bits): Remove PAF_INDEX_XLAT_SORTED_BIT
and PAF_INDEX_XLAT_VALUE_INDEXED_BIT.
(enum xlat_style_private_flag): Remove PAF_INDEX_XLAT_SORTED and
PAF_INDEX_XLAT_VALUE_INDEXED.
(print_array_ex): Remove index_xlat_size argument.
(xlookup_le): New declaration.
(printxval_ex): New macro.
* dyxlat.c (struct dyxlat): Remove used field (use xlat.size instead),
embed struct xlat, add pointer to struct xlat_data.
(MARK_END): Remove.
(dyxlat_alloc, dyxlat_free, dyxlat_get, dyxlat_add_pair): Update in
accordance with the structure changes.
* evdev.c (evdev_abs_size): Remove.
(keycode_ioctl): Use printxval instead of printxval_index.
(decode_bitset): Remove.
(decode_bitset_): Rename to decode_bitset, remove decode_nr_size and xt
arguments, call printxval instead of printxval_dispatch.
(bit_ioctl, evdev_read_ioctl): Do not pass xlat type to decode_bitset.
* fsconfig.c (SYS_FUNC(fsconfig)): Use printxval instead of
printxval_index.
* print_fields.h (PRINT_FIELD_XVAL_SORTED_SIZED,
PRINT_FIELD_XVAL_INDEX): Remove.
* nlattr.h (struct decode_nla_xlat_opts): Remove xlat_size and xt
fields.
* nlattr.c (decode_nla_meminfo): Do not pass
PAF_INDEX_XLAT_VALUE_INDEXED flag and netlink_sk_meminfo_indices size
in a print_array_ex call.
(decode_nla_xval): Call printxval_ex instead of printxval_dispatch_ex.
(decode_nla_ether_proto, decode_nla_ip_proto): Do not pass xlat_size and
xt fields in opts.
(decode_nla_flags): Remove XT_INDEXED unsupported warning.
* process.c (struct_user_offsets_data): Rename from struct_user_offsets,
change type to struct xlat_data[].
(struct_user_offsets): New xlat description.
(print_user_offset_addr): Rewrite using xlookup_le.
* util.c (print_array_ex): Remove index_xlat_size argument, simply call
printxval_ex for index printing.
* aio.c (tprint_lio_opcode): Use printxval_ex instead of
printxval_indexn_ex.
* bpf.c: Use printxval instead of printxval_index; use PRINT_FIELD_XVAL
instead of PRINT_FIELD_XVAL_INDEX.
* bpf_filter.c (print_bpf_filter_code): Use printxval instead of
printxval_index.
* ioctl.c (evdev_decode_number): Use printxval instead of
printxval_indexn.
* kvm.c (kvm_ioctl_decode_check_extension): Use printxval64 instead of
printxval_index.
(kvm_ioctl_run_attach_auxstr): Use xlookup instead of xlat_idx.
* net.c: Use printxval instead of printxval_search/printxval_index, use
printxval_ex instead of printxval_searchn_ex.
* netlink.c (get_fd_nl_family): Rewrite using xlat descriptor structure.
* netlink_packet_diag.c (decode_packet_diag_msg): Use PRINT_FIELD_XVAL
instead of PRINT_FIELD_XVAL_SORTED_SIZED.
* netlink_smc_diag.c (decode_smc_diag_shutdown): Remove ARRSZ_PAIR
wrapper.
(decode_smc_diag_fallback): Use printxval_ex instead of
printxval_search_ex.
(decode_smc_diag_msg): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_INDEX.
* print_statfs.c (print_statfs_type): Use printxval instead of
printxval_search.
* ptrace_syscall_info.c (print_ptrace_syscall_info): Use
PRINT_FIELD_XVAL instead of PRINT_FIELD_XVAL_INDEX.
* rtnl_link.c (decode_ifla_inet6_flags, decode_ifla_inet6_agm):
Likewise.
(decode_nla_tun_type, decode_ifla_xdp_attached): Remove xlat_size,
xt fields.
(decode_ifla_inet_conf, decode_ifla_inet6_conf, decode_ifla_inet6_stats,
decode_ifla_inet6_icmp6_stats): Remove PAF_INDEX_XLAT_VALUE_INDEXED flag
and ARRSZ_PAIR wrapper in print_array_ex calls.
(decode_ifinfomsg): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_SORTED_SIZED.
* rtnl_route.c (decode_nla_rt_proto): Use printxval instead of
printxval_search.
* sock.c (print_ifreq): Use PRINT_FIELD_XVAL instead of
PRINT_FIELD_XVAL_SORTED_SIZED.
* sockaddr.c (print_sockaddr_data_ll, print_sockaddr_data_bt,
print_sockaddr): Use printxval instead of printxval_search and
printxval_index.
* time.c (getitimer, osf_getitimer, setitimer, osf_setitimer,
printclockname): Use printxval instead of printxval_index.
(do_adjtimex): Use xlookup instead of xlat_idx.
* tests/btrfs.c: Update xlat handling, use struct xlat_data instead of
struct xlat for XLAT() arrays.
* tests/ioctl_block.c: Likewise.
* tests/ioctl_rtc.c: Likewise.
* tests/printflags.c: Likewise.
* tests/printxval.c: Likewise.
* tests/prlimit64.c: Likewise.
* tests/setrlimit.c: Likewise.
* tests/socketcall.c: Likewise.
* tests/xgetrlimit.c: Likewise.
* tests/xstatfsx.c: Likewise.
* xlat/af_packet_versions.in: Add #value_indexed.
* xlat/arp_hardware_types.in: Add #sorted.
* xlat/ax25_protocols.in: Likewise.
* xlat/bluetooth_l2_cid.in: Likewise.
* xlat/bluetooth_l2_psm.in: Likewise.
* xlat/ethernet_protocols.in: Likewise.
* xlat/evdev_ff_types.in: Likewise.
* xlat/fsmagic.in: Likewise.
* xlat/hw_breakpoint_type.in: Likewise.
* xlat/iffflags.in: Likewise.
* xlat/inet6_if_flags.in: Likewise.
* xlat/inet_protocols.in: Likewise.
* xlat/msgctl_flags.in: Likewise.
* xlat/perf_hw_cache_id.in: Likewise.
* xlat/perf_hw_cache_op_id.in: Likewise.
* xlat/perf_hw_cache_op_result_id.in: Likewise.
* xlat/perf_hw_id.in: Likewise.
* xlat/perf_sw_ids.in: Likewise.
* xlat/perf_type_id.in: Likewise.
* xlat/routing_protocols.in: Likewise.
* xlat/semctl_flags.in: Likewise.
* xlat/shmctl_flags.in: Likewise.
* xlat/smc_decl_codes.in: Likewise.
* xlat/sock_ax25_options.in: Likewise.
* xlat/sock_bluetooth_options.in: Likewise.
* xlat/sock_dccp_options.in: Likewise.
* xlat/sock_tipc_options.in: Likewise.
* xlat/socketlayers.in: Likewise.
* xlat/v4l2_control_classes.in: Likewise.
* xlat/v4l2_pix_fmts.in: Likewise.
* xlat/v4l2_sdr_fmts.in: Likewise.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
Eugene Syromyatnikov 1 year ago
parent
commit
60a75f19e6
69 changed files with 450 additions and 547 deletions
  1. 1
    2
      aio.c
  2. 15
    17
      bpf.c
  3. 2
    4
      bpf_filter.c
  4. 4
    76
      defs.h
  5. 25
    30
      dyxlat.c
  6. 23
    32
      evdev.c
  7. 1
    1
      fsconfig.c
  8. 2
    4
      ioctl.c
  9. 2
    3
      kvm.c
  10. 27
    29
      net.c
  11. 7
    4
      netlink.c
  12. 2
    4
      netlink_packet_diag.c
  13. 7
    8
      netlink_smc_diag.c
  14. 5
    16
      nlattr.c
  15. 0
    2
      nlattr.h
  16. 0
    17
      print_fields.h
  17. 1
    1
      print_statfs.c
  18. 21
    17
      process.c
  19. 2
    2
      ptrace_syscall_info.c
  20. 16
    29
      rtnl_link.c
  21. 1
    1
      rtnl_route.c
  22. 2
    4
      sock.c
  23. 8
    9
      sockaddr.c
  24. 4
    4
      tests/btrfs.c
  25. 1
    1
      tests/ioctl_block.c
  26. 1
    1
      tests/ioctl_rtc.c
  27. 11
    6
      tests/printflags.c
  28. 8
    3
      tests/printxval.c
  29. 6
    2
      tests/prlimit64.c
  30. 6
    2
      tests/setrlimit.c
  31. 5
    5
      tests/socketcall.c
  32. 6
    2
      tests/xgetrlimit.c
  33. 3
    4
      tests/xstatfsx.c
  34. 8
    14
      time.c
  35. 2
    9
      util.c
  36. 149
    144
      xlat.c
  37. 7
    1
      xlat.h
  38. 1
    0
      xlat/af_packet_versions.in
  39. 1
    1
      xlat/arp_hardware_types.in
  40. 1
    1
      xlat/ax25_protocols.in
  41. 1
    1
      xlat/bluetooth_l2_cid.in
  42. 1
    1
      xlat/bluetooth_l2_psm.in
  43. 1
    1
      xlat/ethernet_protocols.in
  44. 1
    1
      xlat/evdev_ff_types.in
  45. 1
    1
      xlat/fsmagic.in
  46. 28
    7
      xlat/gen.sh
  47. 1
    1
      xlat/hw_breakpoint_type.in
  48. 1
    1
      xlat/iffflags.in
  49. 1
    1
      xlat/inet6_if_flags.in
  50. 1
    1
      xlat/inet_protocols.in
  51. 1
    1
      xlat/msgctl_flags.in
  52. 1
    1
      xlat/perf_hw_cache_id.in
  53. 1
    1
      xlat/perf_hw_cache_op_id.in
  54. 1
    1
      xlat/perf_hw_cache_op_result_id.in
  55. 1
    1
      xlat/perf_hw_id.in
  56. 1
    1
      xlat/perf_sw_ids.in
  57. 1
    1
      xlat/perf_type_id.in
  58. 1
    1
      xlat/routing_protocols.in
  59. 1
    1
      xlat/semctl_flags.in
  60. 1
    1
      xlat/shmctl_flags.in
  61. 1
    1
      xlat/smc_decl_codes.in
  62. 1
    1
      xlat/sock_ax25_options.in
  63. 1
    1
      xlat/sock_bluetooth_options.in
  64. 1
    1
      xlat/sock_dccp_options.in
  65. 1
    1
      xlat/sock_tipc_options.in
  66. 1
    1
      xlat/socketlayers.in
  67. 1
    1
      xlat/v4l2_control_classes.in
  68. 1
    1
      xlat/v4l2_pix_fmts.in
  69. 1
    1
      xlat/v4l2_sdr_fmts.in

+ 1
- 2
aio.c View File

@@ -60,8 +60,7 @@ tprint_lio_opcode(unsigned int cmd)
60 60
 		[IOCB_CMD_PWRITEV]	= SUB_VECTOR,
61 61
 	};
62 62
 
63
-	printxval_indexn_ex(ARRSZ_PAIR(aio_cmds) - 1, cmd, "IOCB_CMD_???",
64
-			    XLAT_STYLE_FMT_U);
63
+	printxval_ex(aio_cmds, cmd, "IOCB_CMD_???", XLAT_STYLE_FMT_U);
65 64
 
66 65
 	return cmd < ARRAY_SIZE(subs) ? subs[cmd] : SUB_NONE;
67 66
 }

+ 15
- 17
bpf.c View File

@@ -131,9 +131,9 @@ print_ebpf_insn(struct tcb * const tcp, void * const elem_buf,
131 131
 
132 132
 	/* We can't use PRINT_FIELD_XVAL on bit fields */
133 133
 	tprints(", dst_reg=");
134
-	printxval_index(ebpf_regs, insn->dst_reg, "BPF_REG_???");
134
+	printxval(ebpf_regs, insn->dst_reg, "BPF_REG_???");
135 135
 	tprints(", src_reg=");
136
-	printxval_index(ebpf_regs, insn->src_reg, "BPF_REG_???");
136
+	printxval(ebpf_regs, insn->src_reg, "BPF_REG_???");
137 137
 
138 138
 	PRINT_FIELD_D(", ", *insn, off);
139 139
 	PRINT_FIELD_X(", ", *insn, imm);
@@ -159,8 +159,8 @@ print_ebpf_prog(struct tcb *const tcp, const uint64_t addr, const uint32_t len)
159 159
 
160 160
 BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
161 161
 {
162
-	PRINT_FIELD_XVAL_INDEX("{", attr, map_type, bpf_map_types,
163
-			       "BPF_MAP_TYPE_???");
162
+	PRINT_FIELD_XVAL("{", attr, map_type, bpf_map_types,
163
+			 "BPF_MAP_TYPE_???");
164 164
 	PRINT_FIELD_U(", ", attr, key_size);
165 165
 	PRINT_FIELD_U(", ", attr, value_size);
166 166
 	PRINT_FIELD_U(", ", attr, max_entries);
@@ -241,8 +241,8 @@ BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)
241 241
 	PRINT_FIELD_FD("{", attr, map_fd, tcp);
242 242
 	PRINT_FIELD_ADDR64(", ", attr, key);
243 243
 	PRINT_FIELD_ADDR64(", ", attr, value);
244
-	PRINT_FIELD_XVAL_INDEX(", ", attr, flags, bpf_map_update_elem_flags,
245
-			       "BPF_???");
244
+	PRINT_FIELD_XVAL(", ", attr, flags, bpf_map_update_elem_flags,
245
+			 "BPF_???");
246 246
 }
247 247
 END_BPF_CMD_DECODER(RVAL_DECODED)
248 248
 
@@ -269,8 +269,8 @@ END_BPF_CMD_DECODER(RVAL_DECODED)
269 269
 
270 270
 BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
271 271
 {
272
-	PRINT_FIELD_XVAL_INDEX("{", attr, prog_type, bpf_prog_types,
273
-			       "BPF_PROG_TYPE_???");
272
+	PRINT_FIELD_XVAL("{", attr, prog_type, bpf_prog_types,
273
+			 "BPF_PROG_TYPE_???");
274 274
 	PRINT_FIELD_U(", ", attr, insn_cnt);
275 275
 	tprints(", insns=");
276 276
 	print_ebpf_prog(tcp, attr.insns, attr.insn_cnt);
@@ -362,8 +362,7 @@ BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)
362 362
 {
363 363
 	PRINT_FIELD_FD("{", attr, target_fd, tcp);
364 364
 	PRINT_FIELD_FD(", ", attr, attach_bpf_fd, tcp);
365
-	PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
366
-			       "BPF_???");
365
+	PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
367 366
 	PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
368 367
 			  "BPF_F_???");
369 368
 }
@@ -372,8 +371,7 @@ END_BPF_CMD_DECODER(RVAL_DECODED)
372 371
 BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
373 372
 {
374 373
 	PRINT_FIELD_FD("{", attr, target_fd, tcp);
375
-	PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
376
-			       "BPF_???");
374
+	PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type, "BPF_???");
377 375
 }
378 376
 END_BPF_CMD_DECODER(RVAL_DECODED)
379 377
 
@@ -826,8 +824,8 @@ BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)
826 824
 
827 825
 	if (entering(tcp)) {
828 826
 		PRINT_FIELD_FD("{query={", attr, target_fd, tcp);
829
-		PRINT_FIELD_XVAL_INDEX(", ", attr, attach_type, bpf_attach_type,
830
-				       "BPF_???");
827
+		PRINT_FIELD_XVAL(", ", attr, attach_type, bpf_attach_type,
828
+				 "BPF_???");
831 829
 		PRINT_FIELD_FLAGS(", ", attr, query_flags, bpf_query_flags,
832 830
 				  "BPF_F_QUERY_???");
833 831
 		PRINT_FIELD_FLAGS(", ", attr, attach_flags, bpf_attach_flags,
@@ -909,8 +907,8 @@ BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY)
909 907
 	print_big_u64_addr(attr.buf);
910 908
 	printstr_ex(tcp, attr.buf, buf_len, QUOTE_0_TERMINATED);
911 909
 	PRINT_FIELD_U(", ", attr, prog_id);
912
-	PRINT_FIELD_XVAL_INDEX(", ", attr, fd_type, bpf_task_fd_type,
913
-			       "BPF_FD_TYPE_???");
910
+	PRINT_FIELD_XVAL(", ", attr, fd_type, bpf_task_fd_type,
911
+			 "BPF_FD_TYPE_???");
914 912
 	PRINT_FIELD_X(", ", attr, probe_offset);
915 913
 	PRINT_FIELD_X(", ", attr, probe_addr);
916 914
 
@@ -952,7 +950,7 @@ SYS_FUNC(bpf)
952 950
 	int rc = RVAL_DECODED;
953 951
 
954 952
 	if (entering(tcp)) {
955
-		printxval_index(bpf_commands, cmd, "BPF_???");
953
+		printxval(bpf_commands, cmd, "BPF_???");
956 954
 		tprints(", ");
957 955
 	}
958 956
 

+ 2
- 4
bpf_filter.c View File

@@ -36,10 +36,8 @@ print_bpf_filter_code(const uint16_t code, bool extended)
36 36
 	const struct xlat *mode = extended ? ebpf_mode : bpf_mode;
37 37
 	uint16_t i = code & ~BPF_CLASS(code);
38 38
 
39
-	if (extended)
40
-		printxval_index(ebpf_class, BPF_CLASS(code), "BPF_???");
41
-	else
42
-		printxval_index(bpf_class, BPF_CLASS(code), "BPF_???");
39
+	printxval(extended ? ebpf_class : bpf_class, BPF_CLASS(code),
40
+		  "BPF_???");
43 41
 	switch (BPF_CLASS(code)) {
44 42
 	case BPF_ST:
45 43
 	case BPF_STX:

+ 4
- 76
defs.h View File

@@ -310,30 +310,13 @@ extern const struct_sysent stub_sysent;
310 310
 # include "xlat.h"
311 311
 
312 312
 extern const struct xlat addrfams[];
313
-
314
-/** Protocol hardware identifiers array, sorted, defined in sockaddr.c. */
315 313
 extern const struct xlat arp_hardware_types[];
316
-/** Protocol hardware identifiers array size without terminating record. */
317
-extern const size_t arp_hardware_types_size;
318
-
319 314
 extern const struct xlat at_flags[];
320 315
 extern const struct xlat clocknames[];
321 316
 extern const struct xlat dirent_types[];
322
-
323
-/** Ethernet protocols list, sorted, defined in sockaddr.c. */
324 317
 extern const struct xlat ethernet_protocols[];
325
-/** Ethernet protocols array size without terminating record. */
326
-extern const size_t ethernet_protocols_size;
327
-
328
-/** IP protocols list, sorted, defined in net.c. */
329 318
 extern const struct xlat inet_protocols[];
330
-/** IP protocols array size without terminating record. */
331
-extern const size_t inet_protocols_size;
332
-
333 319
 extern const struct xlat evdev_abs[];
334
-/** Number of elements in evdev_abs array without the terminating record. */
335
-extern const size_t evdev_abs_size;
336
-
337 320
 extern const struct xlat audit_arch[];
338 321
 extern const struct xlat evdev_ev[];
339 322
 extern const struct xlat iffflags[];
@@ -628,8 +611,7 @@ extern unsigned long getfdinode(struct tcb *, int);
628 611
 extern enum sock_proto getfdproto(struct tcb *, int);
629 612
 
630 613
 extern const char *xlookup(const struct xlat *, const uint64_t);
631
-extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
632
-extern const char *xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val);
614
+extern const char *xlookup_le(const struct xlat *, uint64_t *);
633 615
 
634 616
 struct dyxlat;
635 617
 struct dyxlat *dyxlat_alloc(size_t nmemb);
@@ -701,46 +683,8 @@ extern int printxvals_ex(uint64_t val, const char *dflt,
701 683
 	ATTRIBUTE_SENTINEL;
702 684
 # define printxvals(val_, dflt_, ...) \
703 685
 	printxvals_ex((val_), (dflt_), XLAT_STYLE_DEFAULT, __VA_ARGS__)
704
-
705
-extern int printxval_searchn_ex(const struct xlat *, size_t xlat_size,
706
-				uint64_t val, const char *dflt,
707
-				enum xlat_style);
708
-
709
-static inline int
710
-printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
711
-		  const char *dflt)
712
-{
713
-	return printxval_searchn_ex(xlat, xlat_size, val, dflt,
714
-				    XLAT_STYLE_DEFAULT);
715
-}
716
-
717
-/**
718
- * Wrapper around printxval_searchn that passes ARRAY_SIZE - 1
719
- * as the array size, as all arrays are XLAT_END-terminated and
720
- * printxval_searchn expects a size without the terminating record.
721
- */
722
-# define printxval_search(xlat__, val__, dflt__) \
723
-	printxval_searchn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
724
-# define printxval_search_ex(xlat__, val__, dflt__, style__) \
725
-	printxval_searchn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
726
-			     (dflt__), (style__))
727
-
728
-extern int printxval_indexn_ex(const struct xlat *, size_t xlat_size,
729
-			       uint64_t val, const char *dflt, enum xlat_style);
730
-
731
-static inline int
732
-printxval_indexn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
733
-		 const char *dflt)
734
-{
735
-	return printxval_indexn_ex(xlat, xlat_size, val, dflt,
736
-				   XLAT_STYLE_DEFAULT);
737
-}
738
-
739
-# define printxval_index(xlat__, val__, dflt__) \
740
-	printxval_indexn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
741
-# define printxval_index_ex(xlat__, val__, dflt__, style__) \
742
-	printxval_indexn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
743
-			    (dflt__), (style__))
686
+# define printxval_ex(xlat_, val_, dflt_, style_) \
687
+	printxvals_ex((val_), (dflt_), (style_), (xlat_), NULL)
744 688
 
745 689
 extern int sprintxval_ex(char *buf, size_t size, const struct xlat *,
746 690
 			 unsigned int val, const char *dflt, enum xlat_style);
@@ -752,22 +696,9 @@ sprintxval(char *buf, size_t size, const struct xlat *xlat, unsigned int val,
752 696
 	return sprintxval_ex(buf, size, xlat, val, dflt, XLAT_STYLE_DEFAULT);
753 697
 }
754 698
 
755
-extern void printxval_dispatch_ex(const struct xlat *, size_t xlat_size,
756
-				  uint64_t val, const char *dflt,
757
-				  enum xlat_type, enum xlat_style);
758
-static inline void
759
-printxval_dispatch(const struct xlat *xlat, size_t xlat_size, uint64_t val,
760
-		   const char *dflt, enum xlat_type xt)
761
-{
762
-	return printxval_dispatch_ex(xlat, xlat_size, val, dflt, xt,
763
-				     XLAT_STYLE_DEFAULT);
764
-}
765
-
766 699
 enum xlat_style_private_flag_bits {
767 700
 	/* print_array */
768 701
 	PAF_PRINT_INDICES_BIT = XLAT_STYLE_SPEC_BITS + 1,
769
-	PAF_INDEX_XLAT_SORTED_BIT,
770
-	PAF_INDEX_XLAT_VALUE_INDEXED_BIT,
771 702
 
772 703
 	/* print_xlat */
773 704
 	PXF_DEFAULT_STR_BIT,
@@ -778,8 +709,6 @@ enum xlat_style_private_flag_bits {
778 709
 enum xlat_style_private_flags {
779 710
 	/* print_array */
780 711
 	FLAG_(PAF_PRINT_INDICES),
781
-	FLAG_(PAF_INDEX_XLAT_SORTED),
782
-	FLAG_(PAF_INDEX_XLAT_VALUE_INDEXED),
783 712
 
784 713
 	/* print_xlat */
785 714
 	FLAG_(PXF_DEFAULT_STR),
@@ -871,7 +800,6 @@ print_array_ex(struct tcb *,
871 800
 	       void *opaque_data,
872 801
 	       unsigned int flags,
873 802
 	       const struct xlat *index_xlat,
874
-	       size_t index_xlat_size,
875 803
 	       const char *index_dflt);
876 804
 
877 805
 static inline bool
@@ -886,7 +814,7 @@ print_array(struct tcb *const tcp,
886 814
 {
887 815
 	return print_array_ex(tcp, start_addr, nmemb, elem_buf, elem_size,
888 816
 			      tfetch_mem_func, print_func, opaque_data,
889
-			      0, NULL, 0, NULL);
817
+			      0, NULL, NULL);
890 818
 }
891 819
 
892 820
 extern kernel_ulong_t *

+ 25
- 30
dyxlat.c View File

@@ -7,26 +7,21 @@
7 7
 #include "defs.h"
8 8
 
9 9
 struct dyxlat {
10
-	size_t used;
11 10
 	size_t allocated;
12
-	struct xlat *xlat;
11
+	struct xlat xlat;
12
+	struct xlat_data *data;
13 13
 };
14 14
 
15
-#define MARK_END(xlat)				\
16
-	do {					\
17
-		(xlat).val = 0;			\
18
-		(xlat).str = 0;			\
19
-	} while (0)
20
-
21 15
 struct dyxlat *
22 16
 dyxlat_alloc(const size_t nmemb)
23 17
 {
24 18
 	struct dyxlat *const dyxlat = xmalloc(sizeof(*dyxlat));
25 19
 
26
-	dyxlat->used = 1;
20
+	dyxlat->xlat.type = XT_NORMAL;
21
+	dyxlat->xlat.size = 0;
27 22
 	dyxlat->allocated = nmemb;
28
-	dyxlat->xlat = xgrowarray(NULL, &dyxlat->allocated, sizeof(struct xlat));
29
-	MARK_END(dyxlat->xlat[0]);
23
+	dyxlat->xlat.data = dyxlat->data = xgrowarray(NULL, &dyxlat->allocated,
24
+						      sizeof(struct xlat_data));
30 25
 
31 26
 	return dyxlat;
32 27
 }
@@ -36,20 +31,20 @@ dyxlat_free(struct dyxlat *const dyxlat)
36 31
 {
37 32
 	size_t i;
38 33
 
39
-	for (i = 0; i < dyxlat->used - 1; ++i) {
40
-		free((void *) dyxlat->xlat[i].str);
41
-		dyxlat->xlat[i].str = NULL;
34
+	for (i = 0; i < dyxlat->xlat.size; ++i) {
35
+		free((void *) dyxlat->data[i].str);
36
+		dyxlat->data[i].str = NULL;
42 37
 	}
43 38
 
44
-	free(dyxlat->xlat);
45
-	dyxlat->xlat = NULL;
39
+	free(dyxlat->data);
40
+	dyxlat->xlat.data = NULL;
46 41
 	free(dyxlat);
47 42
 }
48 43
 
49 44
 const struct xlat *
50 45
 dyxlat_get(const struct dyxlat *const dyxlat)
51 46
 {
52
-	return dyxlat->xlat;
47
+	return &dyxlat->xlat;
53 48
 }
54 49
 
55 50
 void
@@ -58,24 +53,24 @@ dyxlat_add_pair(struct dyxlat *const dyxlat, const uint64_t val,
58 53
 {
59 54
 	size_t i;
60 55
 
61
-	for (i = 0; i < dyxlat->used - 1; ++i) {
62
-		if (dyxlat->xlat[i].val == val) {
63
-			if (strncmp(dyxlat->xlat[i].str, str, len) == 0
64
-			    && dyxlat->xlat[i].str[len] == '\0')
56
+	for (i = 0; i < dyxlat->xlat.size; ++i) {
57
+		if (dyxlat->data[i].val == val) {
58
+			if (strncmp(dyxlat->data[i].str, str, len) == 0
59
+			    && dyxlat->data[i].str[len] == '\0')
65 60
 				return;
66 61
 
67
-			free((void *) dyxlat->xlat[i].str);
68
-			dyxlat->xlat[i].str = xstrndup(str, len);
62
+			free((void *) dyxlat->data[i].str);
63
+			dyxlat->data[i].str = xstrndup(str, len);
69 64
 			return;
70 65
 		}
71 66
 	}
72 67
 
73
-	if (dyxlat->used >= dyxlat->allocated)
74
-		dyxlat->xlat = xgrowarray(dyxlat->xlat, &dyxlat->allocated,
75
-					  sizeof(struct xlat));
68
+	if (dyxlat->xlat.size >= dyxlat->allocated)
69
+		dyxlat->xlat.data = dyxlat->data =
70
+			xgrowarray(dyxlat->data, &dyxlat->allocated,
71
+				   sizeof(struct xlat_data));
76 72
 
77
-	dyxlat->xlat[dyxlat->used - 1].val = val;
78
-	dyxlat->xlat[dyxlat->used - 1].str = xstrndup(str, len);
79
-	MARK_END(dyxlat->xlat[dyxlat->used]);
80
-	dyxlat->used++;
73
+	dyxlat->data[dyxlat->xlat.size].val = val;
74
+	dyxlat->data[dyxlat->xlat.size].str = xstrndup(str, len);
75
+	dyxlat->xlat.size++;
81 76
 }

+ 23
- 32
evdev.c View File

@@ -33,8 +33,6 @@
33 33
 #  define SYN_MAX 0xf
34 34
 # endif
35 35
 
36
-const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
37
-
38 36
 static int
39 37
 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
40 38
 {
@@ -78,7 +76,7 @@ keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
78 76
 
79 77
 	if (!umove_or_printaddr(tcp, arg, &keycode)) {
80 78
 		tprintf("[%u, ", keycode[0]);
81
-		printxval_index(evdev_keycode, keycode[1], "KEY_???");
79
+		printxval(evdev_keycode, keycode[1], "KEY_???");
82 80
 		tprints("]");
83 81
 	}
84 82
 
@@ -105,7 +103,7 @@ keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
105 103
 		unsigned int i;
106 104
 
107 105
 		tprintf("index=%" PRIu16 ", keycode=", ike.index);
108
-		printxval_index(evdev_keycode, ike.keycode, "KEY_???");
106
+		printxval(evdev_keycode, ike.keycode, "KEY_???");
109 107
 		tprints(", scancode=[");
110 108
 		for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
111 109
 			if (i > 0)
@@ -144,9 +142,9 @@ getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
144 142
 }
145 143
 
146 144
 static int
147
-decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
148
-	       const struct xlat decode_nr[], const unsigned int max_nr,
149
-	       const char *const dflt, size_t decode_nr_size, enum xlat_type xt)
145
+decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
146
+	      const struct xlat *decode_nr, const unsigned int max_nr,
147
+	      const char *const dflt)
150 148
 {
151 149
 	tprints(", ");
152 150
 
@@ -178,7 +176,7 @@ decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
178 176
 	if (i < 0) {
179 177
 		tprints(" 0 ");
180 178
 	} else {
181
-		printxval_dispatch(decode_nr, decode_nr_size, i, dflt, xt);
179
+		printxval(decode_nr, i, dflt);
182 180
 
183 181
 		while ((i = next_set_bit(decoded_arg, i + 1, size_bits)) > 0) {
184 182
 			if (abbrev(tcp) && bit_displayed >= 3) {
@@ -186,8 +184,7 @@ decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
186 184
 				break;
187 185
 			}
188 186
 			tprints(", ");
189
-			printxval_dispatch(decode_nr, decode_nr_size, i, dflt,
190
-					   xt);
187
+			printxval(decode_nr, i, dflt);
191 188
 			bit_displayed++;
192 189
 		}
193 190
 	}
@@ -197,10 +194,6 @@ decode_bitset_(struct tcb *const tcp, const kernel_ulong_t arg,
197 194
 	return RVAL_IOCTL_DECODED;
198 195
 }
199 196
 
200
-# define decode_bitset(tcp_, arg_, decode_nr_, max_nr_, dflt_, xt_) \
201
-	decode_bitset_((tcp_), (arg_), (decode_nr_), (max_nr_), \
202
-		       (dflt_), ARRAY_SIZE(decode_nr_) - 1, (xt_))
203
-
204 197
 # ifdef EVIOCGMTSLOTS
205 198
 static int
206 199
 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
@@ -251,42 +244,41 @@ bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
251 244
 	switch (ev_nr) {
252 245
 		case 0:
253 246
 			return decode_bitset(tcp, arg, evdev_ev,
254
-					     EV_MAX, "EV_???", XT_SORTED);
247
+					     EV_MAX, "EV_???");
255 248
 		case EV_KEY:
256 249
 			return decode_bitset(tcp, arg, evdev_keycode,
257
-					     KEY_MAX, "KEY_???", XT_INDEXED);
250
+					     KEY_MAX, "KEY_???");
258 251
 		case EV_REL:
259 252
 			return decode_bitset(tcp, arg, evdev_relative_axes,
260
-					     REL_MAX, "REL_???", XT_INDEXED);
253
+					     REL_MAX, "REL_???");
261 254
 		case EV_ABS:
262 255
 			return decode_bitset(tcp, arg, evdev_abs,
263
-					     ABS_MAX, "ABS_???", XT_INDEXED);
256
+					     ABS_MAX, "ABS_???");
264 257
 		case EV_MSC:
265 258
 			return decode_bitset(tcp, arg, evdev_misc,
266
-					     MSC_MAX, "MSC_???", XT_INDEXED);
259
+					     MSC_MAX, "MSC_???");
267 260
 		case EV_SW:
268 261
 			return decode_bitset(tcp, arg, evdev_switch,
269
-					     SW_MAX, "SW_???", XT_INDEXED);
262
+					     SW_MAX, "SW_???");
270 263
 		case EV_LED:
271 264
 			return decode_bitset(tcp, arg, evdev_leds,
272
-					     LED_MAX, "LED_???", XT_INDEXED);
265
+					     LED_MAX, "LED_???");
273 266
 		case EV_SND:
274 267
 			return decode_bitset(tcp, arg, evdev_snd,
275
-					     SND_MAX, "SND_???", XT_INDEXED);
268
+					     SND_MAX, "SND_???");
276 269
 		case EV_REP:
277 270
 			return decode_bitset(tcp, arg, evdev_autorepeat,
278
-					     REP_MAX, "REP_???", XT_INDEXED);
271
+					     REP_MAX, "REP_???");
279 272
 		case EV_FF:
280 273
 			return decode_bitset(tcp, arg, evdev_ff_types,
281
-					     FF_MAX, "FF_???", XT_SORTED);
274
+					     FF_MAX, "FF_???");
282 275
 		case EV_PWR:
283 276
 			tprints(", ");
284 277
 			printnum_int(tcp, arg, "%d");
285 278
 			return RVAL_IOCTL_DECODED;
286 279
 		case EV_FF_STATUS:
287 280
 			return decode_bitset(tcp, arg, evdev_ff_status,
288
-					     FF_STATUS_MAX, "FF_STATUS_???",
289
-					     XT_INDEXED);
281
+					     FF_STATUS_MAX, "FF_STATUS_???");
290 282
 		default:
291 283
 			tprints(", ");
292 284
 			printaddr(arg);
@@ -340,23 +332,22 @@ evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
340 332
 # ifdef EVIOCGPROP
341 333
 		case _IOC_NR(EVIOCGPROP(0)):
342 334
 			return decode_bitset(tcp, arg, evdev_prop,
343
-					     INPUT_PROP_MAX, "PROP_???",
344
-					     XT_INDEXED);
335
+					     INPUT_PROP_MAX, "PROP_???");
345 336
 # endif
346 337
 		case _IOC_NR(EVIOCGSND(0)):
347 338
 			return decode_bitset(tcp, arg, evdev_snd,
348
-					     SND_MAX, "SND_???", XT_INDEXED);
339
+					     SND_MAX, "SND_???");
349 340
 # ifdef EVIOCGSW
350 341
 		case _IOC_NR(EVIOCGSW(0)):
351 342
 			return decode_bitset(tcp, arg, evdev_switch,
352
-					     SW_MAX, "SW_???", XT_INDEXED);
343
+					     SW_MAX, "SW_???");
353 344
 # endif
354 345
 		case _IOC_NR(EVIOCGKEY(0)):
355 346
 			return decode_bitset(tcp, arg, evdev_keycode,
356
-					     KEY_MAX, "KEY_???", XT_INDEXED);
347
+					     KEY_MAX, "KEY_???");
357 348
 		case _IOC_NR(EVIOCGLED(0)):
358 349
 			return decode_bitset(tcp, arg, evdev_leds,
359
-					     LED_MAX, "LED_???", XT_INDEXED);
350
+					     LED_MAX, "LED_???");
360 351
 	}
361 352
 
362 353
 	/* multi-number fixed-length commands */

+ 1
- 1
fsconfig.c View File

@@ -22,7 +22,7 @@ SYS_FUNC(fsconfig)
22 22
 	printfd(tcp, fs_fd);
23 23
 	tprints(", ");
24 24
 
25
-	printxval_index(fsconfig_cmds, cmd, "FSCONFIG_???");
25
+	printxval(fsconfig_cmds, cmd, "FSCONFIG_???");
26 26
 	tprints(", ");
27 27
 
28 28
 	switch (cmd) {

+ 2
- 4
ioctl.c View File

@@ -65,8 +65,7 @@ evdev_decode_number(const unsigned int code)
65 65
 	if (_IOC_DIR(code) == _IOC_WRITE) {
66 66
 		if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
67 67
 			tprints("EVIOCSABS(");
68
-			printxval_indexn(evdev_abs, evdev_abs_size, nr - 0xc0,
69
-					 "ABS_???");
68
+			printxval(evdev_abs, nr - 0xc0, "ABS_???");
70 69
 			tprints(")");
71 70
 			return 1;
72 71
 		}
@@ -85,8 +84,7 @@ evdev_decode_number(const unsigned int code)
85 84
 		return 1;
86 85
 	} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
87 86
 		tprints("EVIOCGABS(");
88
-		printxval_indexn(evdev_abs, evdev_abs_size, nr - 0x40,
89
-				 "ABS_???");
87
+		printxval(evdev_abs, nr - 0x40, "ABS_???");
90 88
 		tprints(")");
91 89
 		return 1;
92 90
 	}

+ 2
- 3
kvm.c View File

@@ -308,7 +308,7 @@ kvm_ioctl_decode_check_extension(struct tcb *const tcp, const unsigned int code,
308 308
 				 const kernel_ulong_t arg)
309 309
 {
310 310
 	tprints(", ");
311
-	printxval_index(kvm_cap, arg, "KVM_CAP_???");
311
+	printxval64(kvm_cap, arg, "KVM_CAP_???");
312 312
 	return RVAL_IOCTL_DECODED;
313 313
 }
314 314
 
@@ -326,8 +326,7 @@ kvm_ioctl_run_attach_auxstr(struct tcb *const tcp,
326 326
 	if (umove(tcp, info->mmap_addr, &vcpu_run_struct) < 0)
327 327
 		return;
328 328
 
329
-	tcp->auxstr = xlat_idx(kvm_exit_reason, ARRAY_SIZE(kvm_exit_reason) - 1,
330
-			       vcpu_run_struct.exit_reason);
329
+	tcp->auxstr = xlookup(kvm_exit_reason, vcpu_run_struct.exit_reason);
331 330
 	if (!tcp->auxstr)
332 331
 		tcp->auxstr = "KVM_EXIT_???";
333 332
 }

+ 27
- 29
net.c View File

@@ -123,14 +123,13 @@ SYS_FUNC(socket)
123 123
 	switch (tcp->u_arg[0]) {
124 124
 	case AF_INET:
125 125
 	case AF_INET6:
126
-		printxval_search(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
126
+		printxval(inet_protocols, tcp->u_arg[2], "IPPROTO_???");
127 127
 		break;
128 128
 
129 129
 	case AF_AX25:
130 130
 		/* Those are not available in public headers.  */
131
-		printxval_searchn_ex(ARRSZ_PAIR(ax25_protocols) - 1,
132
-				     tcp->u_arg[2], "AX25_P_???",
133
-				     XLAT_STYLE_VERBOSE);
131
+		printxval_ex(ax25_protocols, tcp->u_arg[2], "AX25_P_???",
132
+			     XLAT_STYLE_VERBOSE);
134 133
 		break;
135 134
 
136 135
 	case AF_NETLINK:
@@ -139,21 +138,21 @@ SYS_FUNC(socket)
139 138
 
140 139
 	case AF_PACKET:
141 140
 		tprints("htons(");
142
-		printxval_searchn(ethernet_protocols, ethernet_protocols_size,
143
-				  ntohs(tcp->u_arg[2]), "ETH_P_???");
141
+		printxval(ethernet_protocols, ntohs(tcp->u_arg[2]),
142
+			  "ETH_P_???");
144 143
 		tprints(")");
145 144
 		break;
146 145
 
147 146
 	case AF_IRDA:
148
-		printxval_index(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
147
+		printxval(can_protocols, tcp->u_arg[2], "IRDAPROTO_???");
149 148
 		break;
150 149
 
151 150
 	case AF_CAN:
152
-		printxval_index(can_protocols, tcp->u_arg[2], "CAN_???");
151
+		printxval(can_protocols, tcp->u_arg[2], "CAN_???");
153 152
 		break;
154 153
 
155 154
 	case AF_BLUETOOTH:
156
-		printxval_index(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
155
+		printxval(bt_protocols, tcp->u_arg[2], "BTPROTO_???");
157 156
 		break;
158 157
 
159 158
 	case AF_RXRPC:
@@ -165,24 +164,23 @@ SYS_FUNC(socket)
165 164
 		break;
166 165
 
167 166
 	case AF_PHONET:
168
-		printxval_index(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
167
+		printxval(phonet_protocols, tcp->u_arg[2], "PN_PROTO_???");
169 168
 		break;
170 169
 
171 170
 	case AF_CAIF:
172
-		printxval_index(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
171
+		printxval(caif_protocols, tcp->u_arg[2], "CAIFPROTO_???");
173 172
 		break;
174 173
 
175 174
 	case AF_NFC:
176
-		printxval_index(nfc_protocols, tcp->u_arg[2],
177
-				"NFC_SOCKPROTO_???");
175
+		printxval(nfc_protocols, tcp->u_arg[2], "NFC_SOCKPROTO_???");
178 176
 		break;
179 177
 
180 178
 	case AF_KCM:
181
-		printxval_index(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
179
+		printxval(kcm_protocols, tcp->u_arg[2], "KCMPROTO_???");
182 180
 		break;
183 181
 
184 182
 	case AF_SMC:
185
-		printxval_index(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
183
+		printxval(smc_protocols, tcp->u_arg[2], "SMCPROTO_???");
186 184
 		break;
187 185
 
188 186
 	default:
@@ -463,7 +461,7 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
463 461
 {
464 462
 	printfd(tcp, fd);
465 463
 	tprints(", ");
466
-	printxval_search(socketlayers, level, "SOL_??");
464
+	printxval(socketlayers, level, "SOL_??");
467 465
 	tprints(", ");
468 466
 
469 467
 	switch (level) {
@@ -486,13 +484,13 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
486 484
 		printxval(sock_ipx_options, name, "IPX_???");
487 485
 		break;
488 486
 	case SOL_AX25:
489
-		printxval_search(sock_ax25_options, name, "AX25_???");
487
+		printxval(sock_ax25_options, name, "AX25_???");
490 488
 		break;
491 489
 	case SOL_PACKET:
492 490
 		printxval(sock_packet_options, name, "PACKET_???");
493 491
 		break;
494 492
 	case SOL_TCP:
495
-		printxval_index(sock_tcp_options, name, "TCP_???");
493
+		printxval(sock_tcp_options, name, "TCP_???");
496 494
 		break;
497 495
 	case SOL_SCTP:
498 496
 		printxval(sock_sctp_options, name, "SCTP_???");
@@ -507,31 +505,31 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
507 505
 		printxval(sock_udp_options, name, "UDP_???");
508 506
 		break;
509 507
 	case SOL_IRDA:
510
-		printxval_index(sock_irda_options, name, "IRLMP_???");
508
+		printxval(sock_irda_options, name, "IRLMP_???");
511 509
 		break;
512 510
 	case SOL_LLC:
513
-		printxval_index(sock_llc_options, name, "LLC_OPT_???");
511
+		printxval(sock_llc_options, name, "LLC_OPT_???");
514 512
 		break;
515 513
 	case SOL_DCCP:
516
-		printxval_search(sock_dccp_options, name, "DCCP_SOCKOPT_???");
514
+		printxval(sock_dccp_options, name, "DCCP_SOCKOPT_???");
517 515
 		break;
518 516
 	case SOL_TIPC:
519
-		printxval_search(sock_tipc_options, name, "TIPC_???");
517
+		printxval(sock_tipc_options, name, "TIPC_???");
520 518
 		break;
521 519
 	case SOL_RXRPC:
522
-		printxval_index(sock_rxrpc_options, name, "RXRPC_???");
520
+		printxval(sock_rxrpc_options, name, "RXRPC_???");
523 521
 		break;
524 522
 	case SOL_PPPOL2TP:
525
-		printxval_index(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
523
+		printxval(sock_pppol2tp_options, name, "PPPOL2TP_SO_???");
526 524
 		break;
527 525
 	case SOL_BLUETOOTH:
528
-		printxval_search(sock_bluetooth_options, name, "BT_???");
526
+		printxval(sock_bluetooth_options, name, "BT_???");
529 527
 		break;
530 528
 	case SOL_PNPIPE:
531 529
 		printxval(sock_pnp_options, name, "PNPIPE_???");
532 530
 		break;
533 531
 	case SOL_RDS:
534
-		printxval_search(sock_rds_options, name, "RDS_???");
532
+		printxval(sock_rds_options, name, "RDS_???");
535 533
 		break;
536 534
 	case SOL_IUCV:
537 535
 		printxval(sock_iucv_options, name, "SO_???");
@@ -540,10 +538,10 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
540 538
 		printxval(sock_caif_options, name, "CAIFSO_???");
541 539
 		break;
542 540
 	case SOL_ALG:
543
-		printxval_index(sock_alg_options, name, "ALG_???");
541
+		printxval(sock_alg_options, name, "ALG_???");
544 542
 		break;
545 543
 	case SOL_NFC:
546
-		printxval_index(sock_nfcllcp_options, name, "NFC_LLCP_???");
544
+		printxval(sock_nfcllcp_options, name, "NFC_LLCP_???");
547 545
 		break;
548 546
 	case SOL_KCM:
549 547
 		printxval(sock_kcm_options, name, "KCM_???");
@@ -552,7 +550,7 @@ print_sockopt_fd_level_name(struct tcb *tcp, int fd, unsigned int level,
552 550
 		printxval(sock_tls_options, name, "TLS_???");
553 551
 		break;
554 552
 	case SOL_XDP:
555
-		printxval_index(sock_xdp_options, name, "XDP_???");
553
+		printxval(sock_xdp_options, name, "XDP_???");
556 554
 		break;
557 555
 
558 556
 		/* Other SOL_* protocol levels still need work. */

+ 7
- 4
netlink.c View File

@@ -80,11 +80,14 @@ get_fd_nl_family(struct tcb *const tcp, const int fd)
80 80
 	if (nl_details == details)
81 81
 		return -1;
82 82
 
83
-	const struct xlat *xlats = netlink_protocols;
84
-	for (; xlats->str; ++xlats) {
85
-		const char *name = STR_STRIP_PREFIX(xlats->str, "NETLINK_");
83
+	const struct xlat_data *xlats = netlink_protocols->data;
84
+	for (uint32_t idx = 0; idx < netlink_protocols->size; idx++) {
85
+		if (!netlink_protocols->data[idx].str)
86
+			continue;
87
+
88
+		const char *name = STR_STRIP_PREFIX(xlats[idx].str, "NETLINK_");
86 89
 		if (!strncmp(nl_details, name, strlen(name)))
87
-			return xlats->val;
90
+			return xlats[idx].val;
88 91
 	}
89 92
 
90 93
 	if (*nl_details >= '0' && *nl_details <= '9')

+ 2
- 4
netlink_packet_diag.c View File

@@ -174,10 +174,8 @@ DECL_NETLINK_DIAG_DECODER(decode_packet_diag_msg)
174 174
 					 (char *) &msg + offset)) {
175 175
 			PRINT_FIELD_XVAL("", msg, pdiag_type,
176 176
 					 socktypes, "SOCK_???");
177
-			PRINT_FIELD_XVAL_SORTED_SIZED(", ", msg, pdiag_num,
178
-						      ethernet_protocols,
179
-						      ethernet_protocols_size,
180
-						      "ETH_P_???");
177
+			PRINT_FIELD_XVAL(", ", msg, pdiag_num,
178
+					 ethernet_protocols, "ETH_P_???");
181 179
 			PRINT_FIELD_U(", ", msg, pdiag_ino);
182 180
 			PRINT_FIELD_COOKIE(", ", msg, pdiag_cookie);
183 181
 			decode_nla = true;

+ 7
- 8
netlink_smc_diag.c View File

@@ -136,7 +136,7 @@ decode_smc_diag_shutdown(struct tcb *const tcp,
136 136
 			 const void *const opaque_data)
137 137
 {
138 138
 	const struct decode_nla_xlat_opts opts = {
139
-		ARRSZ_PAIR(sock_shutdown_flags) - 1, "???_SHUTDOWN",
139
+		sock_shutdown_flags, "???_SHUTDOWN",
140 140
 		.size = 1,
141 141
 	};
142 142
 
@@ -183,11 +183,11 @@ decode_smc_diag_fallback(struct tcb *const tcp,
183 183
 	 * net/smc/smc_clc.h
184 184
 	 */
185 185
 	tprints("{reason=");
186
-	printxval_search_ex(smc_decl_codes, fb.reason,
187
-			    "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
186
+	printxval_ex(smc_decl_codes, fb.reason, "SMC_CLC_DECL_???",
187
+		     XLAT_STYLE_VERBOSE);
188 188
 	tprints(", peer_diagnosis=");
189
-	printxval_search_ex(smc_decl_codes, fb.peer_diagnosis,
190
-			    "SMC_CLC_DECL_???", XLAT_STYLE_VERBOSE);
189
+	printxval_ex(smc_decl_codes, fb.peer_diagnosis, "SMC_CLC_DECL_???",
190
+		     XLAT_STYLE_VERBOSE);
191 191
 	tprints("}");
192 192
 
193 193
 	return true;
@@ -215,9 +215,8 @@ DECL_NETLINK_DIAG_DECODER(decode_smc_diag_msg)
215 215
 					 (void *) &msg + offset)) {
216 216
 			PRINT_FIELD_XVAL("", msg, diag_state,
217 217
 					 smc_states, "SMC_???");
218
-			PRINT_FIELD_XVAL_INDEX(", ", msg, diag_fallback,
219
-					       smc_diag_mode,
220
-					       "SMC_DIAG_MODE_???");
218
+			PRINT_FIELD_XVAL(", ", msg, diag_fallback,
219
+					 smc_diag_mode, "SMC_DIAG_MODE_???");
221 220
 			PRINT_FIELD_U(", ", msg, diag_shutdown);
222 221
 			/*
223 222
 			 * AF_SMC protocol family socket handler

+ 5
- 16
nlattr.c View File

@@ -196,10 +196,8 @@ decode_nla_meminfo(struct tcb *const tcp,
196 196
 	unsigned int count = 0;
197 197
 	print_array_ex(tcp, addr, nmemb, &mem, sizeof(mem),
198 198
 		       tfetch_mem, print_uint32_array_member, &count,
199
-		       PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
200
-			| XLAT_STYLE_FMT_U,
201
-		       ARRSZ_PAIR(netlink_sk_meminfo_indices) - 1,
202
-		       "SK_MEMINFO_???");
199
+		       PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
200
+		       netlink_sk_meminfo_indices, "SK_MEMINFO_???");
203 201
 
204 202
 	return true;
205 203
 }
@@ -286,8 +284,7 @@ decode_nla_xval(struct tcb *const tcp,
286 284
 			data.val = opts->process_fn(data.val);
287 285
 		if (opts->prefix)
288 286
 			tprints(opts->prefix);
289
-		printxval_dispatch_ex(opts->xlat, opts->xlat_size, data.val,
290
-				      opts->dflt, opts->xt, opts->style);
287
+		printxval_ex(opts->xlat, data.val, opts->dflt, opts->style);
291 288
 		if (opts->suffix)
292 289
 			tprints(opts->suffix);
293 290
 	}
@@ -307,11 +304,9 @@ decode_nla_ether_proto(struct tcb *const tcp,
307 304
 		       const unsigned int len,
308 305
 		       const void *const opaque_data)
309 306
 {
310
-	const struct decode_nla_xlat_opts opts = {
307
+	static const struct decode_nla_xlat_opts opts = {
311 308
 		.xlat = ethernet_protocols,
312
-		.xlat_size = ethernet_protocols_size,
313 309
 		.dflt = "ETHER_P_???",
314
-		.xt = XT_SORTED,
315 310
 		.prefix = "htons(",
316 311
 		.suffix = ")",
317 312
 		.size = 2,
@@ -327,10 +322,8 @@ decode_nla_ip_proto(struct tcb *const tcp,
327 322
 		    const unsigned int len,
328 323
 		    const void *const opaque_data)
329 324
 {
330
-	const struct decode_nla_xlat_opts opts = {
325
+	static const struct decode_nla_xlat_opts opts = {
331 326
 		.xlat = inet_protocols,
332
-		.xlat_size = inet_protocols_size,
333
-		.xt = XT_SORTED,
334 327
 		.dflt = "IPPROTO_???",
335 328
 		.size = 1,
336 329
 	};
@@ -390,10 +383,6 @@ decode_nla_flags(struct tcb *const tcp,
390 383
 
391 384
 	const size_t bytes_offs = is_bigendian ? sizeof(data) - len : 0;
392 385
 
393
-	if (opts->xt == XT_INDEXED)
394
-		error_func_msg("indexed xlats are currently incompatible with "
395
-			       "printflags");
396
-
397 386
 	if (!umoven_or_printaddr(tcp, addr, len, data.bytes + bytes_offs)) {
398 387
 		if (opts->process_fn)
399 388
 			data.flags = opts->process_fn(data.flags);

+ 0
- 2
nlattr.h View File

@@ -14,9 +14,7 @@
14 14
 
15 15
 struct decode_nla_xlat_opts {
16 16
 	const struct xlat *xlat;
17
-	size_t xlat_size; /* is not needed for XT_NORMAL */
18 17
 	const char *dflt;
19
-	enum xlat_type xt;
20 18
 	enum xlat_style style;
21 19
 	const char *prefix;
22 20
 	const char *suffix;

+ 0
- 17
print_fields.h View File

@@ -79,23 +79,6 @@
79 79
 			      (xlat_), NULL);				\
80 80
 	} while (0)
81 81
 
82
-# define PRINT_FIELD_XVAL_SORTED_SIZED(prefix_, where_, field_, xlat_,	\
83
-				      xlat_size_, dflt_)		\
84
-	do {								\
85
-		STRACE_PRINTF("%s%s=", (prefix_), #field_);		\
86
-		printxval_searchn((xlat_), (xlat_size_),		\
87
-				  zero_extend_signed_to_ull((where_).field_), \
88
-				  (dflt_));				\
89
-	} while (0)
90
-
91
-# define PRINT_FIELD_XVAL_INDEX(prefix_, where_, field_, xlat_, dflt_)	\
92
-	do {								\
93
-		STRACE_PRINTF("%s%s=", (prefix_), #field_);		\
94
-		printxval_index((xlat_),				\
95
-				zero_extend_signed_to_ull((where_).field_), \
96
-				(dflt_));				\
97
-	} while (0)
98
-
99 82
 /*
100 83
  * Generic "ID" printing. ID is considered unsigned except for the special value
101 84
  * of -1.

+ 1
- 1
print_statfs.c View File

@@ -14,7 +14,7 @@ static void
14 14
 print_statfs_type(const char *const prefix, const unsigned long long magic)
15 15
 {
16 16
 	tprints(prefix);
17
-	printxval_search(fsmagic, magic, NULL);
17
+	printxval(fsmagic, magic, NULL);
18 18
 }
19 19
 
20 20
 #if defined HAVE_STRUCT_STATFS_F_FLAGS || defined HAVE_STRUCT_STATFS64_F_FLAGS

+ 21
- 17
process.c View File

@@ -33,39 +33,43 @@
33 33
 #define uoff(member)	offsetof(struct user, member)
34 34
 #define XLAT_UOFF(member)	{ uoff(member), "offsetof(struct user, " #member ")" }
35 35
 
36
-static const struct xlat struct_user_offsets[] = {
36
+static const struct xlat_data struct_user_offsets_data[] = {
37 37
 #include "userent.h"
38 38
 	XLAT_END
39 39
 };
40 40
 
41
+static const struct xlat struct_user_offsets = {
42
+	.type = XT_SORTED,
43
+	.size = ARRAY_SIZE(struct_user_offsets_data) - 1,
44
+	.data = struct_user_offsets_data,
45
+};
46
+
41 47
 static void
42 48
 print_user_offset_addr(const kernel_ulong_t addr)
43 49
 {
44
-	bool no_str = false;
45
-	const struct xlat *x;
50
+	const uint64_t last_user_offset = struct_user_offsets.size ?
51
+		struct_user_offsets.data[struct_user_offsets.size - 1].val : 0;
46 52
 
47
-	for (x = struct_user_offsets; x->str; ++x) {
48
-		if (x->val >= addr)
49
-			break;
50
-	}
53
+	uint64_t base_addr = addr;
54
+	const char *str = xlookup_le(&struct_user_offsets, &base_addr);
51 55
 
52
-	if (!x->str || (x == struct_user_offsets && x->val > addr))
53
-		no_str = true;
54
-	if (no_str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
56
+	/* We don't want to pretty print addresses beyond struct user */
57
+	if (addr > base_addr && base_addr == last_user_offset)
58
+		str = NULL;
59
+
60
+	if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
55 61
 		printaddr(addr);
56
-	if (no_str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
62
+	if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
57 63
 		return;
58 64
 
59 65
 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
60 66
 		tprints(" /* ");
61 67
 
62
-	if (x->val > addr) {
63
-		--x;
68
+	if (base_addr == addr)
69
+		tprints(str);
70
+	else
64 71
 		tprintf("%s + %" PRI_klu,
65
-			x->str, addr - (kernel_ulong_t) x->val);
66
-	} else {
67
-		tprints(x->str);
68
-	}
72
+			str, addr - (kernel_ulong_t) base_addr);
69 73
 
70 74
 	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
71 75
 		tprints(" */");

+ 2
- 2
ptrace_syscall_info.c View File

@@ -277,8 +277,8 @@ print_ptrace_syscall_info(struct tcb *tcp, kernel_ulong_t addr,
277 277
 		return;
278 278
 	}
279 279
 
280
-	PRINT_FIELD_XVAL_INDEX("{", info, op, ptrace_syscall_info_op,
281
-			       "PTRACE_SYSCALL_INFO_???");
280
+	PRINT_FIELD_XVAL("{", info, op, ptrace_syscall_info_op,
281
+			 "PTRACE_SYSCALL_INFO_???");
282 282
 	if (fetch_size < offsetofend(struct ptrace_syscall_info, arch))
283 283
 		goto printed;
284 284
 	PRINT_FIELD_XVAL(", ", info, arch, audit_arch, "AUDIT_ARCH_???");

+ 16
- 29
rtnl_link.c View File

@@ -337,10 +337,8 @@ decode_nla_tun_type(struct tcb *const tcp,
337 337
 		    const unsigned int len,
338 338
 		    const void *const opaque_data)
339 339
 {
340
-	const struct decode_nla_xlat_opts opts = {
340
+	static const struct decode_nla_xlat_opts opts = {
341 341
 		.xlat = tun_device_types,
342
-		.xlat_size = ARRAY_SIZE(tun_device_types) - 1,
343
-		.xt = XT_INDEXED,
344 342
 		.dflt = "IFF_???",
345 343
 		.size = 1,
346 344
 	};
@@ -563,10 +561,8 @@ decode_ifla_xdp_attached(struct tcb *const tcp,
563 561
 			 const unsigned int len,
564 562
 			 const void *const opaque_data)
565 563
 {
566
-	const struct decode_nla_xlat_opts opts = {
564
+	static const struct decode_nla_xlat_opts opts = {
567 565
 		.xlat = rtnl_ifla_xdp_attached_mode,
568
-		.xlat_size = ARRAY_SIZE(rtnl_ifla_xdp_attached_mode) - 1,
569
-		.xt = XT_INDEXED,
570 566
 		.dflt = "XDP_ATTACHED_???",
571 567
 		.size = 1,
572 568
 	};
@@ -628,10 +624,8 @@ decode_ifla_inet_conf(struct tcb *const tcp,
628 624
 
629 625
 	print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
630 626
 		       tfetch_mem, print_int32_array_member, NULL,
631
-		       PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
632
-			| XLAT_STYLE_FMT_D,
633
-		       ARRSZ_PAIR(inet_devconf_indices) - 1,
634
-		       "IPV4_DEVCONF_???");
627
+		       PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
628
+		       inet_devconf_indices, "IPV4_DEVCONF_???");
635 629
 
636 630
 	return true;
637 631
 }
@@ -646,8 +640,8 @@ decode_ifla_inet6_flags(struct tcb *const tcp,
646 640
 		        const unsigned int len,
647 641
 		        const void *const opaque_data)
648 642
 {
649
-	const struct decode_nla_xlat_opts opts = {
650
-		ARRSZ_PAIR(inet6_if_flags) - 1, "IF_???",
643
+	static const struct decode_nla_xlat_opts opts = {
644
+		inet6_if_flags, "IF_???",
651 645
 		.size = 4,
652 646
 	};
653 647
 
@@ -668,10 +662,8 @@ decode_ifla_inet6_conf(struct tcb *const tcp,
668 662
 
669 663
 	print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
670 664
 		       tfetch_mem, print_int32_array_member, NULL,
671
-		       PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
672
-			| XLAT_STYLE_FMT_D,
673
-		       ARRSZ_PAIR(inet6_devconf_indices) - 1,
674
-		       "DEVCONF_???");
665
+		       PAF_PRINT_INDICES | XLAT_STYLE_FMT_D,
666
+		       inet6_devconf_indices, "DEVCONF_???");
675 667
 
676 668
 	return true;
677 669
 }
@@ -690,9 +682,8 @@ decode_ifla_inet6_stats(struct tcb *const tcp,
690 682
 
691 683
 	print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
692 684
 		       tfetch_mem, print_uint64_array_member, NULL,
693
-		       PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
694
-			| XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_ip_stats) - 1,
695
-		       "IPSTATS_MIB_???");
685
+		       PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
686
+		       snmp_ip_stats, "IPSTATS_MIB_???");
696 687
 
697 688
 	return true;
698 689
 }
@@ -737,9 +728,8 @@ decode_ifla_inet6_icmp6_stats(struct tcb *const tcp,
737 728
 
738 729
 	print_array_ex(tcp, addr, cnt, &elem, sizeof(elem),
739 730
 		       tfetch_mem, print_uint64_array_member, NULL,
740
-		       PAF_PRINT_INDICES | PAF_INDEX_XLAT_VALUE_INDEXED
741
-			| XLAT_STYLE_FMT_U, ARRSZ_PAIR(snmp_icmp6_stats) - 1,
742
-		       "ICMP6_MIB_???");
731
+		       PAF_PRINT_INDICES | XLAT_STYLE_FMT_U,
732
+		       snmp_icmp6_stats, "ICMP6_MIB_???");
743 733
 
744 734
 	return true;
745 735
 }
@@ -750,9 +740,8 @@ decode_ifla_inet6_agm(struct tcb *const tcp,
750 740
 		      const unsigned int len,
751 741
 		      const void *const opaque_data)
752 742
 {
753
-	const struct decode_nla_xlat_opts opts = {
754
-		ARRSZ_PAIR(in6_addr_gen_mode) - 1, "IN6_ADDR_GEN_MODE_???",
755
-		.xt = XT_INDEXED,
743
+	static const struct decode_nla_xlat_opts opts = {
744
+		in6_addr_gen_mode, "IN6_ADDR_GEN_MODE_???",
756 745
 		.size = 1,
757 746
 	};
758 747
 
@@ -887,10 +876,8 @@ DECL_NETLINK_ROUTE_DECODER(decode_ifinfomsg)
887 876
 		if (!umoven_or_printaddr(tcp, addr + offset,
888 877
 					 sizeof(ifinfo) - offset,
889 878
 					 (char *) &ifinfo + offset)) {
890
-			PRINT_FIELD_XVAL_SORTED_SIZED("", ifinfo, ifi_type,
891
-						      arp_hardware_types,
892
-						      arp_hardware_types_size,
893
-						      "ARPHRD_???");
879
+			PRINT_FIELD_XVAL("", ifinfo, ifi_type,
880
+					 arp_hardware_types, "ARPHRD_???");
894 881
 			PRINT_FIELD_IFINDEX(", ", ifinfo, ifi_index);
895 882
 			PRINT_FIELD_FLAGS(", ", ifinfo, ifi_flags,
896 883
 					  iffflags, "IFF_???");

+ 1
- 1
rtnl_route.c View File

@@ -52,7 +52,7 @@ decode_nla_rt_proto(struct tcb *const tcp,
52 52
 	if (len < sizeof(num))
53 53
 		return false;
54 54
 	if (!umove_or_printaddr(tcp, addr, &num))
55
-		printxval_search(routing_protocols, num, "RTPROT_???");
55
+		printxval(routing_protocols, num, "RTPROT_???");
56 56
 	return true;
57 57
 }
58 58
 

+ 2
- 4
sock.c View File

@@ -60,10 +60,8 @@ print_ifreq(struct tcb *const tcp, const unsigned int code,
60 60
 		break;
61 61
 	case SIOCSIFHWADDR:
62 62
 	case SIOCGIFHWADDR: {
63
-		PRINT_FIELD_XVAL_SORTED_SIZED("ifr_hwaddr={", ifr->ifr_hwaddr,
64
-					      sa_family, arp_hardware_types,
65
-					      arp_hardware_types_size,
66
-					      "ARPHRD_???");
63
+		PRINT_FIELD_XVAL("ifr_hwaddr={", ifr->ifr_hwaddr, sa_family,
64
+				 arp_hardware_types, "ARPHRD_???");
67 65
 		PRINT_FIELD_HWADDR_SZ(", ", ifr->ifr_hwaddr, sa_data,
68 66
 				      sizeof(ifr->ifr_hwaddr.sa_data),
69 67
 				      ifr->ifr_hwaddr.sa_family);

+ 8
- 9
sockaddr.c View File

@@ -433,8 +433,8 @@ print_sll_protocol(const struct sockaddr_ll *const sa_ll)
433 433
 		tprints(" /* ");
434 434
 
435 435
 	tprints("htons(");
436
-	printxval_search_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
437
-			    "ETH_P_???", XLAT_STYLE_ABBREV);
436
+	printxval_ex(ethernet_protocols, ntohs(sa_ll->sll_protocol),
437
+		     "ETH_P_???", XLAT_STYLE_ABBREV);
438 438
 	tprints(")");
439 439
 
440 440
 	if (x_style == XLAT_STYLE_VERBOSE)
@@ -449,9 +449,9 @@ print_sockaddr_data_ll(const void *const buf, const int addrlen)
449 449
 	print_sll_protocol(sa_ll);
450 450
 	PRINT_FIELD_IFINDEX(", ", *sa_ll, sll_ifindex);
451 451
 	tprints(", sll_hatype=");
452
-	printxval_search(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
452
+	printxval(arp_hardware_types, sa_ll->sll_hatype, "ARPHRD_???");
453 453
 	tprints(", sll_pkttype=");
454
-	printxval_index(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
454
+	printxval(af_packet_types, sa_ll->sll_pkttype, "PACKET_???");
455 455
 	tprintf(", sll_halen=%u", sa_ll->sll_halen);
456 456
 	if (sa_ll->sll_halen) {
457 457
 		const unsigned int oob_halen =
@@ -603,8 +603,7 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
603 603
 		const struct sockaddr_hci *const hci = buf;
604 604
 		tprintf("hci_dev=htobs(%hu), hci_channel=",
605 605
 			btohs(hci->hci_dev));
606
-		printxval_index(hci_channels, hci->hci_channel,
607
-				"HCI_CHANNEL_???");
606
+		printxval(hci_channels, hci->hci_channel, "HCI_CHANNEL_???");
608 607
 		break;
609 608
 	}
610 609
 	case sizeof(struct sockaddr_sco): {
@@ -630,8 +629,8 @@ print_sockaddr_data_bt(const void *const buf, const int addrlen)
630 629
 
631 630
 		if (addrlen == sizeof(struct sockaddr_l2)) {
632 631
 			tprints(", l2_bdaddr_type=");
633
-			printxval_index(bdaddr_types, l2->l2_bdaddr_type,
634
-					"BDADDR_???");
632
+			printxval(bdaddr_types, l2->l2_bdaddr_type,
633
+				  "BDADDR_???");
635 634
 		}
636 635
 
637 636
 		break;
@@ -665,7 +664,7 @@ print_sockaddr(const void *const buf, const int addrlen)
665 664
 	const struct sockaddr *const sa = buf;
666 665
 
667 666
 	tprints("{sa_family=");
668
-	printxval_index(addrfams, sa->sa_family, "AF_???");
667
+	printxval(addrfams, sa->sa_family, "AF_???");
669 668
 
670 669
 	if (addrlen > (int) SIZEOF_SA_FAMILY) {
671 670
 		tprints(", ");

+ 4
- 4
tests/btrfs.c View File

@@ -886,9 +886,9 @@ btrfs_test_defrag_ioctls(void)
886 886
 static const char *
887 887
 xlookup(const struct xlat *xlat, const uint64_t val)
888 888
 {
889
-	for (; xlat->str != NULL; xlat++)
890
-		if (xlat->val == val)
891
-			return xlat->str;
889
+	for (size_t i = 0; i < xlat->size; i++)
890
+		if (xlat->data[i].val == val)
891
+			return xlat->data[i].str;
892 892
 	return NULL;
893 893
 }
894 894
 
@@ -2068,7 +2068,7 @@ btrfs_test_features_ioctls(void)
2068 2068
 static void
2069 2069
 btrfs_test_read_ioctls(void)
2070 2070
 {
2071
-	static const struct xlat btrfs_read_cmd[] = {
2071
+	static const struct xlat_data btrfs_read_cmd[] = {
2072 2072
 		XLAT(BTRFS_IOC_BALANCE_PROGRESS),
2073 2073
 		XLAT(BTRFS_IOC_FS_INFO),
2074 2074
 		XLAT(BTRFS_IOC_GET_FEATURES),

+ 1
- 1
tests/ioctl_block.c View File

@@ -24,7 +24,7 @@
24 24
 static const unsigned int magic = 0xdeadbeef;
25 25
 static const unsigned long lmagic = (unsigned long) 0xdeadbeefbadc0dedULL;
26 26
 
27
-static struct xlat block_argless[] = {
27
+static struct xlat_data block_argless[] = {
28 28
 	XLAT(BLKRRPART),
29 29
 	XLAT(BLKFLSBUF),
30 30
 #ifdef BLKTRACESTART

+ 1
- 1
tests/ioctl_rtc.c View File

@@ -34,7 +34,7 @@ print_rtc_time(const struct rtc_time *rt)
34 34
 #endif
35 35
 }
36 36
 
37
-static struct xlat rtc_argless[] = {
37
+static struct xlat_data rtc_argless[] = {
38 38
 	XLAT(RTC_AIE_OFF),
39 39
 	XLAT(RTC_PIE_ON),
40 40
 	XLAT(RTC_PIE_OFF),

+ 11
- 6
tests/printflags.c View File

@@ -17,21 +17,26 @@ int
17 17
 printflags(const struct xlat *xlat, unsigned long long flags,
18 18
 	   const char *const dflt)
19 19
 {
20
-	if (flags == 0 && xlat->val == 0 && xlat->str) {
21
-		fputs(xlat->str, stdout);
20
+	if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
21
+		fputs(xlat->data->str, stdout);
22 22
 		return 1;
23 23
 	}
24 24
 
25 25
 	int n;
26
+	size_t i = 0;
26 27
 	char sep = 0;
27
-	for (n = 0; xlat->str; xlat++) {
28
-		if (xlat->val && (flags & xlat->val) == xlat->val) {
28
+	const struct xlat_data *xd = xlat->data;
29
+	for (n = 0; i < xlat->size; xd++, i++) {
30
+		if (!xd->str)
31
+			continue;
32
+
33
+		if (xd->val && (flags & xd->val) == xd->val) {
29 34
 			if (sep)
30 35
 				putc(sep, stdout);
31 36
 			else
32 37
 				sep = '|';
33
-			fputs(xlat->str, stdout);
34
-			flags &= ~xlat->val;
38
+			fputs(xd->str, stdout);
39
+			flags &= ~xd->val;
35 40
 			n++;
36 41
 		}
37 42
 	}

+ 8
- 3
tests/printxval.c View File

@@ -17,9 +17,14 @@ int
17 17
 printxval(const struct xlat *xlat, unsigned long long val,
18 18
 	  const char *const dflt)
19 19
 {
20
-	for (; xlat->str; xlat++) {
21
-		if (xlat->val == val) {
22
-			fputs(xlat->str, stdout);
20
+	const struct xlat_data *xd = xlat->data;
21
+
22
+	for (size_t i = 0; i < xlat->size; i++, xd++) {
23
+		if (!xd->str)
24
+			continue;
25
+
26
+		if (xd->val == val) {
27
+			fputs(xd->str, stdout);
23 28
 			return 1;
24 29
 		}
25 30
 	}

+ 6
- 2
tests/prlimit64.c View File

@@ -44,9 +44,13 @@ main(void)
44 44
 	unsigned long pid =
45 45
 		(unsigned long) 0xdefaced00000000ULL | (unsigned) getpid();
46 46
 	uint64_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
47
-	const struct xlat *xlat;
47
+	const struct xlat_data *xlat;
48
+	size_t i = 0;
49
+
50
+	for (xlat = resources->data; i < resources->size; ++xlat, ++i) {
51
+		if (!xlat->str)
52
+			continue;
48 53
 
49
-	for (xlat = resources; xlat->str; ++xlat) {
50 54
 		unsigned long res = 0xfacefeed00000000ULL | xlat->val;
51 55
 		long rc = syscall(__NR_prlimit64, pid, res, 0, rlimit);
52 56
 		if (rc)

+ 6
- 2
tests/setrlimit.c View File

@@ -19,9 +19,13 @@ int
19 19
 main(void)
20 20
 {
21 21
 	kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
22
-	const struct xlat *xlat;
22
+	const struct xlat_data *xlat;
23
+	size_t i = 0;
24
+
25
+	for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
26
+		if (!xlat->str)
27
+			continue;
23 28
 
24
-	for (xlat = resources; xlat->str; ++xlat) {
25 29
 		unsigned long res = 0xfacefeed00000000ULL | xlat->val;
26 30
 		long rc = syscall(__NR_setrlimit, res, 0);
27 31
 # if XLAT_RAW

+ 5
- 5
tests/socketcall.c View File

@@ -22,9 +22,9 @@
22 22
 static const char *
23 23
 xlookup_uint(const struct xlat *xlat, const unsigned int val)
24 24
 {
25
-	for (; xlat->str != NULL; xlat++)
26
-		if (xlat->val == val)
27
-			return xlat->str;
25
+	for (size_t i = 0; i < xlat->size; i++)
26
+		if (xlat->data[i].val == val)
27
+			return xlat->data[i].str;
28 28
 	return NULL;
29 29
 }
30 30
 
@@ -52,8 +52,8 @@ test_socketcall(const int i, const void *const addr)
52 52
 int
53 53
 main(void)
54 54
 {
55
-	assert((unsigned) sc_min == socketcalls[0].val);
56
-	assert((unsigned) sc_max == socketcalls[ARRAY_SIZE(socketcalls) - 2].val);
55
+	assert((unsigned) sc_min == socketcalls->data[0].val);
56
+	assert((unsigned) sc_max == socketcalls->data[socketcalls->size - 1].val);
57 57
 
58 58
 	const unsigned long *const args = tail_alloc(sizeof(*args) * 6);
59 59
 	efault = tail_alloc(1) + 1;

+ 6
- 2
tests/xgetrlimit.c View File

@@ -77,9 +77,13 @@ int
77 77
 main(void)
78 78
 {
79 79
 	kernel_ulong_t *const rlimit = tail_alloc(sizeof(*rlimit) * 2);
80
-	const struct xlat *xlat;
80
+	const struct xlat_data *xlat;
81
+	size_t i;
82
+
83
+	for (xlat = resources->data, i = 0; i < resources->size; ++xlat, ++i) {
84
+		if (!xlat->str)
85
+			continue;
81 86
 
82
-	for (xlat = resources; xlat->str; ++xlat) {
83 87
 		unsigned long res = 0xfacefeed00000000ULL | xlat->val;
84 88
 		long rc = syscall(NR_GETRLIMIT, res, 0);
85 89
 		if (rc && ENOSYS == errno)

+ 3
- 4
tests/xstatfsx.c View File

@@ -34,10 +34,9 @@ static void
34 34
 print_statfs_type(const char *const prefix, const unsigned int magic)
35 35
 {
36 36
 	fputs(prefix, stdout);
37
-	unsigned int i;
38
-	for (i = 0; i < ARRAY_SIZE(fsmagic); ++i)
39
-		if (magic == fsmagic[i].val) {
40
-			fputs(fsmagic[i].str, stdout);
37
+	for (unsigned int i = 0; i < fsmagic->size; ++i)
38
+		if (magic == fsmagic->data[i].val) {
39
+			fputs(fsmagic->data[i].str, stdout);
41 40
 			return;
42 41
 		}
43 42
 	printf("%#x", magic);

+ 8
- 14
time.c View File

@@ -113,8 +113,7 @@ SYS_FUNC(nanosleep_time64)
113 113
 SYS_FUNC(getitimer)
114 114
 {
115 115
 	if (entering(tcp)) {
116
-		printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
117
-				"ITIMER_???");
116
+		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
118 117
 		tprints(", ");
119 118
 	} else {
120 119
 		print_itimerval(tcp, tcp->u_arg[1]);
@@ -126,8 +125,7 @@ SYS_FUNC(getitimer)
126 125
 SYS_FUNC(osf_getitimer)
127 126
 {
128 127
 	if (entering(tcp)) {
129
-		printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
130
-				"ITIMER_???");
128
+		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
131 129
 		tprints(", ");
132 130
 	} else {
133 131
 		print_itimerval32(tcp, tcp->u_arg[1]);
@@ -139,8 +137,7 @@ SYS_FUNC(osf_getitimer)
139 137
 SYS_FUNC(setitimer)
140 138
 {
141 139
 	if (entering(tcp)) {
142
-		printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
143
-				"ITIMER_???");
140
+		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
144 141
 		tprints(", ");
145 142
 		print_itimerval(tcp, tcp->u_arg[1]);
146 143
 		tprints(", ");
@@ -154,8 +151,7 @@ SYS_FUNC(setitimer)
154 151
 SYS_FUNC(osf_setitimer)
155 152
 {
156 153
 	if (entering(tcp)) {
157
-		printxval_index(itimer_which, (unsigned int) tcp->u_arg[0],
158
-				"ITIMER_???");
154
+		printxval(itimer_which, tcp->u_arg[0], "ITIMER_???");
159 155
 		tprints(", ");
160 156
 		print_itimerval32(tcp, tcp->u_arg[1]);
161 157
 		tprints(", ");
@@ -174,8 +170,7 @@ do_adjtimex(struct tcb *const tcp, const print_obj_by_addr_fn print_tx,
174 170
 {
175 171
 	if (print_tx(tcp, addr))
176 172
 		return 0;
177
-	tcp->auxstr = xlat_idx(adjtimex_state, ARRAY_SIZE(adjtimex_state) - 1,
178
-			       (kernel_ulong_t) tcp->u_rval);
173
+	tcp->auxstr = xlookup(adjtimex_state, (kernel_ulong_t) tcp->u_rval);
179 174
 	return RVAL_STR;
180 175
 }
181 176
 
@@ -228,9 +223,8 @@ printclockname(int clockid)
228 223
 					"MAKE_THREAD_CPUCLOCK" :
229 224
 					"MAKE_PROCESS_CPUCLOCK",
230 225
 				CPUCLOCK_PID(clockid));
231
-			printxval_index(cpuclocknames,
232
-					(unsigned int) clockid & CLOCKFD_MASK,
233
-					"CPUCLOCK_???");
226
+			printxval(cpuclocknames, clockid & CLOCKFD_MASK,
227
+				  "CPUCLOCK_???");
234 228
 			tprints(")");
235 229
 		}
236 230
 
@@ -238,7 +232,7 @@ printclockname(int clockid)
238 232
 			tprints(" */");
239 233
 	} else
240 234
 #endif
241
-		printxval_index(clocknames, clockid, "CLOCK_???");
235
+		printxval(clocknames, clockid, "CLOCK_???");
242 236
 }
243 237
 
244 238
 static int

+ 2
- 9
util.c View File

@@ -1239,7 +1239,6 @@ print_array_ex(struct tcb *const tcp,
1239 1239
 	       void *const opaque_data,
1240 1240
 	       unsigned int flags,
1241 1241
 	       const struct xlat *index_xlat,
1242
-	       size_t index_xlat_size,
1243 1242
 	       const char *index_dflt)
1244 1243
 {
1245 1244
 	if (!start_addr) {
@@ -1295,15 +1294,9 @@ print_array_ex(struct tcb *const tcp,
1295 1294
 
1296 1295
 			if (!index_xlat) {
1297 1296
 				print_xlat_ex(idx, NULL, xlat_style);
1298
-			} else if (flags & PAF_INDEX_XLAT_VALUE_INDEXED) {
1299
-				printxval_indexn_ex(index_xlat,
1300
-						    index_xlat_size, idx,
1301
-						    index_dflt, xlat_style);
1302 1297
 			} else {
1303
-				printxvals_ex(idx, index_dflt, xlat_style,
1304
-					      (flags & PAF_INDEX_XLAT_SORTED)
1305
-						&& idx ? NULL : index_xlat,
1306
-					      NULL);
1298
+				printxval_ex(idx ? NULL : index_xlat, idx,
1299
+					     index_dflt, xlat_style);
1307 1300
 			}
1308 1301
 
1309 1302
 			tprints("] = ");

+ 149
- 144
xlat.c View File

@@ -50,49 +50,159 @@ print_xlat_val(uint64_t val, enum xlat_style style)
50 50
 	tprints(sprint_xlat_val(val, style));
51 51
 }
52 52
 
53
+static int
54
+xlat_bsearch_compare(const void *a, const void *b)
55
+{
56
+	const uint64_t val1 = *(const uint64_t *) a;
57
+	const uint64_t val2 = ((const struct xlat_data *) b)->val;
58
+	return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
59
+}
60
+
53 61
 const char *
54 62
 xlookup(const struct xlat *xlat, const uint64_t val)
55 63
 {
56
-	static const struct xlat *pos;
64
+	static const struct xlat *x;
65
+	static size_t idx;
66
+	const struct xlat_data *e;
57 67
 
58
-	if (xlat)
59
-		pos = xlat;
68
+	if (xlat) {
69
+		x = xlat;
70
+		idx = 0;
71
+	}
72
+
73
+	if (!x || !x->data)
74
+		return NULL;
75
+
76
+	switch (x->type) {
77
+	case XT_NORMAL:
78
+		for (; idx < x->size; idx++)
79
+			if (x->data[idx].val == val)
80
+				return x->data[idx].str;
81
+		break;
82
+
83
+	case XT_SORTED:
84
+		e = bsearch((const void *) &val,
85
+			    x->data + idx,
86
+			    x->size - idx,
87
+			    sizeof(x->data[0]),
88
+			    xlat_bsearch_compare);
89
+		if (e) {
90
+			idx = e - x->data;
91
+			return e->str;
92
+		}
93
+		break;
94
+
95
+	case XT_INDEXED:
96
+		if (val < x->size) {
97
+			if (val == x->data[val].val)
98
+				return x->data[val].str;
99
+			if (x->data[val].val == 0)
100
+				break; /* a hole in the index */
101
+			error_func_msg("Unexpected xlat value %" PRIu64
102
+				       " at index %" PRIu64 " (str %s)",
103
+				       x->data[val].val, val,
104
+				       x->data[val].str);
105
+		}
106
+		break;
107
+
108
+	default:
109
+		error_func_msg("Invalid xlat type: %#x", x->type);
110
+	}
60 111
 
61
-	for (; pos->str != NULL; pos++)
62
-		if (pos->val == val)
63
-			return pos->str;
64 112
 	return NULL;
65 113
 }
66 114
 
67
-static int
68
-xlat_bsearch_compare(const void *a, const void *b)
115
+static const char *
116
+xlat_search_eq_or_less(const struct xlat *xlat, uint64_t *val)
69 117
 {
70
-	const uint64_t val1 = *(const uint64_t *) a;
71
-	const uint64_t val2 = ((const struct xlat *) b)->val;
72
-	return (val1 > val2) ? 1 : (val1 < val2) ? -1 : 0;
118
+	const struct xlat_data *base = xlat->data;
119
+	const struct xlat_data *cur = xlat->data;
120
+	size_t nmemb = xlat->size;
121
+
122
+	for (; nmemb > 0; nmemb >>= 1) {
123
+		cur = base + (nmemb >> 1);
124
+
125
+		if (*val == cur->val)
126
+			return cur->str;
127
+
128
+		if (*val > cur->val) {
129
+			base = cur + 1;
130
+			nmemb--;
131
+		}
132
+	}
133
+
134
+	if (*val < cur->val) {
135
+		if (cur > xlat->data)
136
+			cur--;
137
+		else
138
+			return NULL;
139
+	}
140
+
141
+	*val = cur->val;
142
+	return cur->str;
73 143
 }
74 144
 
75 145
 const char *
76
-xlat_search(const struct xlat *xlat, const size_t nmemb, const uint64_t val)
146
+xlookup_le(const struct xlat *xlat, uint64_t *val)
77 147
 {
78
-	static const struct xlat *pos;
79
-	static size_t memb_left;
148
+	if (!xlat || !xlat->data)
149
+		return NULL;
80 150
 
81
-	if (xlat) {
82
-		pos = xlat;
83
-		memb_left = nmemb;
151
+	switch (xlat->type) {
152
+	case XT_SORTED:
153
+		return xlat_search_eq_or_less(xlat, val);
154
+
155
+#if 0 /* enable when used */
156
+	case XT_NORMAL: {
157
+		uint64_t best_hit = 0;
158
+		const char *str = NULL;
159
+
160
+		for (size_t idx = 0; idx < xlat->size; idx++) {
161
+			if (xlat->data[idx].val == *val)
162
+				return xlat->data[idx].str;
163
+
164
+			if (xlat->data[idx].val < *val
165
+			    && xlat->data[idx].val > best_hit) {
166
+				best_hit = xlat->data[idx].val;
167
+				str = xlat->data[idx].str;
168
+			}
169
+		}
170
+
171
+		*val = best_hit;
172
+		return str;
84 173
 	}
85 174
 
86
-	const struct xlat *e =
87
-		bsearch((const void *) &val,
88
-			pos, memb_left, sizeof(*pos), xlat_bsearch_compare);
175
+	case XT_INDEXED: {
176
+		size_t idx = *val;
89 177
 
90
-	if (e) {
91
-		memb_left -= e - pos;
92
-		return e->str;
93
-	} else {
178
+		if (idx >= xlat->size) {
179
+			if (!xlat->size)
180
+				return NULL;
181
+
182
+			idx = xlat->size - 1;
183
+		}
184
+
185
+		do {
186
+			if (idx == xlat->data[idx].val && xlat->data[idx].str) {
187
+				*val = idx;
188
+				return xlat->data[idx].str;
189
+			}
190
+			if (xlat->data[idx].val == 0)
191
+				continue; /* a hole in the index */
192
+			error_func_msg("Unexpected xlat value %" PRIu64
193
+				       " at index %zu (str %s)",
194
+				       xlat->data[idx].val, idx,
195
+				       xlat->data[idx].str);
196
+		} while (idx--);
94 197
 		return NULL;
95 198
 	}
199
+#endif
200
+
201
+	default:
202
+		error_func_msg("Invalid xlat type: %#x", xlat->type);
203
+	}
204
+
205
+	return NULL;
96 206
 }
97 207
 
98 208
 /**
@@ -180,94 +290,6 @@ sprintxval_ex(char *const buf, const size_t size, const struct xlat *const x,
180 290
 	return xsnprintf(buf, size, "%s", sprint_xlat_val(val, style));
181 291
 }
182 292
 
183
-/**
184
- * Print entry in sorted struct xlat table, if it is there.
185
- *
186
- * @param xlat      Pointer to an array of xlat values (not terminated with
187
- *                  XLAT_END).
188
- * @param xlat_size Number of xlat elements present in array (usually ARRAY_SIZE
189
- *                  if array is declared in the unit's scope and not
190
- *                  terminated with XLAT_END).
191
- * @param val       Value to search literal representation for.
192
- * @param dflt      String (abbreviated in comment syntax) which should be
193
- *                  emitted if no appropriate xlat value has been found.
194
- * @param style     Style in which xlat value should be printed.
195
- * @param fn        Search function.
196
- * @return          1 if appropriate xlat value has been found, 0
197
- *                  otherwise.
198
- */
199
-static int
200
-printxval_sized(const struct xlat *xlat, size_t xlat_size, uint64_t val,
201
-		const char *dflt, enum xlat_style style,
202
-		const char *(* fn)(const struct xlat *, size_t, uint64_t))
203
-{
204
-	style = get_xlat_style(style);
205
-
206
-	if (xlat_verbose(style) == XLAT_STYLE_RAW) {
207
-		print_xlat_val(val, style);
208
-		return 0;
209
-	}
210
-
211
-	const char *s = fn(xlat, xlat_size, val);
212
-
213
-	if (s) {
214
-		if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
215
-			print_xlat_val(val, style);
216
-			tprints_comment(s);
217
-		} else {
218
-			tprints(s);
219
-		}
220
-		return 1;
221
-	}
222
-
223
-	print_xlat_val(val, style);
224
-	tprints_comment(dflt);
225
-
226
-	return 0;
227
-}
228
-
229
-int
230
-printxval_searchn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
231
-		     const char *dflt, enum xlat_style style)
232
-{
233
-	return printxval_sized(xlat, xlat_size, val, dflt, style,
234
-				  xlat_search);
235
-}
236
-
237
-const char *
238
-xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val)
239
-{
240
-	static const struct xlat *pos;
241
-	static size_t memb_left;
242
-
243
-	if (xlat) {
244
-		pos = xlat;
245
-		memb_left = nmemb;
246
-	}
247
-
248
-	if (val >= memb_left)
249
-		return NULL;
250
-
251
-	if (val != pos[val].val) {
252
-		if (pos[val].val == 0)
253
-			return NULL;	/* a hole in the index */
254
-
255
-		error_func_msg("Unexpected xlat value %" PRIu64
256
-			       " at index %" PRIu64,
257
-			       pos[val].val, val);
258
-		return NULL;
259
-	}
260
-
261
-	return pos[val].str;
262
-}
263
-
264
-int
265
-printxval_indexn_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
266
-		    const char *dflt, enum xlat_style style)
267
-{
268
-	return printxval_sized(xlat, xlat_size, val, dflt, style, xlat_idx);
269
-}
270
-
271 293
 /*
272 294
  * Interpret `xlat' as an array of flags.
273 295
  * Print to static string the entries whose bits are on in `flags'
@@ -313,14 +335,14 @@ sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
313 335
 		return outstr;
314 336
 	}
315 337
 
316
-	if (flags == 0 && xlat->val == 0 && xlat->str) {
338
+	if (flags == 0 && xlat->data->val == 0 && xlat->data->str) {
317 339
 		if (sep)
318 340
 			*outptr++ = sep;
319 341
 		if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
320 342
 			outptr = xappendstr(outstr, outptr, "0 /* %s */",
321
-					    xlat->str);
343
+					    xlat->data->str);
322 344
 		} else {
323
-			strcpy(outptr, xlat->str);
345
+			strcpy(outptr, xlat->data->str);
324 346
 		}
325 347
 
326 348
 		return outstr;
@@ -335,18 +357,19 @@ sprintflags_ex(const char *prefix, const struct xlat *xlat, uint64_t flags,
335 357
 				    sprint_xlat_val(flags, style));
336 358
 	}
337 359
 
338
-	for (; flags && xlat->str; xlat++) {
339
-		if (xlat->val && (flags & xlat->val) == xlat->val) {
360
+	for (size_t idx = 0; flags && idx < xlat->size; idx++) {
361
+		if (xlat->data[idx].val && xlat->data[idx].str
362
+		    && (flags & xlat->data[idx].val) == xlat->data[idx].val) {
340 363
 			if (sep) {
341 364
 				*outptr++ = sep;
342 365
 			} else if (xlat_verbose(style) == XLAT_STYLE_VERBOSE) {
343 366
 				outptr = stpcpy(outptr, " /* ");
344 367
 			}
345 368
 
346
-			outptr = stpcpy(outptr, xlat->str);
369
+			outptr = stpcpy(outptr, xlat->data[idx].str);
347 370
 			found = 1;
348 371
 			sep = '|';
349
-			flags &= ~xlat->val;
372
+			flags &= ~xlat->data[idx].val;
350 373
 		}
351 374
 	}
352 375
 
@@ -418,15 +441,17 @@ printflags_ex(uint64_t flags, const char *dflt, enum xlat_style style,
418 441
 
419 442
 	va_start(args, xlat);
420 443
 	for (; xlat; xlat = va_arg(args, const struct xlat *)) {
421
-		for (; (flags || !n) && xlat->str; ++xlat) {
422
-			if ((flags == xlat->val) ||
423
-			    (xlat->val && (flags & xlat->val) == xlat->val)) {
444
+		for (size_t idx = 0; (flags || !n) && idx < xlat->size; ++idx) {
445
+			uint64_t v = xlat->data[idx].val;
446
+			if (xlat->data[idx].str
447
+			    && ((flags == v) || (v && (flags & v) == v))) {
424 448
 				if (xlat_verbose(style) == XLAT_STYLE_VERBOSE
425 449
 				    && !flags)
426 450
 					tprints("0");
427 451
 				tprintf("%s%s",
428
-					(n++ ? "|" : init_sep), xlat->str);
429
-				flags &= ~xlat->val;
452
+					(n++ ? "|" : init_sep),
453
+					xlat->data[idx].str);
454
+				flags &= ~v;
430 455
 			}
431 456
 			if (!flags)
432 457
 				break;
@@ -489,23 +514,3 @@ print_xlat_ex(const uint64_t val, const char *str, enum xlat_style style)
489 514
 		tprints_comment(str);
490 515
 	}
491 516
 }
492
-
493
-void
494
-printxval_dispatch_ex(const struct xlat *xlat, size_t xlat_size, uint64_t val,
495
-		      const char *dflt, enum xlat_type xt,
496
-		      enum xlat_style style)
497
-{
498
-	switch (xt) {
499
-	case XT_NORMAL:
500
-		printxvals_ex(val, dflt, style, xlat, NULL);
501
-		break;
502
-
503
-	case XT_SORTED:
504
-		printxval_searchn_ex(xlat, xlat_size, val, dflt, style);
505
-		break;
506
-
507
-	case XT_INDEXED:
508
-		printxval_indexn_ex(xlat, xlat_size, val, dflt, style);
509
-		break;
510
-	}
511
-}

+ 7
- 1
xlat.h View File

@@ -48,11 +48,17 @@ enum xlat_style {
48 48
 # define XLAT_STYLE_MASK ((1 << XLAT_STYLE_SPEC_BITS) - 1)
49 49
 };
50 50
 
51
-struct xlat {
51
+struct xlat_data {
52 52
 	uint64_t val;
53 53
 	const char *str;
54 54
 };
55 55
 
56
+struct xlat {
57
+	const struct xlat_data *data;
58
+	uint32_t size;
59
+	enum xlat_type type;
60
+};
61
+
56 62
 # define XLAT(val)			{ (unsigned)(val), #val }
57 63
 # define XLAT_PAIR(val, str)		{ (unsigned)(val), str  }
58 64
 # define XLAT_TYPE(type, val)		{     (type)(val), #val }

+ 1
- 0
xlat/af_packet_versions.in View File

@@ -1,3 +1,4 @@
1
+#value_indexed
1 2
 TPACKET_V1	0
2 3
 TPACKET_V2	1
3 4
 TPACKET_V3	2

+ 1
- 1
xlat/arp_hardware_types.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2g */
1
+#sorted sort -k2,2g
2 2
 ARPHRD_NETROM			0
3 3
 ARPHRD_ETHER			1
4 4
 ARPHRD_EETHER			2

+ 1
- 1
xlat/ax25_protocols.in View File

@@ -1,4 +1,4 @@
1
-/* sorted */
1
+#sorted
2 2
 /* Those are pulled from include/net/ax25.h, they should be part of UAPI */
3 3
 AX25_P_ROSE		0x01
4 4
 AX25_P_VJCOMP		0x06	/* Compressed TCP/IP packet   */

+ 1
- 1
xlat/bluetooth_l2_cid.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 L2CAP_CID_SIGNALING	0x0001
3 3
 L2CAP_CID_CONN_LESS	0x0002
4 4
 L2CAP_CID_A2MP		0x0003

+ 1
- 1
xlat/bluetooth_l2_psm.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 L2CAP_PSM_SDP           0x0001
3 3
 L2CAP_PSM_RFCOMM        0x0003
4 4
 L2CAP_PSM_3DSP          0x0021

+ 1
- 1
xlat/ethernet_protocols.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 ETH_P_802_3	0x0001		/* Dummy type for 802.3 frames  */
3 3
 ETH_P_AX25	0x0002		/* Dummy protocol id for AX.25  */
4 4
 ETH_P_ALL	0x0003		/* Every packet (be careful!!!) */

+ 1
- 1
xlat/evdev_ff_types.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 FF_RUMBLE       0x50
3 3
 FF_PERIODIC     0x51
4 4
 FF_CONSTANT     0x52

+ 1
- 1
xlat/fsmagic.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 { 0x0000002f,	"QNX4_SUPER_MAGIC"	},
3 3
 { 0x00000187,	"AUTOFS_SUPER_MAGIC"	},
4 4
 { 0x00001373,	"DEVFS_SUPER_MAGIC"	},

+ 28
- 7
xlat/gen.sh View File

@@ -112,6 +112,7 @@ gen_header()
112 112
 	local mpers="${0%/*}/../mpers_xlat.h"
113 113
 	local decl="extern const struct xlat ${name}[];"
114 114
 	local in_defs= in_mpers=
115
+	local xlat_type="XT_NORMAL"
115 116
 
116 117
 	value_indexed=0
117 118
 
@@ -152,8 +153,12 @@ gen_header()
152 153
 		'#val_type '*)
153 154
 			# to be processed during 2nd pass
154 155
 			;;
156
+		'#sorted'|'#sorted '*)
157
+			xlat_type="XT_SORTED"
158
+			;;
155 159
 		'#value_indexed')
156 160
 			value_indexed=1
161
+			xlat_type="XT_INDEXED"
157 162
 			;;
158 163
 		'#'*)
159 164
 			echo "${line}"
@@ -184,9 +189,6 @@ gen_header()
184 189
 
185 190
 			# else
186 191
 
187
-			#  if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
188
-			static
189
-			#  endif
190 192
 		EOF
191 193
 	else
192 194
 		cat <<-EOF
@@ -196,11 +198,10 @@ gen_header()
196 198
 
197 199
 			# else
198 200
 
199
-			static
200 201
 		EOF
201 202
 	fi
202 203
 
203
-	echo "const struct xlat ${name}[] = {"
204
+	echo "static const struct xlat_data ${name}_xdata[] = {"
204 205
 
205 206
 	unconditional= val_type=
206 207
 	# 2nd pass: output everything.
@@ -219,6 +220,8 @@ gen_header()
219 220
 		'#unconditional')
220 221
 			unconditional=1
221 222
 			;;
223
+		'#sorted'|'#sorted '*)
224
+			;;
222 225
 		'#value_indexed')
223 226
 			;;
224 227
 		'#val_type '*)
@@ -246,10 +249,28 @@ gen_header()
246 249
 			;;
247 250
 		esac
248 251
 	done < "${input}"
249
-	echo ' XLAT_END'
252
+	echo '};'
253
+
254
+	if [ -n "$in_defs" ]; then
255
+		:
256
+	elif [ -n "$in_mpers" ]; then
257
+		cat <<-EOF
258
+			#  if !(defined HAVE_M32_MPERS || defined HAVE_MX32_MPERS)
259
+			static
260
+			#  endif
261
+		EOF
262
+	else
263
+		cat <<-EOF
264
+			static
265
+		EOF
266
+	fi
250 267
 
251 268
 	cat <<-EOF
252
-		};
269
+		const struct xlat ${name}[1] = { {
270
+			 .data = ${name}_xdata,
271
+			 .size = ARRAY_SIZE(${name}_xdata),
272
+			 .type = ${xlat_type},
273
+		} };
253 274
 
254 275
 		# endif /* !IN_MPERS */
255 276
 

+ 1
- 1
xlat/hw_breakpoint_type.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 HW_BREAKPOINT_EMPTY 0
3 3
 HW_BREAKPOINT_R 1
4 4
 HW_BREAKPOINT_W 2

+ 1
- 1
xlat/iffflags.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k4,4g */
1
+#sorted sort -k4,4g
2 2
 IFF_UP		(1 << 0)
3 3
 IFF_BROADCAST	(1 << 1)
4 4
 IFF_DEBUG	(1 << 2)

+ 1
- 1
xlat/inet6_if_flags.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2g */
1
+#sorted sort -k2,2g
2 2
 IF_RS_SENT	0x10
3 3
 IF_RA_RCVD	0x20
4 4
 IF_RA_MANAGED	0x40

+ 1
- 1
xlat/inet_protocols.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 IPPROTO_IP		0
3 3
 IPPROTO_ICMP		1
4 4
 IPPROTO_IGMP		2

+ 1
- 1
xlat/msgctl_flags.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2g */
1
+#sorted sort -k2,2g
2 2
 IPC_RMID 0
3 3
 IPC_SET 1
4 4
 IPC_STAT 2

+ 1
- 1
xlat/perf_hw_cache_id.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_COUNT_HW_CACHE_L1D  0
3 3
 PERF_COUNT_HW_CACHE_L1I  1
4 4
 PERF_COUNT_HW_CACHE_LL   2

+ 1
- 1
xlat/perf_hw_cache_op_id.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_COUNT_HW_CACHE_OP_READ     0
3 3
 PERF_COUNT_HW_CACHE_OP_WRITE    1
4 4
 PERF_COUNT_HW_CACHE_OP_PREFETCH 2

+ 1
- 1
xlat/perf_hw_cache_op_result_id.in View File

@@ -1,3 +1,3 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_COUNT_HW_CACHE_RESULT_ACCESS 0
3 3
 PERF_COUNT_HW_CACHE_RESULT_MISS   1

+ 1
- 1
xlat/perf_hw_id.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_COUNT_HW_CPU_CYCLES               0
3 3
 PERF_COUNT_HW_INSTRUCTIONS             1
4 4
 PERF_COUNT_HW_CACHE_REFERENCES         2

+ 1
- 1
xlat/perf_sw_ids.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_COUNT_SW_CPU_CLOCK         0
3 3
 PERF_COUNT_SW_TASK_CLOCK        1
4 4
 PERF_COUNT_SW_PAGE_FAULTS       2

+ 1
- 1
xlat/perf_type_id.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 PERF_TYPE_HARDWARE    0
3 3
 PERF_TYPE_SOFTWARE    1
4 4
 PERF_TYPE_TRACEPOINT  2

+ 1
- 1
xlat/routing_protocols.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 RTPROT_UNSPEC	0
3 3
 RTPROT_REDIRECT	1
4 4
 RTPROT_KERNEL	2

+ 1
- 1
xlat/semctl_flags.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2g */
1
+#sorted sort -k2,2g
2 2
 IPC_RMID 0
3 3
 IPC_SET 1
4 4
 IPC_STAT 2

+ 1
- 1
xlat/shmctl_flags.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2g */
1
+#sorted sort -k2,2g
2 2
 IPC_RMID 0
3 3
 IPC_SET 1
4 4
 IPC_STAT 2

+ 1
- 1
xlat/smc_decl_codes.in View File

@@ -1,4 +1,4 @@
1
-/* sorted */
1
+#sorted
2 2
 SMC_CLC_DECL_MEM	0x01010000
3 3
 SMC_CLC_DECL_TIMEOUT_CL	0x02010000
4 4
 SMC_CLC_DECL_TIMEOUT_AL	0x02020000

+ 1
- 1
xlat/sock_ax25_options.in View File

@@ -1,4 +1,4 @@
1
-/* sorted */
1
+#sorted
2 2
 AX25_WINDOW	1
3 3
 AX25_T1		2
4 4
 AX25_N2		3

+ 1
- 1
xlat/sock_bluetooth_options.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 BT_SECURITY		4
3 3
 BT_DEFER_SETUP		7
4 4
 BT_FLUSHABLE		8

+ 1
- 1
xlat/sock_dccp_options.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 DCCP_SOCKOPT_PACKET_SIZE	1
3 3
 DCCP_SOCKOPT_SERVICE		2
4 4
 DCCP_SOCKOPT_CHANGE_L		3

+ 1
- 1
xlat/sock_tipc_options.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 TIPC_IMPORTANCE		127
3 3
 TIPC_SRC_DROPPABLE	128
4 4
 TIPC_DEST_DROPPABLE	129

+ 1
- 1
xlat/socketlayers.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2n */
1
+#sorted sort -k2,2n
2 2
 SOL_IP		0
3 3
 #if !(defined __alpha__ || defined __hppa__ || defined __mips__ || defined __sparc__)
4 4
 SOL_SOCKET	1

+ 1
- 1
xlat/v4l2_control_classes.in View File

@@ -1,4 +1,4 @@
1
-/* sort -k2,2 */
1
+#sorted sort -k2,2
2 2
 V4L2_CTRL_CLASS_USER		0x00980000	/* Old-style 'user' controls */
3 3
 V4L2_CTRL_CLASS_MPEG		0x00990000	/* MPEG-compression controls */
4 4
 V4L2_CTRL_CLASS_CAMERA		0x009a0000	/* Camera class controls */

+ 1
- 1
xlat/v4l2_pix_fmts.in View File

@@ -1,4 +1,4 @@
1
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
1
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
2 2
 V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10  Greyscale     */
3 3
 V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale     */
4 4
 V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*  4  Greyscale     */

+ 1
- 1
xlat/v4l2_sdr_fmts.in View File

@@ -1,4 +1,4 @@
1
-/* sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2- */
1
+#sorted sed -rn 's/.*v4l2_fourcc(_be)?\('"'(.)', '(.)', '(.)', '(.)'"'\).*/\10\5\4\3\2\t\0/p' |LC_COLLATE=C sort -k1,1 -t' ' |cut -f2-
2 2
 V4L2_SDR_FMT_PCU20BE      v4l2_fourcc('P', 'C', '2', '0') /* planar complex u20be */
3 3
 V4L2_SDR_FMT_RU12LE       v4l2_fourcc('R', 'U', '1', '2') /* real u12le */
4 4
 V4L2_SDR_FMT_CS14LE       v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */

Loading…
Cancel
Save