/*
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 "UndefinedFunction.h"
#include
#include
#include
#include
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(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 TEST
int main()
{
UndefMgr* mgr = new UndefMgr;
int (*func)() = (int(*)()) mgr->generateNew("TestFunction");
int (*func2)() = (int(*)()) mgr->generateNew("TestFunction2");
func();
func2();
delete mgr;
return 0;
}
#endif