Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 May 2013 18:02:49 -0500
From:      Stacey Son <sson@FreeBSD.org>
To:        freebsd-arch@freebsd.org
Subject:   A General or Miscellaneous Binary Image Activator
Message-ID:  <71BF89C0-13F9-41CA-9F7E-A3FDE11C2346@FreeBSD.org>

next in thread | raw e-mail | index | archive | help
Hi All,

I have written a miscellaneous (or general) binary interpreter image =
activator to support cross building mips64 ports using user mode qemu.   =
The source code can be found at:

	http://people.freebsd.org/~sson/imgact_binmisc/imgact_binmisc.h
	http://people.freebsd.org/~sson/imgact_binmisc/imgact_binmisc.c

I just saw Nathan Whitehorn's posting 'LLVM Image Activator' on this =
same list and hope we are not duplicating work.  Like Nathan's this code =
invokes a user-level interpreter or emulator when it recognizes the =
magic bytes in a header of a binary.  Unlike Nathan's it is much more =
general purpose.   It does this by using a magic field that may be up to =
'IBE_MAGIC_MAX'  (or 256) bytes long , an offset value in the binary, =
and, optionally, a bit mask field the same size as the magic field that =
can mask out and ignore any of the bits in the magic. Therefore, it is =
very flexible in supporting binary file types which I needed to figure =
out the arch for ELF files.

Of course, image activators have been a source for security issues.  If =
this or something like this is include in the kernel then I would =
recommend it be optional.  It has proven to be very useful for creating =
a mixed arch cross build environment.  This allows running things like =
the cross compiler/toolchain and /bin/sh natively on the host system =
which significantly helps performance.  Using this, and the user mode =
qemu port I have been working on, I have successfully cross built well =
over 9000 mips64 packages from ports using an old amd64 athlon (FYI, see =
https://wiki.freebsd.org/QemuUserModeHowTo for more information about =
user mode qemu).

It is configured from user space using sysctl(3).  For example, the =
following is for adding an activator that runs mips64 executables on an =
amd64 host using "user mode" qemu:

#include <sys/imgact_binmisc.h>

#define MIPS64_ELF_MAGIC                			=
"\x7f\x45\x4c\x46\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\=
x00\x08"
#define MIPS64_ELF_MASK   =
"\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\=
xff\xff"

ximgact_binmisc_entry_t xbe;=20

xbe.xbe_version =3D IBE_VERSION;
xbe.xbe_command =3D IBC_ADD;
xbe.xbe_flags =3D IBF_ENABLED | IBF_USE_MASK;
strlcpy(xbe.xbe_name, "mips64elf", (IBE_NAME_MAX - 1));
strlcpy((xbe.xbe_interpreter, "/usr/local/bin/qemu-mips64", (MAXPATHLEN =
-1));
xbe.xbe_offset =3D 0;
xbe.xbe_size =3D sizeof(MIPS64_ELF_MAGIC) - 1;
memcpy(xbe.xbe_magic, MIPS64_ELF_MAGIC, xbe.xbe_size);
memcpy(xbe.xbe_mask, MIPS64_ELF_MASK, xbe.xbe_size);

 int ret =3D sysctlbyname("kern.binmisc", NULL, NULL, &xbe, =
sizeof(xbe));

To disable/enable/delete the above entry in the kernel:

xbe.xbe_version =3D IBE_VERSION;
xbe.xbe_command =3D IBC_DISABLE; // or IBC_ENABLE or IBC_DELETE
strlcpy(xbe.xbe_name, "mips64elf", (IBE_NAME_MAX - 1));

int ret =3D sysctlbyname("kern.binmisc", NULL, NULL, &xbe, sizeof(xbe));

To list all the interperter entries that are currently configured:

ximagact_binmisc_list_t xbl;
size_t xbe_size =3D sizeof(xbe);
size_t xbl_size =3D sizeof(xbl);

xbe.xbe_version =3D IBE_VERSION;
xbe.xbe_command =3D IBC_LIST;
sysctlbyname("kern.binmisc", &xbl, &xbl_size, &xbe, sizeof(xbe));

 for(int i =3D 0; i < xbl.xbl_count; i++) {
=09
	xbe.xbe_version =3D IBE_VERSION;
 	xbe.xbe_command =3D IBC_LOOKUP;
=09
	strlcpy(xbe.xbe_name, xbl.xbl_names[i], (IBE_NAME_MAX - 1));
=09
	ret =3D sysctlbyname("kern.binmisc", &xbe, &xbe_size, &xbe, =
sizeof(xbe));
=09
	if (!ret) {
		// 'xbe' contains an interperter entry from the kernel =
for=09
		// the given 'xbl.xbl_name[i]' name.
	}
 }

 The sysctlbyname() calls above may return the following errors in =
addition
 to the one from sysctl(3):

 [EINVAL]  Invalid argment in the input ximgact_binmisc_entry_t =
structure.
 [EEXIST]  Interpreter entry for given name already exist in kernel =
list.=20
 [ENOMEM]  Allocating memory in the kernel failed.
 [ENOENT]  Interpreter entry for given name is not found.
 [ENOSPC]  Attempted to exceed maximum number of entries =
(IBE_MAX_ENTRIES).

Of course, comments, questions, concerns, etc. are welcome.

Best Regards,

-stacey.
sson@FreeBSD.org=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?71BF89C0-13F9-41CA-9F7E-A3FDE11C2346>