summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_module.c
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2005-01-19 17:53:06 +0000
committerps <ps@FreeBSD.org>2005-01-19 17:53:06 +0000
commit87f1a6a1a638e5f82df94665d8fa0acb753c2e89 (patch)
tree089b9a68f02ef246b54157f386ca4cbae98890dc /sys/kern/kern_module.c
parentdb53196a486202b8b4ae0290034043f953c01491 (diff)
downloadFreeBSD-src-87f1a6a1a638e5f82df94665d8fa0acb753c2e89.zip
FreeBSD-src-87f1a6a1a638e5f82df94665d8fa0acb753c2e89.tar.gz
Add a 32bit syscall wrapper for modstat
Obtained from: Yahoo!
Diffstat (limited to 'sys/kern/kern_module.c')
-rw-r--r--sys/kern/kern_module.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c
index cecb2e1..e101e6b 100644
--- a/sys/kern/kern_module.c
+++ b/sys/kern/kern_module.c
@@ -24,6 +24,8 @@
* SUCH DAMAGE.
*/
+#include "opt_compat.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -410,3 +412,82 @@ modfind(struct thread *td, struct modfind_args *uap)
MOD_SUNLOCK;
return (error);
}
+
+#ifdef COMPAT_IA32
+#include <sys/mount.h>
+#include <compat/freebsd32/freebsd32_util.h>
+#include <compat/freebsd32/freebsd32.h>
+#include <compat/freebsd32/freebsd32_proto.h>
+
+typedef union modspecific32 {
+ int intval;
+ u_int32_t uintval;
+ int longval;
+ u_int32_t ulongval;
+} modspecific32_t;
+
+struct module_stat32 {
+ int version;
+ char name[MAXMODNAME];
+ int refs;
+ int id;
+ modspecific32_t data;
+};
+
+/*
+ * MPSAFE
+ */
+int
+freebsd32_modstat(struct thread *td, struct freebsd32_modstat_args *uap)
+{
+ module_t mod;
+ modspecific32_t data32;
+ int error = 0;
+ int id, namelen, refs, version;
+ struct module_stat32 *stat32;
+ char *name;
+
+ MOD_SLOCK;
+ mod = module_lookupbyid(uap->modid);
+ if (mod == NULL) {
+ MOD_SUNLOCK;
+ return (ENOENT);
+ }
+
+ id = mod->id;
+ refs = mod->refs;
+ name = mod->name;
+ CP(data32, mod->data, intval);
+ CP(data32, mod->data, uintval);
+ CP(data32, mod->data, longval);
+ CP(data32, mod->data, ulongval);
+ MOD_SUNLOCK;
+ stat32 = uap->stat;
+
+ if ((error = copyin(&stat32->version, &version, sizeof(version))) != 0)
+ return (error);
+ if (version != sizeof(struct module_stat_v1)
+ && version != sizeof(struct module_stat32))
+ return (EINVAL);
+ namelen = strlen(mod->name) + 1;
+ if (namelen > MAXMODNAME)
+ namelen = MAXMODNAME;
+ if ((error = copyout(name, &stat32->name[0], namelen)) != 0)
+ return (error);
+
+ if ((error = copyout(&refs, &stat32->refs, sizeof(int))) != 0)
+ return (error);
+ if ((error = copyout(&id, &stat32->id, sizeof(int))) != 0)
+ return (error);
+
+ /*
+ * >v1 stat includes module data.
+ */
+ if (version == sizeof(struct module_stat32))
+ if ((error = copyout(&data32, &stat32->data,
+ sizeof(data32))) != 0)
+ return (error);
+ td->td_retval[0] = 0;
+ return (error);
+}
+#endif
OpenPOWER on IntegriCloud