Skip to content

Commit

Permalink
Merge branch '32-on-64'
Browse files Browse the repository at this point in the history
  • Loading branch information
nelhage committed May 13, 2011
2 parents 66888f4 + 8701cf6 commit e17b77a
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 98 deletions.
85 changes: 74 additions & 11 deletions arch/amd64.h
Expand Up @@ -19,16 +19,79 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define orig_ax orig_rax
#define reg_ax rax
#define reg_ip rip
#include "x86_common.h"

#define syscall_rv rax
#define syscall_arg0 rdi
#define syscall_arg1 rsi
#define syscall_arg2 rdx
#define syscall_arg3 r10
#define syscall_arg4 r8
#define syscall_arg5 r9
#define ARCH_HAVE_MULTIPLE_PERSONALITIES

#include "x86_common.h"
static struct ptrace_personality arch_personality[2] = {
{
offsetof(struct user, regs.rax),
offsetof(struct user, regs.rdi),
offsetof(struct user, regs.rsi),
offsetof(struct user, regs.rdx),
offsetof(struct user, regs.r10),
offsetof(struct user, regs.r8),
offsetof(struct user, regs.r9),
offsetof(struct user, regs.rip),
},
{
offsetof(struct user, regs.rax),
offsetof(struct user, regs.rbx),
offsetof(struct user, regs.rcx),
offsetof(struct user, regs.rdx),
offsetof(struct user, regs.rsi),
offsetof(struct user, regs.rdi),
offsetof(struct user, regs.rbp),
offsetof(struct user, regs.rip),
},
};

struct x86_personality x86_personality[2] = {
{
offsetof(struct user, regs.orig_rax),
offsetof(struct user, regs.rax),
},
{
offsetof(struct user, regs.orig_rax),
offsetof(struct user, regs.rax),
},
};

struct syscall_numbers arch_syscall_numbers[2] = {
#include "default-syscalls.h"
{
/*
* These don't seem to be available in any convenient header. We could
* include unistd_32.h, but those definitions would conflict with the
* standard ones. So, let's just hardcode the values for now. Probably
* we should generate this from unistd_32.h during the build process or
* soemthing.
*/
.nr_mmap = 90,
.nr_mmap2 = 192,
.nr_munmap = 91,
.nr_getsid = 147,
.nr_setsid = 66,
.nr_setpgid = 57,
.nr_fork = 2,
.nr_wait4 = 114,
.nr_signal = 48,
.nr_rt_sigaction = 173,
.nr_open = 5,
.nr_close = 6,
.nr_ioctl = 54,
.nr_dup2 = 63
}
};

int arch_get_personality(struct ptrace_child *child) {
unsigned long cs;

cs = ptrace_command(child, PTRACE_PEEKUSER,
offsetof(struct user, regs.cs));
if (child->error)
return -1;
if (cs == 0x23)
child->personality = 1;
return 0;
}
27 changes: 15 additions & 12 deletions arch/arm.h
Expand Up @@ -19,18 +19,21 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define reg_ip ARM_pc
static struct ptrace_personality arch_personality[1] = {
{
offsetof(struct user, regs.uregs[0]),
offsetof(struct user, regs.uregs[0]),
offsetof(struct user, regs.uregs[1]),
offsetof(struct user, regs.uregs[2]),
offsetof(struct user, regs.uregs[3]),
offsetof(struct user, regs.uregs[4]),
offsetof(struct user, regs.uregs[5]),
offsetof(struct user, regs.ARM_pc),
}
};

#define syscall_rv uregs[0]
#define syscall_arg0 uregs[0]
#define syscall_arg1 uregs[1]
#define syscall_arg2 uregs[2]
#define syscall_arg3 uregs[3]
#define syscall_arg4 uregs[4]
#define syscall_arg5 uregs[5]

static inline void arch_fixup_regs(struct user *user) {
user->regs.reg_ip -= 4;
static inline void arch_fixup_regs(struct ptrace_child *child) {
child->user.regs.ARM_pc -= 4;
}

static inline int arch_set_syscall(struct ptrace_child *child,
Expand All @@ -40,7 +43,7 @@ static inline int arch_set_syscall(struct ptrace_child *child,

static inline int arch_save_syscall(struct ptrace_child *child) {
unsigned long swi;
swi = ptrace_command(child, PTRACE_PEEKTEXT, child->user.regs.reg_ip);
swi = ptrace_command(child, PTRACE_PEEKTEXT, child->user.regs.ARM_pc);
if (child->error)
return -1;
if (swi == 0xef000000)
Expand Down
32 changes: 32 additions & 0 deletions arch/default-syscalls.h
@@ -0,0 +1,32 @@
#define SC(name) .nr_##name = __NR_##name

{
#ifdef __NR_mmap
SC(mmap),
#else
.nr_mmap = -1,
#endif
#ifdef __NR_mmap2
SC(mmap2),
#else
.nr_mmap2 = -1,
#endif
SC(munmap),
SC(getsid),
SC(setsid),
SC(setpgid),
SC(fork),
SC(wait4),
#ifdef __NR_signal
SC(signal),
#else
.nr_signal = -1,
#endif
SC(rt_sigaction),
SC(open),
SC(close),
SC(ioctl),
SC(dup2),
},

#undef SC
30 changes: 19 additions & 11 deletions arch/i386.h
Expand Up @@ -19,16 +19,24 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define orig_ax orig_eax
#define reg_ax eax
#define reg_ip eip
#include "x86_common.h"

#define syscall_rv eax
#define syscall_arg0 ebx
#define syscall_arg1 ecx
#define syscall_arg2 edx
#define syscall_arg3 esi
#define syscall_arg4 edi
#define syscall_arg5 ebp
static struct ptrace_personality arch_personality[1] = {
{
offsetof(struct user, regs.eax),
offsetof(struct user, regs.ebx),
offsetof(struct user, regs.ecx),
offsetof(struct user, regs.edx),
offsetof(struct user, regs.esi),
offsetof(struct user, regs.edi),
offsetof(struct user, regs.ebp),
offsetof(struct user, regs.eip),
}
};

#include "x86_common.h"
struct x86_personality x86_personality[1] = {
{
offsetof(struct user, regs.orig_eax),
offsetof(struct user, regs.eax),
}
};
28 changes: 23 additions & 5 deletions arch/x86_common.h
Expand Up @@ -19,23 +19,41 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
static inline void arch_fixup_regs(struct user *user) {
user->regs.reg_ip -= 2;
user->regs.reg_ax = user->regs.orig_ax;

struct x86_personality {
size_t orig_ax;
size_t ax;
};

struct x86_personality x86_personality[];

static inline struct x86_personality *x86_pers(struct ptrace_child *child) {
return &x86_personality[child->personality];
}

static inline void arch_fixup_regs(struct ptrace_child *child) {
struct x86_personality *x86pers = x86_pers(child);
struct ptrace_personality *pers = personality(child);
struct user *user = &child->user;
#define ptr(user, off) ((unsigned long*)((void*)(user)+(off)))
*ptr(user, pers->reg_ip) -= 2;
*ptr(user, x86pers->ax) = *ptr(user, x86pers->orig_ax);
}

static inline int arch_set_syscall(struct ptrace_child *child,
unsigned long sysno) {
return ptrace_command(child, PTRACE_POKEUSER,
offsetof(struct user, regs.orig_ax),
x86_pers(child)->orig_ax,
sysno);
}

static inline int arch_save_syscall(struct ptrace_child *child) {
child->saved_syscall = child->user.regs.orig_ax;
child->saved_syscall = *ptr(&child->user, x86_pers(child)->orig_ax);
return 0;
}

static inline int arch_restore_syscall(struct ptrace_child *child) {
return 0;
}

#undef ptr

0 comments on commit e17b77a

Please sign in to comment.