{"id":74,"date":"2020-12-30T18:28:41","date_gmt":"2020-12-30T17:28:41","guid":{"rendered":"https:\/\/threedots.ovh\/blog\/?p=74"},"modified":"2020-12-30T18:29:40","modified_gmt":"2020-12-30T17:29:40","slug":"houdini-run-arm-32-bit-and-64-bit-applications-on-an-x86_64-system","status":"publish","type":"post","link":"https:\/\/threedots.ovh\/blog\/2020\/12\/houdini-run-arm-32-bit-and-64-bit-applications-on-an-x86_64-system\/","title":{"rendered":"Houdini: run Arm 32-bit and 64-bit applications on an x86_64 system"},"content":{"rendered":"\n<p>Intel Houdini is a dynamic binary translation layer to run Arm applications on x86_64 systems. Its targeted platform is Android, but you can use it for _other_ platforms too. It&#8217;s much faster than Qemu at that task.<\/p>\n\n\n\n<p>Houdini 6 with AArch64 on x86_64 compatibility is available at&nbsp;<a href=\"http:\/\/dl.android-x86.org\/houdini\/6_z\/houdini.sfs\">http:\/\/dl.android-x86.org\/houdini\/6_z\/houdini.sfs<\/a>&nbsp;and for AArch32 on x86_64 at&nbsp;<a href=\"http:\/\/dl.android-x86.org\/houdini\/6_y\/houdini.sfs\">http:\/\/dl.android-x86.org\/houdini\/6_y\/houdini.sfs<\/a>.<\/p>\n\n\n\n<p>The patch function at <a href=\"https:\/\/everydaywithlinux.blogspot.com\/2012\/11\/patch-strings-in-binary-files-with-sed.html\">https:\/\/everydaywithlinux.blogspot.com\/2012\/11\/patch-strings-in-binary-files-with-sed.html<\/a>&nbsp;will be used here.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir arm64_x64\nmkdir armv7_x64\nunsquashfs houdini-6_z.sfs\ncp squashfs-root\/houdini64 arm64_x64\/\ncp squashfs-root\/cpuinfo arm64_x64\/\ncp squashfs-root\/linker64 arm64_x64\/\nrm -rf squashfs-root\n\nunsquashfs houdini-6_y.sfs\ncp squashfs-root\/houdini armv7_x64\/\ncp squashfs-root\/cpuinfo armv7_x64\/\ncp squashfs-root\/linker armv7_x64\/\nrm -rf squashfs-root<\/code><\/pre>\n\n\n\n<p>First, the SquashFS image that Houdini ships in is unpacked.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>patch_strings_in_file arm64_x64\/houdini64 \"\/system\/lib64\/arm64\/cpuinfo\" \"\/usr\/lib\/houdini\/cpu64\"\npatch_strings_in_file arm64_x64\/houdini64 \"\/system\/lib64\/arm64\/linker64\" \"\/lib\/ld-linux-aarch64.so.1\"\npatch_strings_in_file arm64_x64\/houdini64 \"\/system\/lib64\/arm64\/libaeabi_map.so\" \"\"\n\npatch_strings_in_file armv7_x64\/houdini \"\/system\/lib\/arm\/cpuinfo\" \"\/usr\/lib\/houdini\/cpu32\"\npatch_strings_in_file armv7_x64\/houdini \"\/system\/lib\/arm\/linker\" \"\/usr\/lib\/houdini\/ld.so\"\npatch_strings_in_file armv7_x64\/houdini \"\/system\/lib\/arm\/libaeabi_map.so\" \"\"<\/code><\/pre>\n\n\n\n<p>Then, patches are made, note here that we patched the library loader path to \/usr\/lib\/houdini\/ld.so for 32-bit Arm binaries, that&#8217;s because we don&#8217;t have enough bytes to put in the full path.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>:arm_exe:M::\\x7f\\x45\\x4c\\x46\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28::\/usr\/libexec\/houdini:POC\n:armv7_exe:M::\\x7f\\x45\\x4c\\x46\\x01\\x01\\x01\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28::\/usr\/libexec\/houdini:POC\n:arm64_exe:M::\\x7f\\x45\\x4c\\x46\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7::\/usr\/libexec\/houdini64:POC\n:arm64_exe_2:M::\\x7f\\x45\\x4c\\x46\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\xb7::\/usr\/libexec\/houdini64:POC\n:arm64_exe_3:M::\\x7f\\x45\\x4c\\x46\\x02\\x01\\x01\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7::\/usr\/libexec\/houdini64:POC<\/code><\/pre>\n\n\n\n<p>That&#8217;s the content of the houdini.conf file that&#8217;ll be used by binfmt_misc to redirect the attempts to run Arm applications to Houdini.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/usr\/libexec\ninstall -m 755 arm64_x64\/houdini64 $DESTDIR\/usr\/libexec\/houdini64\ninstall -m 755 armv7_x64\/houdini $DESTDIR\/usr\/libexec\/houdini\n\nmkdir -p \/usr\/lib\/houdini\ninstall -m 644 arm64_x64\/cpuinfo $DESTDIR\/usr\/lib\/houdini\/cpu64\ninstall -m 644 armv7_x64\/cpuinfo $DESTDIR\/usr\/lib\/houdini\/cpu32\nln -s \/lib\/ld-linux-armhf.so.3 $DESTDIR\/usr\/lib\/houdini\/ld.so\n\nmkdir -p \/etc\/binfmt.d\ninstall -m 644 houdini.conf $DESTDIR\/etc\/binfmt.d\/houdini.conf\n\nsystemctl restart systemd-binfmt.service<\/code><\/pre>\n\n\n\n<p>You can then install to your system this way, or by making a proper package. (to run as root)<\/p>\n\n\n\n<p>You&#8217;ll then have to copy over those files to the Arm chroot that your distribution will run in too. For 32-bit Arm, it&#8217;s also needed to link \/usr\/lib\/houdini\/ld.so to your library loader.<\/p>\n\n\n\n<p>You can then set the bind mounts to \/sys, \/dev, \/dev\/pts and \/proc. Afterwards, you can chroot and use the Arm environment.<\/p>\n\n\n\n<p>In case of Linux distributions using the musl C library, you&#8217;ll have to link \/lib\/ld-linux-armhf.so.3 and \/lib\/ld-linux-aarch64.so.1 to your libc path for the architecture. (on musl, the C library and the library loader are the same executable)<\/p>\n\n\n\n<p><em>Note: If you try to access to the TPIDRURW MSR when using Houdini running a 32-bit Arm application, you&#8217;ll get a crash. This MSR is only used in practice when using Wine to run a 32-bit Arm Windows app.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intel Houdini is a dynamic binary translation layer to run Arm applications on x86_64 systems. Its targeted platform is Android, but you can use it for _other_ platforms too. It&#8217;s much faster than Qemu at that task. Houdini 6 with AArch64 on x86_64 compatibility is available at&nbsp;http:\/\/dl.android-x86.org\/houdini\/6_z\/houdini.sfs&nbsp;and for AArch32 on x86_64 at&nbsp;http:\/\/dl.android-x86.org\/houdini\/6_y\/houdini.sfs. The patch function&hellip;&nbsp;<a href=\"https:\/\/threedots.ovh\/blog\/2020\/12\/houdini-run-arm-32-bit-and-64-bit-applications-on-an-x86_64-system\/\" rel=\"bookmark\">Read More &raquo;<span class=\"screen-reader-text\">Houdini: run Arm 32-bit and 64-bit applications on an x86_64 system<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[4],"tags":[],"class_list":["post-74","post","type-post","status-publish","format-standard","hentry","category-arm"],"_links":{"self":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":3,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"predecessor-version":[{"id":77,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions\/77"}],"wp:attachment":[{"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/threedots.ovh\/blog\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}