Merge branch 'master' of github.com:reswitched/Mephisto

This commit is contained in:
misson20000 2018-01-15 22:48:48 -08:00
commit 4c6d02c21e
6 changed files with 71 additions and 9 deletions

26
Dockerfile Normal file
View file

@ -0,0 +1,26 @@
FROM ubuntu:17.10
RUN apt update; apt install -y wget; \
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -;\
echo 'deb http://apt.llvm.org/xenial/ llvm-toolchain-artful-5.0 main' >> /etc/apt/sources.list ; apt update;\
apt install -y clang-5.0 lldb-5.0 lld-5.0 libc++-dev git cmake python-pip liblz4-dev; apt clean all
ADD . /nonexistent/Mephisto
RUN chown nobody:nogroup /nonexistent -R
USER nobody
RUN cd /nonexistent; git clone --depth 1 https://github.com/reswitched/unicorn.git;\
cd unicorn;\
UNICORN_ARCHS="aarch64" ./make.sh;\
PREFIX=/nonexistent/usr ./make.sh install
RUN cd /nonexistent/Mephisto;\
pip install -r requirements.txt;\
EXTRA_CC_FLAGS="-I ../usr/include" EXTRA_LD_FLAGS="-L ../usr/lib" make
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/nonexistent/usr/lib
EXPOSE 24689
ENTRYPOINT ["/nonexistent/Mephisto/ctu"]
CMD ["${*}"]

View file

@ -385,10 +385,14 @@ void GdbStub::sendSignal(uint32_t signal) {
intToGdbHex(sp, reg(31));
intToGdbHex(pc, reg(32));
auto curthread = ctu->tm.current();
string buffer = stringFromFormat("T%02x%02x:%.16s;%02x:%.16s;", latestSignal, 32, pc, 31, sp);
auto curthread = ctu->tm.current();
if(curthread == nullptr)
curthread = ctu->tm.last();
if (curthread != nullptr)
buffer += stringFromFormat("thread:%x;", curthread->id);
LOG_DEBUG(GdbStub, "Response: %s", buffer.c_str());
sendReply(buffer.c_str());
}

View file

@ -68,3 +68,29 @@ Alternatively, you can pass a single NSO file on the command line:
```
See help for other info, e.g. enabling GDB support.
### Run through Docker
First build the docker image, this may take some time
```bash
docker build -t reswitched/mephisto .
```
To run Mephisto it needs access to your NSO/NRO files, make sure to bind mount the location into the container.
__Example:__
```bash
docker run -ti --rm -p 24689:24689 -v $HOME:$HOME -u $UID reswitched/mephisto --load-nro $HOME/Coding/libtransistor/build/test/test_helloworld.nro
```
You can also create a bash alias.
```
alias ctu='docker run -ti --rm -p 24689:24689 -v $HOME:$HOME -u $UID reswitched/mephisto'
```
Now you can simply run `ctu` with your desired arguments.
__Example:__
```bash
ctu --load-nro $HOME/Coding/libtransistor/build/test/test_helloworld.nro
```

13
Svc.cpp
View file

@ -94,7 +94,7 @@ Svc::Svc(Ctu *_ctu) : ctu(_ctu) {
registerSvc_ret_X0( 0x19, CancelSynchronization, (ghandle) IX0);
registerSvc_ret_X0( 0x1A, LockMutex, (ghandle) IX0, IX1, (ghandle) IX2);
registerSvc( 0x1B, UnlockMutex, IX0);
registerSvc( 0x1C, WaitProcessWideKeyAtomic, IX0, IX1, (ghandle) IX2, IX3);
registerSvc_ret_X0( 0x1C, WaitProcessWideKeyAtomic, IX0, IX1, (ghandle) IX2, IX3);
registerSvc_ret_X0( 0x1D, SignalProcessWideKey, IX0, IX1);
registerSvc_ret_X0( 0x1E, GetSystemTick);
registerSvc_ret_X0_X1( 0x1F, ConnectToPort, IX1);
@ -222,7 +222,9 @@ guint Svc::SleepThread(guint ns) {
auto thread = ctu->tm.current();
// Yield, at least.
thread->suspend([=] {
thread->resume([=] {});
thread->resume([=] {
thread->regs.X0 = 0;
});
});
return 0;
}
@ -391,7 +393,7 @@ shared_ptr<Semaphore> Svc::ensureSemaphore(gptr semaAddr) {
return semaphores[semaAddr];
}
void Svc::WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle threadHandle, guint timeout) {
guint Svc::WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle threadHandle, guint timeout) {
LOG_DEBUG(Svc[0x1C], "WaitProcessWideKeyAtomic 0x" LONGFMT " 0x" LONGFMT " 0x%x 0x" LONGFMT, mutexAddr, semaAddr, threadHandle, timeout);
auto mutex = ensureMutex(mutexAddr);
@ -401,7 +403,7 @@ void Svc::WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle thread
if(semaphore->value() > 0) {
semaphore->decrement();
return;
return 0;
}
auto thread = ctu->getHandle<Thread>(threadHandle);
@ -409,13 +411,14 @@ void Svc::WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle thread
semaphore->wait([=] {
semaphore->decrement();
thread->resume([=] {
LockMutex(0, mutexAddr, threadHandle);
thread->regs.X0 = LockMutex(0, mutexAddr, threadHandle);
});
return 1;
});
});
mutex->guestRelease();
return 0;
}
guint Svc::SignalProcessWideKey(gptr semaAddr, guint target) {

2
Svc.h
View file

@ -47,7 +47,7 @@ private:
guint CancelSynchronization(ghandle handle); // 0x19
guint LockMutex(ghandle curthread, gptr mutexAddr, ghandle reqthread); // 0x1A
void UnlockMutex(gptr mutexAddr); // 0x1B
void WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle threadHandle, guint timeout); // 0x1C
guint WaitProcessWideKeyAtomic(gptr mutexAddr, gptr semaAddr, ghandle threadHandle, guint timeout); // 0x1C
guint SignalProcessWideKey(gptr semaAddr, guint target); // 0x1D
guint GetSystemTick(); // 0x1E
tuple<guint, ghandle> ConnectToPort(guint name); // 0x1F

View file

@ -6,7 +6,7 @@ Thread::Thread(Ctu *_ctu, int _id) : ctu(_ctu), id(_id), started(false) {
active = false;
memset(&regs, 0, sizeof(ThreadRegisters));
auto tlsSize = 1024 * 1024;
auto tlsSize = 0x1000;
tlsBase = (1 << 24) + tlsSize * _id;
ctu->cpu.map(tlsBase, tlsSize);
}
@ -19,6 +19,8 @@ void Thread::assignHandle(uint32_t _handle) {
void Thread::terminate() {
signal();
ctu->tm.terminate(id);
auto tlsSize = 0x1000;
ctu->cpu.unmap(tlsBase, tlsSize);
}
void Thread::suspend(function<void()> cb) {
@ -121,7 +123,8 @@ void ThreadManager::start() {
ctu->cpu.exec(wasStep ? 1 : INSN_PER_SLICE);
if(wasStep) {
ctu->gdbStub.haltLoop = ctu->gdbStub.stepLoop = false;
_current->freeze();
if (_current != nullptr)
_current->freeze();
ctu->gdbStub._break();
}
} else {