Something went wrong. Try again.
Cider Isn't Darwin Emulation, Really
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118/*This file is part of Darling.
Copyright (C) 2012-2013 Lubos Dolezel
Darling is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.
You should have received a copy of the GNU General Public Licensealong with Darling. If not, see <http://www.gnu.org/licenses/>.*/
#include "UndefinedFunction.h"#include <unistd.h>#include <sys/mman.h>#include <stdexcept>#include <dlfcn.h>
UndefMgr::UndefMgr(int entries): m_nNext(0){ int ps = getpagesize(); void* mem; int bytes = entries * sizeof(UndefinedFunction); bytes = (bytes + ps - 1) / ps * ps; mem = ::mmap(0, bytes, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); if (mem == MAP_FAILED) throw std::runtime_error("Failed to map pages for UndefMgr"); m_pMem = static_cast<UndefinedFunction*>(mem); m_nMax = bytes / sizeof(UndefinedFunction); m_nBytes = bytes;}
UndefMgr::~UndefMgr(){ ::munmap(m_pMem, m_nBytes);}
void* UndefMgr::generateNew(const char* name){ if (m_nNext >= m_nMax) throw std::runtime_error("UndefMgr buffer full"); m_pMem[m_nNext].init(name); return &m_pMem[m_nNext++];}
void UndefinedFunction::init(const char* name){#if defined(__x86_64__) _asm1[0] = 0x48; _asm1[1] = 0xbf; _asm2[0] = 0x48; _asm2[1] = 0xbe; _asm3[0] = 0x48; _asm3[1] = 0xba; _asm4[0] = 0x48; _asm4[1] = 0xb9; _asm5[0] = 0x48; _asm5[1] = 0x31; _asm5[2] = 0xc0; _asm5[3] = 0xff; _asm5[4] = 0xd1; _asm5[5] = 0x48; _asm5[6] = 0x31; _asm5[7] = 0xc0; _asm5[8] = 0xc3;#elif defined(__i386__) _asm1[0] = 0xb8; _asm2[0] = 0x50; _asm2[1] = 0xb8; _asm3[0] = 0x50; _asm3[1] = 0xb8; _asm4[0] = 0x50; _asm4[1] = 0xb8; _asm5[0] = 0xff; _asm5[1] = 0xd0; _asm5[2] = 0x83; _asm5[3] = 0xc4; _asm5[4] = 0x0c; _asm5[5] = 0x31; _asm5[6] = 0xc0; _asm5[7] = 0xc3;#else# error Unsupported platform!#endif
pStderr = stderr; pErrMsg = "Undefined function called: %s\n"; pFuncName = name; pFprintf = dlsym(RTLD_DEFAULT, "fprintf");}
#ifdef TESTint main(){ UndefMgr* mgr = new UndefMgr; int (*func)() = (int(*)()) mgr->generateNew("TestFunction"); int (*func2)() = (int(*)()) mgr->generateNew("TestFunction2"); func(); func2(); delete mgr; return 0;}#endif