/* This file is part of Darling. Copyright (C) 2012-2013 Lubos Dolezel Darling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Darling is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Darling. If not, see . */ #include "binfmt_misc.h" #include #include #include #include static void checkRoot() { if (getuid()) throw std::runtime_error("You must be root for this operation"); } void Darling::binfmtRegister(const char* loader) { checkRoot(); std::ofstream reg("/proc/sys/fs/binfmt_misc/register"); if (!reg.is_open()) throw std::runtime_error("Cannot register the binfmt_misc handler, is binfmt_misc kernel support loaded and mounted?"); #if defined(__x86_64__) || defined(__powerpc64__) reg << ":Mach-O 64bit:M::\\xcf\\xfa\\xed\\xfe::" << loader << ":\n"; #elif defined(__i386__) || defined(__powerpc__) || defined(__arm__) reg << ":Mach-O 32bit:M::\\xce\\xfa\\xed\\xfe::" << loader << ":\n"; #else # error Unuspported platform #endif reg.close(); // In multilib environments, register FAT Mach-O files with dyld64 only #if !defined(MULTILIB) reg.open("/proc/sys/fs/binfmt_misc/register"); reg << ":Mach-O Universal:M::\\xca\\xfe\\xba\\xbe::" << loader << ":\n"; reg.close(); #elif defined(__x86_64__) || defined(__powerpc64__) { std::string universalLoader = loader; universalLoader.resize(universalLoader.size() - 2); reg.open("/proc/sys/fs/binfmt_misc/register"); reg << ":Mach-O Universal:M::\\xca\\xfe\\xba\\xbe::" << universalLoader.c_str() << ":\n"; reg.close(); } #endif } static void deregister(const char* fmt) { std::ofstream dereg(std::string("/proc/sys/fs/binfmt_misc/") + fmt); if (dereg.is_open()) dereg << "-1\n"; } void Darling::binfmtDeregister() { checkRoot(); deregister("Mach-O Universal"); if (sizeof(void*) == 8) deregister("Mach-O 64bit"); else deregister("Mach-O 32bit"); }