[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 07/10] bsd-user: common routine do_freebsd_sysctl_oid for all sysc
From: |
Warner Losh |
Subject: |
[PULL 07/10] bsd-user: common routine do_freebsd_sysctl_oid for all sysctl variants |
Date: |
Wed, 1 Mar 2023 11:23:50 -0700 |
From: Juergen Lock <nox@jelal.kn-bremen.de>
do_freebsd_sysctl_oid filters out some of the binary and special sysctls
where host != target. None of the sysctls that have to be translated from
host to target are handled here.
Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de>
Co-Authored-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Co-Authored-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
bsd-user/freebsd/os-sys.c | 90 +++++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 4 deletions(-)
diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
index 8bd1db69410..625018b185b 100644
--- a/bsd-user/freebsd/os-sys.c
+++ b/bsd-user/freebsd/os-sys.c
@@ -112,7 +112,7 @@ static abi_ulong h2g_ulong_sat(u_long ul)
* sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt() (compare to
* src/sbin/sysctl/sysctl.c)
*/
-static int G_GNUC_UNUSED oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
+static int oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
{
int qoid[CTL_MAXNAME + 2];
uint8_t buf[BUFSIZ];
@@ -154,7 +154,7 @@ static int G_GNUC_UNUSED oidfmt(int *oid, int len, char
*fmt, uint32_t *kind)
*
* For opaque data, per sysctl OID converts take care of it.
*/
-static void G_GNUC_UNUSED h2g_old_sysctl(void *holdp, size_t *holdlen,
uint32_t kind)
+static void h2g_old_sysctl(void *holdp, size_t *holdlen, uint32_t kind)
{
size_t len;
int hlen, glen;
@@ -233,7 +233,7 @@ static void G_GNUC_UNUSED h2g_old_sysctl(void *holdp,
size_t *holdlen, uint32_t
/*
* Convert the undocmented name2oid sysctl data for the target.
*/
-static inline void G_GNUC_UNUSED sysctl_name2oid(uint32_t *holdp, size_t
holdlen)
+static inline void sysctl_name2oid(uint32_t *holdp, size_t holdlen)
{
size_t i, num = holdlen / sizeof(uint32_t);
@@ -242,12 +242,94 @@ static inline void G_GNUC_UNUSED sysctl_name2oid(uint32_t
*holdp, size_t holdlen
}
}
-static inline void G_GNUC_UNUSED sysctl_oidfmt(uint32_t *holdp)
+static inline void sysctl_oidfmt(uint32_t *holdp)
{
/* byte swap the kind */
holdp[0] = tswap32(holdp[0]);
}
+static abi_long G_GNUC_UNUSED do_freebsd_sysctl_oid(CPUArchState *env, int32_t
*snamep,
+ int32_t namelen, void *holdp, size_t *holdlenp, void *hnewp,
+ size_t newlen)
+{
+ uint32_t kind = 0;
+ abi_long ret;
+ size_t holdlen, oldlen;
+#ifdef TARGET_ABI32
+ void *old_holdp;
+#endif
+
+ holdlen = oldlen = *holdlenp;
+ oidfmt(snamep, namelen, NULL, &kind);
+
+ /* Handle some arch/emulator dependent sysctl()'s here. */
+
+#ifdef TARGET_ABI32
+ /*
+ * For long and ulong with a 64-bit host and a 32-bit target we have to do
+ * special things. holdlen here is the length provided by the target to the
+ * system call. So we allocate a buffer twice as large because longs are
+ * twice as big on the host which will be writing them. In h2g_old_sysctl
+ * we'll adjust them and adjust the length.
+ */
+ if (kind == CTLTYPE_LONG || kind == CTLTYPE_ULONG) {
+ old_holdp = holdp;
+ holdlen = holdlen * 2;
+ holdp = g_malloc(holdlen);
+ }
+#endif
+
+ ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
+ if (!ret && (holdp != 0)) {
+
+ if (snamep[0] == CTL_SYSCTL) {
+ switch (snamep[1]) {
+ case CTL_SYSCTL_NEXT:
+ case CTL_SYSCTL_NAME2OID:
+ case CTL_SYSCTL_NEXTNOSKIP:
+ /*
+ * All of these return an OID array, so we need to convert to
+ * target.
+ */
+ sysctl_name2oid(holdp, holdlen);
+ break;
+
+ case CTL_SYSCTL_OIDFMT:
+ /* Handle oidfmt */
+ sysctl_oidfmt(holdp);
+ break;
+ case CTL_SYSCTL_OIDDESCR:
+ case CTL_SYSCTL_OIDLABEL:
+ default:
+ /* Handle it based on the type */
+ h2g_old_sysctl(holdp, &holdlen, kind);
+ /* NB: None of these are LONG or ULONG */
+ break;
+ }
+ } else {
+ /*
+ * Need to convert from host to target. All the weird special cases
+ * are handled above.
+ */
+ h2g_old_sysctl(holdp, &holdlen, kind);
+#ifdef TARGET_ABI32
+ /*
+ * For the 32-bit on 64-bit case, for longs we need to copy the
+ * now-converted buffer to the target and free the buffer.
+ */
+ if (kind == CTLTYPE_LONG || kind == CTLTYPE_ULONG) {
+ memcpy(old_holdp, holdp, holdlen);
+ g_free(holdp);
+ holdp = old_holdp;
+ }
+#endif
+ }
+ }
+
+ *holdlenp = holdlen;
+ return ret;
+}
+
/* sysarch() is architecture dependent. */
abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
{
--
2.39.1
- [PULL 00/10] Bsd user 2023q1 patches, Warner Losh, 2023/03/01
- [PULL 01/10] bsd-user: Don't truncate the return value from freebsd_syscall, Warner Losh, 2023/03/01
- [PULL 02/10] build: Don't specify -no-pie for --static user-mode programs, Warner Losh, 2023/03/01
- [PULL 03/10] bsd-user: Add sysarch syscall, Warner Losh, 2023/03/01
- [PULL 04/10] bsd-user: various helper routines for sysctl, Warner Losh, 2023/03/01
- [PULL 05/10] bsd-user: Helper routines oidfmt, Warner Losh, 2023/03/01
- [PULL 06/10] bsd-user: sysctl helper funtions: sysctl_name2oid and sysctl_oidfmt, Warner Losh, 2023/03/01
- [PULL 07/10] bsd-user: common routine do_freebsd_sysctl_oid for all sysctl variants,
Warner Losh <=
- [PULL 08/10] bsd-user: Start translation of arch-specific sysctls, Warner Losh, 2023/03/01
- [PULL 09/10] bsd-user: do_freebsd_sysctl helper for sysctl(2), Warner Losh, 2023/03/01
- [PULL 10/10] bsd-user: implement sysctlbyname(2), Warner Losh, 2023/03/01
- Re: [PULL 00/10] Bsd user 2023q1 patches, Peter Maydell, 2023/03/02