Rather than using a zero tuple to end the table, use a macro
to apply ARRAY_SIZE and pass that on to the convert functions.
This fixes two bugs in which the conversion functions required
that both the target and host masks be non-zero in order to
continue, rather than require both target and host masks be
zero in order to terminate.
This affected mmap_flags_tbl when the host does not support
all of the flags we wish to convert (e.g. MAP_UNINITIALIZED).
Mapping these flags to zero is good enough, and matches how
the kernel ignores bits that are unknown.
Fixes:
4b840f96 ("linux-user: Populate more bits in mmap_flags_tbl")
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
}
/* So far all target and host bitmasks are the same */
+#undef target_to_host_bitmask
#define target_to_host_bitmask(x, tbl) (x)
+#undef host_to_target_bitmask
#define host_to_target_bitmask(x, tbl) (x)
#endif /* SYSCALL_DEFS_H */
}
}
-unsigned int target_to_host_bitmask(unsigned int target_mask,
- const bitmask_transtbl * trans_tbl);
-unsigned int host_to_target_bitmask(unsigned int host_mask,
- const bitmask_transtbl * trans_tbl);
+unsigned int target_to_host_bitmask_len(unsigned int target_mask,
+ const bitmask_transtbl *trans_tbl,
+ size_t trans_len);
+unsigned int host_to_target_bitmask_len(unsigned int host_mask,
+ const bitmask_transtbl * trans_tbl,
+ size_t trans_len);
+
+#define target_to_host_bitmask(M, T) \
+ target_to_host_bitmask_len(M, T, ARRAY_SIZE(T))
+#define host_to_target_bitmask(M, T) \
+ host_to_target_bitmask_len(M, T, ARRAY_SIZE(T))
void thunk_init(unsigned int max_structs);
#if TARGET_O_LARGEFILE != 0 || O_LARGEFILE != 0
{ TARGET_O_LARGEFILE, TARGET_O_LARGEFILE, O_LARGEFILE, O_LARGEFILE, },
#endif
- { 0, 0, 0, 0 }
};
_syscall2(int, sys_getcwd1, char *, buf, size_t, size)
{ TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF },
{ TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL },
{ TARGET_IUTF8, TARGET_IUTF8, IUTF8, IUTF8},
- { 0, 0, 0, 0 }
};
static const bitmask_transtbl oflag_tbl[] = {
{ TARGET_VTDLY, TARGET_VT1, VTDLY, VT1 },
{ TARGET_FFDLY, TARGET_FF0, FFDLY, FF0 },
{ TARGET_FFDLY, TARGET_FF1, FFDLY, FF1 },
- { 0, 0, 0, 0 }
};
static const bitmask_transtbl cflag_tbl[] = {
{ TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL },
{ TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL },
{ TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS },
- { 0, 0, 0, 0 }
};
static const bitmask_transtbl lflag_tbl[] = {
{ TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN },
{ TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN },
{ TARGET_EXTPROC, TARGET_EXTPROC, EXTPROC, EXTPROC},
- { 0, 0, 0, 0 }
};
static void target_to_host_termios (void *dst, const void *src)
MAP_FIXED_NOREPLACE, MAP_FIXED_NOREPLACE },
{ TARGET_MAP_UNINITIALIZED, TARGET_MAP_UNINITIALIZED,
MAP_UNINITIALIZED, MAP_UNINITIALIZED },
- { 0, 0, 0, 0 }
};
/*
/* Utility function: Table-driven functions to translate bitmasks
* between host and target formats
*/
-unsigned int target_to_host_bitmask(unsigned int target_mask,
- const bitmask_transtbl * trans_tbl)
+unsigned int target_to_host_bitmask_len(unsigned int target_mask,
+ const bitmask_transtbl *tbl,
+ size_t len)
{
- const bitmask_transtbl *btp;
unsigned int host_mask = 0;
- for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) {
- if ((target_mask & btp->target_mask) == btp->target_bits) {
- host_mask |= btp->host_bits;
+ for (size_t i = 0; i < len; ++i) {
+ if ((target_mask & tbl[i].target_mask) == tbl[i].target_bits) {
+ host_mask |= tbl[i].host_bits;
}
}
return host_mask;
}
-unsigned int host_to_target_bitmask(unsigned int host_mask,
- const bitmask_transtbl * trans_tbl)
+unsigned int host_to_target_bitmask_len(unsigned int host_mask,
+ const bitmask_transtbl *tbl,
+ size_t len)
{
- const bitmask_transtbl *btp;
unsigned int target_mask = 0;
- for (btp = trans_tbl; btp->target_mask && btp->host_mask; btp++) {
- if ((host_mask & btp->host_mask) == btp->host_bits) {
- target_mask |= btp->target_bits;
+ for (size_t i = 0; i < len; ++i) {
+ if ((host_mask & tbl[i].host_mask) == tbl[i].host_bits) {
+ target_mask |= tbl[i].target_bits;
}
}
return target_mask;