ARM: Implement TLS. This is not tested.
This commit is contained in:
parent
5daeefc505
commit
37ac2871d5
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include "sim/process.hh"
|
||||
#include "sim/syscall_emul.hh"
|
||||
#include "sim/system.hh"
|
||||
|
||||
using namespace std;
|
||||
using namespace ArmISA;
|
||||
|
@ -411,12 +412,25 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = {
|
|||
/* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc),
|
||||
};
|
||||
|
||||
/// Target set_tls() handler.
|
||||
static SyscallReturn
|
||||
setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
uint32_t tlsPtr = process->getSyscallArg(tc, 0);
|
||||
TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0));
|
||||
|
||||
tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0,
|
||||
(uint8_t *)&tlsPtr, sizeof(tlsPtr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
SyscallDesc ArmLinuxProcess::privSyscallDescs[] = {
|
||||
/* 1 */ SyscallDesc("breakpoint", unimplementedFunc),
|
||||
/* 2 */ SyscallDesc("cacheflush", unimplementedFunc),
|
||||
/* 3 */ SyscallDesc("usr26", unimplementedFunc),
|
||||
/* 4 */ SyscallDesc("usr32", unimplementedFunc),
|
||||
/* 5 */ SyscallDesc("set_tls", unimplementedFunc)
|
||||
/* 5 */ SyscallDesc("set_tls", setTLSFunc)
|
||||
};
|
||||
|
||||
ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params,
|
||||
|
@ -426,6 +440,8 @@ ArmLinuxProcess::ArmLinuxProcess(LiveProcessParams * params,
|
|||
Num_Priv_Syscall_Descs(sizeof(privSyscallDescs) / sizeof(SyscallDesc))
|
||||
{ }
|
||||
|
||||
const Addr ArmLinuxProcess::commPage = 0xffff0000;
|
||||
|
||||
SyscallDesc*
|
||||
ArmLinuxProcess::getDesc(int callnum)
|
||||
{
|
||||
|
@ -448,3 +464,28 @@ ArmLinuxProcess::getDesc(int callnum)
|
|||
|
||||
return &syscallDescs[callnum];
|
||||
}
|
||||
|
||||
void
|
||||
ArmLinuxProcess::startup()
|
||||
{
|
||||
ArmLiveProcess::startup();
|
||||
pTable->allocate(commPage, PageBytes);
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
|
||||
uint8_t swiNeg1[] = {
|
||||
0xff, 0xff, 0xff, 0xef //swi -1
|
||||
};
|
||||
|
||||
// Fill this page with swi -1 so we'll no if we land in it somewhere.
|
||||
for (Addr addr = 0; addr < PageBytes; addr += sizeof(swiNeg1)) {
|
||||
tc->getMemPort()->writeBlob(commPage + addr,
|
||||
swiNeg1, sizeof(swiNeg1));
|
||||
}
|
||||
|
||||
uint8_t get_tls[] =
|
||||
{
|
||||
0x08, 0x00, 0x9f, 0xe5, //ldr r0, [pc, #(16 - 8)]
|
||||
0x0e, 0xf0, 0xa0, 0xe1 //usr_ret lr
|
||||
};
|
||||
tc->getMemPort()->writeBlob(commPage + 0x0fe0, get_tls, sizeof(get_tls));
|
||||
}
|
||||
|
|
|
@ -42,9 +42,14 @@ class ArmLinuxProcess : public ArmLiveProcess
|
|||
|
||||
virtual SyscallDesc* getDesc(int callnum);
|
||||
|
||||
void startup();
|
||||
|
||||
/// The target system's hostname.
|
||||
static const char *hostname;
|
||||
|
||||
/// A page to hold "kernel" provided functions. The name might be wrong.
|
||||
static const Addr commPage;
|
||||
|
||||
/// Array of syscall descriptors, indexed by call number.
|
||||
static SyscallDesc syscallDescs[];
|
||||
|
||||
|
|
Loading…
Reference in a new issue