suppressed tgetx and tputx (initial patch by Thayne Harbaugh)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3653 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
67276f53dc
commit
2f6196984b
16
arm-semi.c
16
arm-semi.c
@ -165,8 +165,14 @@ static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ARG(n) tget32(args + (n) * 4)
|
||||
#define SET_ARG(n, val) tput32(args + (n) * 4,val)
|
||||
#define ARG(n) \
|
||||
({ \
|
||||
target_ulong __arg; \
|
||||
/* FIXME - handle get_user() failure */ \
|
||||
get_user_ual(__arg, args + (n) * 4); \
|
||||
__arg; \
|
||||
})
|
||||
#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
|
||||
uint32_t do_arm_semihosting(CPUState *env)
|
||||
{
|
||||
target_ulong args;
|
||||
@ -213,7 +219,11 @@ uint32_t do_arm_semihosting(CPUState *env)
|
||||
}
|
||||
case SYS_WRITEC:
|
||||
{
|
||||
char c = tget8(args);
|
||||
char c;
|
||||
|
||||
if (get_user_u8(c, args))
|
||||
/* FIXME - should this error code be -TARGET_EFAULT ? */
|
||||
return (uint32_t)-1;
|
||||
/* Write to debug console. stderr is near enough. */
|
||||
if (use_gdb_syscalls()) {
|
||||
gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args);
|
||||
|
@ -179,8 +179,9 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
||||
regs->ARM_cpsr |= CPSR_T;
|
||||
regs->ARM_pc = infop->entry & 0xfffffffe;
|
||||
regs->ARM_sp = infop->start_stack;
|
||||
regs->ARM_r2 = tgetl(stack + 8); /* envp */
|
||||
regs->ARM_r1 = tgetl(stack + 4); /* envp */
|
||||
/* FIXME - what to for failure of get_user()? */
|
||||
get_user_ual(regs->ARM_r2, stack + 8); /* envp */
|
||||
get_user_ual(regs->ARM_r1, stack + 4); /* envp */
|
||||
/* XXX: it seems that r0 is zeroed after ! */
|
||||
regs->ARM_r0 = 0;
|
||||
/* For uClinux PIC binaries. */
|
||||
@ -341,7 +342,8 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info *
|
||||
* but this is what the ABI wants and is needed to allow
|
||||
* execution of PPC BSD programs.
|
||||
*/
|
||||
_regs->gpr[3] = tgetl(pos);
|
||||
/* FIXME - what to for failure of get_user()? */
|
||||
get_user_ual(_regs->gpr[3], pos);
|
||||
pos += sizeof(abi_ulong);
|
||||
_regs->gpr[4] = pos;
|
||||
for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong))
|
||||
@ -733,7 +735,8 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss)
|
||||
if (nbyte) {
|
||||
nbyte = qemu_host_page_size - nbyte;
|
||||
do {
|
||||
tput8(elf_bss, 0);
|
||||
/* FIXME - what to do if put_user() fails? */
|
||||
put_user_u8(0, elf_bss);
|
||||
elf_bss++;
|
||||
} while (--nbyte);
|
||||
}
|
||||
@ -782,17 +785,11 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
/* This is correct because Linux defines
|
||||
* elf_addr_t as Elf32_Off / Elf64_Off
|
||||
*/
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
#define NEW_AUX_ENT(id, val) do { \
|
||||
sp -= n; tput32(sp, val); \
|
||||
sp -= n; tput32(sp, id); \
|
||||
#define NEW_AUX_ENT(id, val) do { \
|
||||
sp -= n; put_user_ual(val, sp); \
|
||||
sp -= n; put_user_ual(id, sp); \
|
||||
} while(0)
|
||||
#else
|
||||
#define NEW_AUX_ENT(id, val) do { \
|
||||
sp -= n; tput64(sp, val); \
|
||||
sp -= n; tput64(sp, id); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
NEW_AUX_ENT (AT_NULL, 0);
|
||||
|
||||
/* There must be exactly DLINFO_ITEMS entries here. */
|
||||
|
@ -598,14 +598,16 @@ static int load_flat_file(struct linux_binprm * bprm,
|
||||
rp = datapos;
|
||||
while (1) {
|
||||
abi_ulong addr;
|
||||
addr = tgetl(rp);
|
||||
if (get_user_ual(addr, rp))
|
||||
return -EFAULT;
|
||||
if (addr == -1)
|
||||
break;
|
||||
if (addr) {
|
||||
addr = calc_reloc(addr, libinfo, id, 0);
|
||||
if (addr == RELOC_FAILED)
|
||||
return -ENOEXEC;
|
||||
tputl(rp, addr);
|
||||
if (put_user_ual(addr, rp))
|
||||
return -EFAULT;
|
||||
}
|
||||
rp += sizeof(abi_ulong);
|
||||
}
|
||||
@ -629,14 +631,16 @@ static int load_flat_file(struct linux_binprm * bprm,
|
||||
/* Get the address of the pointer to be
|
||||
relocated (of course, the address has to be
|
||||
relocated first). */
|
||||
relval = tgetl(reloc + i * sizeof (abi_ulong));
|
||||
if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))
|
||||
return -EFAULT;
|
||||
addr = flat_get_relocate_addr(relval);
|
||||
rp = calc_reloc(addr, libinfo, id, 1);
|
||||
if (rp == RELOC_FAILED)
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Get the pointer's value. */
|
||||
addr = tgetl(rp);
|
||||
if (get_user_ual(addr, rp))
|
||||
return -EFAULT;
|
||||
if (addr != 0) {
|
||||
/*
|
||||
* Do the relocation. PIC relocs in the data section are
|
||||
@ -652,13 +656,15 @@ static int load_flat_file(struct linux_binprm * bprm,
|
||||
return -ENOEXEC;
|
||||
|
||||
/* Write back the relocated pointer. */
|
||||
tputl(rp, addr);
|
||||
if (put_user_ual(addr, rp))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < relocs; i++) {
|
||||
abi_ulong relval;
|
||||
relval = tgetl(reloc + i * sizeof (abi_ulong));
|
||||
if (get_user_ual(relval, reloc + i * sizeof(abi_ulong)))
|
||||
return -EFAULT;
|
||||
old_reloc(&libinfo[0], relval);
|
||||
}
|
||||
}
|
||||
@ -744,9 +750,12 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
|
||||
p = libinfo[i].start_data;
|
||||
for (j=0; j<MAX_SHARED_LIBS; j++) {
|
||||
p -= 4;
|
||||
tput32(p, libinfo[j].loaded
|
||||
? libinfo[j].start_data
|
||||
: UNLOADED_LIB);
|
||||
/* FIXME - handle put_user() failures */
|
||||
if (put_user_ual(libinfo[j].loaded
|
||||
? libinfo[j].start_data
|
||||
: UNLOADED_LIB,
|
||||
p))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -779,7 +788,9 @@ int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
|
||||
for (i = MAX_SHARED_LIBS-1; i>0; i--) {
|
||||
if (libinfo[i].loaded) {
|
||||
/* Push previos first to call address */
|
||||
--sp; put_user(start_addr, sp);
|
||||
--sp;
|
||||
if (put_user_ual(start_addr, sp))
|
||||
return -EFAULT;
|
||||
start_addr = libinfo[i].entry;
|
||||
}
|
||||
}
|
||||
|
@ -124,21 +124,32 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
|
||||
sp -= (argc + 1) * n;
|
||||
argv = sp;
|
||||
if (push_ptr) {
|
||||
sp -= n; tputl(sp, envp);
|
||||
sp -= n; tputl(sp, argv);
|
||||
/* FIXME - handle put_user() failures */
|
||||
sp -= n;
|
||||
put_user_ual(envp, sp);
|
||||
sp -= n;
|
||||
put_user_ual(argv, sp);
|
||||
}
|
||||
sp -= n; tputl(sp, argc);
|
||||
sp -= n;
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_ual(argc, sp);
|
||||
|
||||
while (argc-- > 0) {
|
||||
tputl(argv, stringp); argv += n;
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_ual(stringp, argv);
|
||||
argv += n;
|
||||
stringp += target_strlen(stringp) + 1;
|
||||
}
|
||||
tputl(argv, 0);
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_ual(0, argv);
|
||||
while (envc-- > 0) {
|
||||
tputl(envp, stringp); envp += n;
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_ual(stringp, envp);
|
||||
envp += n;
|
||||
stringp += target_strlen(stringp) + 1;
|
||||
}
|
||||
tputl(envp, 0);
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_ual(0, envp);
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
@ -380,7 +380,8 @@ void cpu_loop(CPUARMState *env)
|
||||
|
||||
/* we handle the FPU emulation here, as Linux */
|
||||
/* we get the opcode */
|
||||
opcode = tget32(env->regs[15]);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_u32(opcode, env->regs[15]);
|
||||
|
||||
if (EmulateAll(opcode, &ts->fpa, env) == 0) {
|
||||
info.si_signo = SIGILL;
|
||||
@ -401,20 +402,24 @@ void cpu_loop(CPUARMState *env)
|
||||
/* system call */
|
||||
if (trapnr == EXCP_BKPT) {
|
||||
if (env->thumb) {
|
||||
insn = tget16(env->regs[15]);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_u16(insn, env->regs[15]);
|
||||
n = insn & 0xff;
|
||||
env->regs[15] += 2;
|
||||
} else {
|
||||
insn = tget32(env->regs[15]);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_u32(insn, env->regs[15]);
|
||||
n = (insn & 0xf) | ((insn >> 4) & 0xff0);
|
||||
env->regs[15] += 4;
|
||||
}
|
||||
} else {
|
||||
if (env->thumb) {
|
||||
insn = tget16(env->regs[15] - 2);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_u16(insn, env->regs[15] - 2);
|
||||
n = insn & 0xff;
|
||||
} else {
|
||||
insn = tget32(env->regs[15] - 4);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_u32(insn, env->regs[15] - 4);
|
||||
n = insn & 0xffffff;
|
||||
}
|
||||
}
|
||||
@ -520,7 +525,8 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1)
|
||||
(int)sp_ptr, cwp1);
|
||||
#endif
|
||||
for(i = 0; i < 16; i++) {
|
||||
tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]);
|
||||
/* FIXME - what to do if put_user() fails? */
|
||||
put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
|
||||
sp_ptr += sizeof(abi_ulong);
|
||||
}
|
||||
}
|
||||
@ -556,7 +562,8 @@ static void restore_window(CPUSPARCState *env)
|
||||
(int)sp_ptr, cwp1);
|
||||
#endif
|
||||
for(i = 0; i < 16; i++) {
|
||||
env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
|
||||
sp_ptr += sizeof(abi_ulong);
|
||||
}
|
||||
env->wim = new_wim;
|
||||
@ -1533,10 +1540,11 @@ void cpu_loop(CPUMIPSState *env)
|
||||
sp_reg = env->gpr[29][env->current_tc];
|
||||
switch (nb_args) {
|
||||
/* these arguments are taken from the stack */
|
||||
case 8: arg8 = tgetl(sp_reg + 28);
|
||||
case 7: arg7 = tgetl(sp_reg + 24);
|
||||
case 6: arg6 = tgetl(sp_reg + 20);
|
||||
case 5: arg5 = tgetl(sp_reg + 16);
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
case 8: get_user_ual(arg8, sp_reg + 28);
|
||||
case 7: get_user_ual(arg7, sp_reg + 24);
|
||||
case 6: get_user_ual(arg6, sp_reg + 20);
|
||||
case 5: get_user_ual(arg5, sp_reg + 16);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
int size = sizeof(*hptr);\
|
||||
switch(size) {\
|
||||
case 1:\
|
||||
*(uint8_t *)(hptr) = (typeof(*hptr))(x);\
|
||||
*(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
|
||||
break;\
|
||||
case 2:\
|
||||
*(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
|
||||
@ -260,6 +260,8 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
|
||||
break;\
|
||||
default:\
|
||||
/* avoid warning */\
|
||||
x = 0;\
|
||||
abort();\
|
||||
}\
|
||||
0;\
|
||||
@ -291,11 +293,36 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||
if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
|
||||
__ret = __get_user((x), __hptr); \
|
||||
unlock_user(__hptr, __gaddr, 0); \
|
||||
} else \
|
||||
} else { \
|
||||
/* avoid warning */ \
|
||||
(x) = 0; \
|
||||
__ret = -TARGET_EFAULT; \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
|
||||
#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
|
||||
#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
|
||||
#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
|
||||
#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
|
||||
#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
|
||||
#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
|
||||
#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
|
||||
#define put_user_u8(x, gaddr) put_user((x), (gaddr), uint8_t)
|
||||
#define put_user_s8(x, gaddr) put_user((x), (gaddr), int8_t)
|
||||
|
||||
#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
|
||||
#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
|
||||
#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
|
||||
#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
|
||||
#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
|
||||
#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
|
||||
#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
|
||||
#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
|
||||
#define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
|
||||
#define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
|
||||
|
||||
/* copy_from_user() and copy_to_user() are usually used to copy data
|
||||
* buffers between the target and host. These internally perform
|
||||
* locking/unlocking of the memory.
|
||||
@ -368,20 +395,4 @@ static inline void *lock_user_string(abi_ulong guest_addr)
|
||||
#define unlock_user_struct(host_ptr, guest_addr, copy) \
|
||||
unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
|
||||
|
||||
#define tget8(addr) ldub(addr)
|
||||
#define tput8(addr, val) stb(addr, val)
|
||||
#define tget16(addr) lduw(addr)
|
||||
#define tput16(addr, val) stw(addr, val)
|
||||
#define tget32(addr) ldl(addr)
|
||||
#define tput32(addr, val) stl(addr, val)
|
||||
#define tget64(addr) ldq(addr)
|
||||
#define tput64(addr, val) stq(addr, val)
|
||||
#if TARGET_ABI_BITS == 64
|
||||
#define tgetl(addr) ldq(addr)
|
||||
#define tputl(addr, val) stq(addr, val)
|
||||
#else
|
||||
#define tgetl(addr) ldl(addr)
|
||||
#define tputl(addr, val) stl(addr, val)
|
||||
#endif
|
||||
|
||||
#endif /* QEMU_H */
|
||||
|
@ -783,7 +783,7 @@ static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh,
|
||||
|
||||
/* do_setsockopt() Must return target values and target errnos. */
|
||||
static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||
abi_ulong optval, socklen_t optlen)
|
||||
abi_ulong optval_addr, socklen_t optlen)
|
||||
{
|
||||
abi_long ret;
|
||||
int val;
|
||||
@ -794,7 +794,8 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||
if (optlen < sizeof(uint32_t))
|
||||
return -TARGET_EINVAL;
|
||||
|
||||
val = tget32(optval);
|
||||
if (get_user_u32(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
|
||||
break;
|
||||
case SOL_IP:
|
||||
@ -816,9 +817,11 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||
case IP_MULTICAST_LOOP:
|
||||
val = 0;
|
||||
if (optlen >= sizeof(uint32_t)) {
|
||||
val = tget32(optval);
|
||||
if (get_user_u32(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
} else if (optlen >= 1) {
|
||||
val = tget8(optval);
|
||||
if (get_user_u8(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
|
||||
break;
|
||||
@ -890,9 +893,10 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||
goto unimplemented;
|
||||
}
|
||||
if (optlen < sizeof(uint32_t))
|
||||
return -TARGET_EINVAL;
|
||||
return -TARGET_EINVAL;
|
||||
|
||||
val = tget32(optval);
|
||||
if (get_user_u32(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
|
||||
break;
|
||||
default:
|
||||
@ -905,7 +909,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
||||
|
||||
/* do_getsockopt() Must return target values and target errnos. */
|
||||
static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
abi_ulong optval, abi_ulong optlen)
|
||||
abi_ulong optval_addr, abi_ulong optlen)
|
||||
{
|
||||
abi_long ret;
|
||||
int len, lv, val;
|
||||
@ -928,7 +932,8 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
case SOL_TCP:
|
||||
/* TCP options all take an 'int' value. */
|
||||
int_case:
|
||||
len = tget32(optlen);
|
||||
if (get_user_u32(len, optlen))
|
||||
return -TARGET_EFAULT;
|
||||
if (len < 0)
|
||||
return -TARGET_EINVAL;
|
||||
lv = sizeof(int);
|
||||
@ -938,11 +943,15 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
val = tswap32(val);
|
||||
if (len > lv)
|
||||
len = lv;
|
||||
if (len == 4)
|
||||
tput32(optval, val);
|
||||
else
|
||||
tput8(optval, val);
|
||||
tput32(optlen, len);
|
||||
if (len == 4) {
|
||||
if (put_user_u32(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
} else {
|
||||
if (put_user_u8(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
if (put_user_u32(len, optlen))
|
||||
return -TARGET_EFAULT;
|
||||
break;
|
||||
case SOL_IP:
|
||||
switch(optname) {
|
||||
@ -961,7 +970,8 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
#endif
|
||||
case IP_MULTICAST_TTL:
|
||||
case IP_MULTICAST_LOOP:
|
||||
len = tget32(optlen);
|
||||
if (get_user_u32(len, optlen))
|
||||
return -TARGET_EFAULT;
|
||||
if (len < 0)
|
||||
return -TARGET_EINVAL;
|
||||
lv = sizeof(int);
|
||||
@ -970,13 +980,15 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
|
||||
return ret;
|
||||
if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
|
||||
len = 1;
|
||||
tput32(optlen, len);
|
||||
tput8(optval, val);
|
||||
if (put_user_u32(len, optlen)
|
||||
|| put_user_u8(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
} else {
|
||||
if (len > sizeof(int))
|
||||
len = sizeof(int);
|
||||
tput32(optlen, len);
|
||||
tput32(optval, val);
|
||||
if (put_user_u32(len, optlen)
|
||||
|| put_user_u32(val, optval_addr))
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1148,63 +1160,82 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg,
|
||||
|
||||
/* do_accept() Must return target values and target errnos. */
|
||||
static abi_long do_accept(int fd, abi_ulong target_addr,
|
||||
abi_ulong target_addrlen)
|
||||
abi_ulong target_addrlen_addr)
|
||||
{
|
||||
socklen_t addrlen = tget32(target_addrlen);
|
||||
void *addr = alloca(addrlen);
|
||||
socklen_t addrlen;
|
||||
void *addr;
|
||||
abi_long ret;
|
||||
|
||||
if (get_user_u32(addrlen, target_addrlen_addr))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
addr = alloca(addrlen);
|
||||
|
||||
ret = get_errno(accept(fd, addr, &addrlen));
|
||||
if (!is_error(ret)) {
|
||||
host_to_target_sockaddr(target_addr, addr, addrlen);
|
||||
tput32(target_addrlen, addrlen);
|
||||
if (put_user_u32(addrlen, target_addrlen_addr))
|
||||
ret = -TARGET_EFAULT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do_getpeername() Must return target values and target errnos. */
|
||||
static abi_long do_getpeername(int fd, abi_ulong target_addr,
|
||||
abi_ulong target_addrlen)
|
||||
abi_ulong target_addrlen_addr)
|
||||
{
|
||||
socklen_t addrlen = tget32(target_addrlen);
|
||||
void *addr = alloca(addrlen);
|
||||
socklen_t addrlen;
|
||||
void *addr;
|
||||
abi_long ret;
|
||||
|
||||
if (get_user_u32(addrlen, target_addrlen_addr))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
addr = alloca(addrlen);
|
||||
|
||||
ret = get_errno(getpeername(fd, addr, &addrlen));
|
||||
if (!is_error(ret)) {
|
||||
host_to_target_sockaddr(target_addr, addr, addrlen);
|
||||
tput32(target_addrlen, addrlen);
|
||||
if (put_user_u32(addrlen, target_addrlen_addr))
|
||||
ret = -TARGET_EFAULT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do_getsockname() Must return target values and target errnos. */
|
||||
static abi_long do_getsockname(int fd, abi_ulong target_addr,
|
||||
abi_ulong target_addrlen)
|
||||
abi_ulong target_addrlen_addr)
|
||||
{
|
||||
socklen_t addrlen = tget32(target_addrlen);
|
||||
void *addr = alloca(addrlen);
|
||||
socklen_t addrlen;
|
||||
void *addr;
|
||||
abi_long ret;
|
||||
|
||||
if (get_user_u32(addrlen, target_addrlen_addr))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
addr = alloca(addrlen);
|
||||
|
||||
ret = get_errno(getsockname(fd, addr, &addrlen));
|
||||
if (!is_error(ret)) {
|
||||
host_to_target_sockaddr(target_addr, addr, addrlen);
|
||||
tput32(target_addrlen, addrlen);
|
||||
if (put_user_u32(addrlen, target_addrlen_addr))
|
||||
ret = -TARGET_EFAULT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do_socketpair() Must return target values and target errnos. */
|
||||
static abi_long do_socketpair(int domain, int type, int protocol,
|
||||
abi_ulong target_tab)
|
||||
abi_ulong target_tab_addr)
|
||||
{
|
||||
int tab[2];
|
||||
abi_long ret;
|
||||
|
||||
ret = get_errno(socketpair(domain, type, protocol, tab));
|
||||
if (!is_error(ret)) {
|
||||
tput32(target_tab, tab[0]);
|
||||
tput32(target_tab + 4, tab[1]);
|
||||
if (put_user_s32(tab[0], target_tab_addr)
|
||||
|| put_user_s32(tab[1], target_tab_addr + sizeof(tab[0])))
|
||||
ret = -TARGET_EFAULT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1245,7 +1276,10 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
|
||||
if (!host_msg)
|
||||
return -TARGET_EFAULT;
|
||||
if (target_addr) {
|
||||
addrlen = tget32(target_addrlen);
|
||||
if (get_user_u32(addrlen, target_addrlen)) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
addr = alloca(addrlen);
|
||||
ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
|
||||
} else {
|
||||
@ -1255,10 +1289,14 @@ static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags,
|
||||
if (!is_error(ret)) {
|
||||
if (target_addr) {
|
||||
host_to_target_sockaddr(target_addr, addr, addrlen);
|
||||
tput32(target_addrlen, addrlen);
|
||||
if (put_user_u32(addrlen, target_addrlen)) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
unlock_user(host_msg, msg, len);
|
||||
} else {
|
||||
fail:
|
||||
unlock_user(host_msg, msg, 0);
|
||||
}
|
||||
return ret;
|
||||
@ -1274,112 +1312,187 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
|
||||
switch(num) {
|
||||
case SOCKOP_socket:
|
||||
{
|
||||
int domain = tgetl(vptr);
|
||||
int type = tgetl(vptr + n);
|
||||
int protocol = tgetl(vptr + 2 * n);
|
||||
int domain, type, protocol;
|
||||
|
||||
if (get_user_s32(domain, vptr)
|
||||
|| get_user_s32(type, vptr + n)
|
||||
|| get_user_s32(protocol, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_socket(domain, type, protocol);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_bind:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong target_addr = tgetl(vptr + n);
|
||||
socklen_t addrlen = tgetl(vptr + 2 * n);
|
||||
int sockfd;
|
||||
abi_ulong target_addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(target_addr, vptr + n)
|
||||
|| get_user_u32(addrlen, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_bind(sockfd, target_addr, addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_connect:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong target_addr = tgetl(vptr + n);
|
||||
socklen_t addrlen = tgetl(vptr + 2 * n);
|
||||
int sockfd;
|
||||
abi_ulong target_addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(target_addr, vptr + n)
|
||||
|| get_user_u32(addrlen, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_connect(sockfd, target_addr, addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_listen:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
int backlog = tgetl(vptr + n);
|
||||
int sockfd, backlog;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_s32(backlog, vptr + n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = get_errno(listen(sockfd, backlog));
|
||||
}
|
||||
break;
|
||||
case SOCKOP_accept:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong target_addr = tgetl(vptr + n);
|
||||
abi_ulong target_addrlen = tgetl(vptr + 2 * n);
|
||||
int sockfd;
|
||||
abi_ulong target_addr, target_addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(target_addr, vptr + n)
|
||||
|| get_user_u32(target_addrlen, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_accept(sockfd, target_addr, target_addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_getsockname:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong target_addr = tgetl(vptr + n);
|
||||
abi_ulong target_addrlen = tgetl(vptr + 2 * n);
|
||||
int sockfd;
|
||||
abi_ulong target_addr, target_addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(target_addr, vptr + n)
|
||||
|| get_user_u32(target_addrlen, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_getsockname(sockfd, target_addr, target_addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_getpeername:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong target_addr = tgetl(vptr + n);
|
||||
abi_ulong target_addrlen = tgetl(vptr + 2 * n);
|
||||
int sockfd;
|
||||
abi_ulong target_addr, target_addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(target_addr, vptr + n)
|
||||
|| get_user_u32(target_addrlen, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_getpeername(sockfd, target_addr, target_addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_socketpair:
|
||||
{
|
||||
int domain = tgetl(vptr);
|
||||
int type = tgetl(vptr + n);
|
||||
int protocol = tgetl(vptr + 2 * n);
|
||||
abi_ulong tab = tgetl(vptr + 3 * n);
|
||||
int domain, type, protocol;
|
||||
abi_ulong tab;
|
||||
|
||||
if (get_user_s32(domain, vptr)
|
||||
|| get_user_s32(type, vptr + n)
|
||||
|| get_user_s32(protocol, vptr + 2 * n)
|
||||
|| get_user_ual(tab, vptr + 3 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_socketpair(domain, type, protocol, tab);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_send:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong msg = tgetl(vptr + n);
|
||||
size_t len = tgetl(vptr + 2 * n);
|
||||
int flags = tgetl(vptr + 3 * n);
|
||||
int sockfd;
|
||||
abi_ulong msg;
|
||||
size_t len;
|
||||
int flags;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(msg, vptr + n)
|
||||
|| get_user_ual(len, vptr + 2 * n)
|
||||
|| get_user_s32(flags, vptr + 3 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_sendto(sockfd, msg, len, flags, 0, 0);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_recv:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong msg = tgetl(vptr + n);
|
||||
size_t len = tgetl(vptr + 2 * n);
|
||||
int flags = tgetl(vptr + 3 * n);
|
||||
int sockfd;
|
||||
abi_ulong msg;
|
||||
size_t len;
|
||||
int flags;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(msg, vptr + n)
|
||||
|| get_user_ual(len, vptr + 2 * n)
|
||||
|| get_user_s32(flags, vptr + 3 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_recvfrom(sockfd, msg, len, flags, 0, 0);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_sendto:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong msg = tgetl(vptr + n);
|
||||
size_t len = tgetl(vptr + 2 * n);
|
||||
int flags = tgetl(vptr + 3 * n);
|
||||
abi_ulong addr = tgetl(vptr + 4 * n);
|
||||
socklen_t addrlen = tgetl(vptr + 5 * n);
|
||||
int sockfd;
|
||||
abi_ulong msg;
|
||||
size_t len;
|
||||
int flags;
|
||||
abi_ulong addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(msg, vptr + n)
|
||||
|| get_user_ual(len, vptr + 2 * n)
|
||||
|| get_user_s32(flags, vptr + 3 * n)
|
||||
|| get_user_ual(addr, vptr + 4 * n)
|
||||
|| get_user_u32(addrlen, vptr + 5 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_sendto(sockfd, msg, len, flags, addr, addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_recvfrom:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
abi_ulong msg = tgetl(vptr + n);
|
||||
size_t len = tgetl(vptr + 2 * n);
|
||||
int flags = tgetl(vptr + 3 * n);
|
||||
abi_ulong addr = tgetl(vptr + 4 * n);
|
||||
abi_ulong addrlen = tgetl(vptr + 5 * n);
|
||||
int sockfd;
|
||||
abi_ulong msg;
|
||||
size_t len;
|
||||
int flags;
|
||||
abi_ulong addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_ual(msg, vptr + n)
|
||||
|| get_user_ual(len, vptr + 2 * n)
|
||||
|| get_user_s32(flags, vptr + 3 * n)
|
||||
|| get_user_ual(addr, vptr + 4 * n)
|
||||
|| get_user_u32(addrlen, vptr + 5 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_recvfrom(sockfd, msg, len, flags, addr, addrlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_shutdown:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
int how = tgetl(vptr + n);
|
||||
int sockfd, how;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_s32(how, vptr + n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = get_errno(shutdown(sockfd, how));
|
||||
}
|
||||
@ -1391,9 +1504,10 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
|
||||
abi_ulong target_msg;
|
||||
int flags;
|
||||
|
||||
fd = tgetl(vptr);
|
||||
target_msg = tgetl(vptr + n);
|
||||
flags = tgetl(vptr + 2 * n);
|
||||
if (get_user_s32(fd, vptr)
|
||||
|| get_user_ual(target_msg, vptr + n)
|
||||
|| get_user_s32(flags, vptr + 2 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_sendrecvmsg(fd, target_msg, flags,
|
||||
(num == SOCKOP_sendmsg));
|
||||
@ -1401,24 +1515,38 @@ static abi_long do_socketcall(int num, abi_ulong vptr)
|
||||
break;
|
||||
case SOCKOP_setsockopt:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
int level = tgetl(vptr + n);
|
||||
int optname = tgetl(vptr + 2 * n);
|
||||
abi_ulong optval = tgetl(vptr + 3 * n);
|
||||
socklen_t optlen = tgetl(vptr + 4 * n);
|
||||
int sockfd;
|
||||
int level;
|
||||
int optname;
|
||||
abi_ulong optval;
|
||||
socklen_t optlen;
|
||||
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_s32(level, vptr + n)
|
||||
|| get_user_s32(optname, vptr + 2 * n)
|
||||
|| get_user_ual(optval, vptr + 3 * n)
|
||||
|| get_user_u32(optlen, vptr + 4 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_setsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
break;
|
||||
case SOCKOP_getsockopt:
|
||||
{
|
||||
int sockfd = tgetl(vptr);
|
||||
int level = tgetl(vptr + n);
|
||||
int optname = tgetl(vptr + 2 * n);
|
||||
abi_ulong optval = tgetl(vptr + 3 * n);
|
||||
abi_ulong poptlen = tgetl(vptr + 4 * n);
|
||||
int sockfd;
|
||||
int level;
|
||||
int optname;
|
||||
abi_ulong optval;
|
||||
socklen_t optlen;
|
||||
|
||||
ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
|
||||
if (get_user_s32(sockfd, vptr)
|
||||
|| get_user_s32(level, vptr + n)
|
||||
|| get_user_s32(optname, vptr + 2 * n)
|
||||
|| get_user_ual(optval, vptr + 3 * n)
|
||||
|| get_user_u32(optlen, vptr + 4 * n))
|
||||
return -TARGET_EFAULT;
|
||||
|
||||
ret = do_getsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1883,7 +2011,7 @@ static abi_long do_ipc(unsigned int call, int first,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (put_user(raddr, third, abi_ulong))
|
||||
if (put_user_ual(raddr, third))
|
||||
return -TARGET_EFAULT;
|
||||
ret = 0;
|
||||
}
|
||||
@ -2957,10 +3085,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
unlock_user(p, arg2, 0);
|
||||
break;
|
||||
case TARGET_NR_open:
|
||||
if (!(p = lock_user_string(arg1))) {
|
||||
return -TARGET_EFAULT;
|
||||
goto fail;
|
||||
}
|
||||
if (!(p = lock_user_string(arg1)))
|
||||
goto efault;
|
||||
ret = get_errno(open(path(p),
|
||||
target_to_host_bitmask(arg2, fcntl_flags_tbl),
|
||||
arg3));
|
||||
@ -2991,8 +3117,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
int status;
|
||||
ret = get_errno(waitpid(arg1, &status, arg3));
|
||||
if (!is_error(ret) && arg2)
|
||||
tput32(arg2, status);
|
||||
if (!is_error(ret) && arg2
|
||||
&& put_user_s32(status, arg2))
|
||||
goto efault;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -3059,56 +3186,71 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
|
||||
argc = 0;
|
||||
guest_argp = arg2;
|
||||
for (gp = guest_argp; tgetl(gp); gp++)
|
||||
for (gp = guest_argp; ; gp++) {
|
||||
if (get_user_ual(guest_argp, gp))
|
||||
goto efault;
|
||||
if (!guest_argp)
|
||||
break;
|
||||
argc++;
|
||||
}
|
||||
envc = 0;
|
||||
guest_envp = arg3;
|
||||
for (gp = guest_envp; tgetl(gp); gp++)
|
||||
for (gp = guest_envp; ; gp++) {
|
||||
if (get_user_ual(guest_envp, gp))
|
||||
goto efault;
|
||||
if (!guest_envp)
|
||||
break;
|
||||
envc++;
|
||||
}
|
||||
|
||||
argp = alloca((argc + 1) * sizeof(void *));
|
||||
envp = alloca((envc + 1) * sizeof(void *));
|
||||
|
||||
for (gp = guest_argp, q = argp; ;
|
||||
gp += sizeof(abi_ulong), q++) {
|
||||
addr = tgetl(gp);
|
||||
if (get_user_ual(addr, gp))
|
||||
goto execve_efault;
|
||||
if (!addr)
|
||||
break;
|
||||
if (!(*q = lock_user_string(addr))) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto execve_fail;
|
||||
}
|
||||
if (!(*q = lock_user_string(addr)))
|
||||
goto execve_efault;
|
||||
}
|
||||
*q = NULL;
|
||||
|
||||
for (gp = guest_envp, q = envp; ;
|
||||
gp += sizeof(abi_ulong), q++) {
|
||||
addr = tgetl(gp);
|
||||
if (get_user_ual(addr, gp))
|
||||
goto execve_efault;
|
||||
if (!addr)
|
||||
break;
|
||||
if (!(*q = lock_user_string(addr))) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto execve_fail;
|
||||
}
|
||||
if (!(*q = lock_user_string(addr)))
|
||||
goto execve_efault;
|
||||
}
|
||||
*q = NULL;
|
||||
|
||||
if (!(p = lock_user_string(arg1))) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto execve_fail;
|
||||
}
|
||||
if (!(p = lock_user_string(arg1)))
|
||||
goto execve_efault;
|
||||
ret = get_errno(execve(p, argp, envp));
|
||||
unlock_user(p, arg1, 0);
|
||||
|
||||
execve_fail:
|
||||
goto execve_end;
|
||||
|
||||
execve_efault:
|
||||
ret = -TARGET_EFAULT;
|
||||
|
||||
execve_end:
|
||||
for (gp = guest_argp, q = argp; *q;
|
||||
gp += sizeof(abi_ulong), q++) {
|
||||
addr = tgetl(gp);
|
||||
if (get_user_ual(addr, gp)
|
||||
|| !addr)
|
||||
break;
|
||||
unlock_user(*q, addr, 0);
|
||||
}
|
||||
for (gp = guest_envp, q = envp; *q;
|
||||
gp += sizeof(abi_ulong), q++) {
|
||||
addr = tgetl(gp);
|
||||
if (get_user_ual(addr, gp)
|
||||
|| !addr)
|
||||
break;
|
||||
unlock_user(*q, addr, 0);
|
||||
}
|
||||
}
|
||||
@ -3124,8 +3266,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
time_t host_time;
|
||||
ret = get_errno(time(&host_time));
|
||||
if (!is_error(ret) && arg1)
|
||||
tputl(arg1, host_time);
|
||||
if (!is_error(ret)
|
||||
&& arg1
|
||||
&& put_user_sal(host_time, arg1))
|
||||
goto efault;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -3199,7 +3343,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_stime:
|
||||
{
|
||||
time_t host_time;
|
||||
host_time = tgetl(arg1);
|
||||
if (get_user_sal(host_time, arg1))
|
||||
goto efault;
|
||||
ret = get_errno(stime(&host_time));
|
||||
}
|
||||
break;
|
||||
@ -3358,8 +3503,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
env->gpr[3][env->current_tc] = host_pipe[1];
|
||||
ret = host_pipe[0];
|
||||
#else
|
||||
tput32(arg1, host_pipe[0]);
|
||||
tput32(arg1 + 4, host_pipe[1]);
|
||||
if (put_user_s32(host_pipe[0], arg1)
|
||||
|| put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
|
||||
goto efault;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -4267,11 +4413,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
rusage_ptr = NULL;
|
||||
ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
|
||||
if (!is_error(ret)) {
|
||||
if (status_ptr)
|
||||
tputl(status_ptr, status);
|
||||
if (target_rusage) {
|
||||
host_to_target_rusage(target_rusage, &rusage);
|
||||
if (status_ptr) {
|
||||
if (put_user_s32(status, status_ptr))
|
||||
goto efault;
|
||||
}
|
||||
if (target_rusage)
|
||||
host_to_target_rusage(target_rusage, &rusage);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4404,11 +4551,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
#if defined (__x86_64__)
|
||||
ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
|
||||
tput64(arg4, ret);
|
||||
if (put_user_s64(ret, arg4))
|
||||
goto efault;
|
||||
#else
|
||||
int64_t res;
|
||||
ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
|
||||
tput64(arg4, res);
|
||||
if (put_user_s64(res, arg4))
|
||||
goto efault;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@ -4674,8 +4823,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
int deathsig;
|
||||
ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
|
||||
if (!is_error(ret) && arg2)
|
||||
tput32(arg2, deathsig);
|
||||
if (!is_error(ret) && arg2
|
||||
&& put_user_ual(deathsig, arg2))
|
||||
goto efault;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -4932,9 +5082,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
uid_t ruid, euid, suid;
|
||||
ret = get_errno(getresuid(&ruid, &euid, &suid));
|
||||
if (!is_error(ret)) {
|
||||
tput16(arg1, tswap16(high2lowuid(ruid)));
|
||||
tput16(arg2, tswap16(high2lowuid(euid)));
|
||||
tput16(arg3, tswap16(high2lowuid(suid)));
|
||||
if (put_user_u16(high2lowuid(ruid), arg1)
|
||||
|| put_user_u16(high2lowuid(euid), arg2)
|
||||
|| put_user_u16(high2lowuid(suid), arg3))
|
||||
goto efault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4952,9 +5103,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
gid_t rgid, egid, sgid;
|
||||
ret = get_errno(getresgid(&rgid, &egid, &sgid));
|
||||
if (!is_error(ret)) {
|
||||
tput16(arg1, tswap16(high2lowgid(rgid)));
|
||||
tput16(arg2, tswap16(high2lowgid(egid)));
|
||||
tput16(arg3, tswap16(high2lowgid(sgid)));
|
||||
if (put_user_u16(high2lowgid(rgid), arg1)
|
||||
|| put_user_u16(high2lowgid(egid), arg2)
|
||||
|| put_user_u16(high2lowgid(sgid), arg3))
|
||||
goto efault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -5077,9 +5229,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
uid_t ruid, euid, suid;
|
||||
ret = get_errno(getresuid(&ruid, &euid, &suid));
|
||||
if (!is_error(ret)) {
|
||||
tput32(arg1, tswap32(ruid));
|
||||
tput32(arg2, tswap32(euid));
|
||||
tput32(arg3, tswap32(suid));
|
||||
if (put_user_u32(ruid, arg1)
|
||||
|| put_user_u32(euid, arg2)
|
||||
|| put_user_u32(suid, arg3))
|
||||
goto efault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -5095,9 +5248,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
gid_t rgid, egid, sgid;
|
||||
ret = get_errno(getresgid(&rgid, &egid, &sgid));
|
||||
if (!is_error(ret)) {
|
||||
tput32(arg1, tswap32(rgid));
|
||||
tput32(arg2, tswap32(egid));
|
||||
tput32(arg3, tswap32(sgid));
|
||||
if (put_user_u32(rgid, arg1)
|
||||
|| put_user_u32(egid, arg2)
|
||||
|| put_user_u32(sgid, arg3))
|
||||
goto efault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
28
m68k-semi.c
28
m68k-semi.c
@ -142,15 +142,23 @@ static void m68k_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
|
||||
if (m68k_semi_is_fseek) {
|
||||
/* FIXME: We've already lost the high bits of the fseek
|
||||
return value. */
|
||||
tput32(args, 0);
|
||||
/* FIXME - handle put_user() failure */
|
||||
put_user_u32(0, args);
|
||||
args += 4;
|
||||
m68k_semi_is_fseek = 0;
|
||||
}
|
||||
tput32(args, ret);
|
||||
tput32(args + 4, errno);
|
||||
/* FIXME - handle put_user() failure */
|
||||
put_user_u32(ret, args);
|
||||
put_user_u32(errno, args + 4);
|
||||
}
|
||||
|
||||
#define ARG(x) tget32(args + (x) * 4)
|
||||
#define ARG(n) \
|
||||
({ \
|
||||
target_ulong __arg; \
|
||||
/* FIXME - handle get_user() failure */ \
|
||||
get_user_ual(__arg, args + (n) * 4); \
|
||||
__arg; \
|
||||
})
|
||||
#define PARG(x) ((unsigned long)ARG(x))
|
||||
void do_m68k_semihosting(CPUM68KState *env, int nr)
|
||||
{
|
||||
@ -237,9 +245,10 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
|
||||
ARG(0), off, ARG(3));
|
||||
} else {
|
||||
off = lseek(ARG(0), off, ARG(3));
|
||||
tput32(args, off >> 32);
|
||||
tput32(args + 4, off);
|
||||
tput32(args + 8, errno);
|
||||
/* FIXME - handle put_user() failure */
|
||||
put_user_u32(off >> 32, args);
|
||||
put_user_u32(off, args + 4);
|
||||
put_user_u32(errno, args + 8);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -390,6 +399,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
|
||||
cpu_abort(env, "Unsupported semihosting syscall %d\n", nr);
|
||||
result = 0;
|
||||
}
|
||||
tput32(args, result);
|
||||
tput32(args + 4, errno);
|
||||
/* FIXME - handle put_user() failure */
|
||||
put_user_u32(result, args);
|
||||
put_user_u32(errno, args + 4);
|
||||
}
|
||||
|
@ -21,15 +21,18 @@ static inline uint32_t softmmu_tget8(CPUState *env, uint32_t addr)
|
||||
cpu_memory_rw_debug(env, addr, &val, 1, 0);
|
||||
return val;
|
||||
}
|
||||
#define tget32(p) softmmu_tget32(env, p)
|
||||
#define tget8(p) softmmu_tget8(env, p)
|
||||
|
||||
#define get_user_u32(arg, p) ({ arg = softmmu_tget32(env, p) ; 0; })
|
||||
#define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; })
|
||||
#define get_user_ual(arg, p) get_user_u32(arg, p)
|
||||
|
||||
static inline void softmmu_tput32(CPUState *env, uint32_t addr, uint32_t val)
|
||||
{
|
||||
val = tswap32(val);
|
||||
cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
|
||||
}
|
||||
#define tput32(p, val) softmmu_tput32(env, p, val)
|
||||
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
|
||||
#define put_user_ual(arg, p) put_user_u32(arg, p)
|
||||
|
||||
static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,
|
||||
int copy)
|
||||
|
@ -34,7 +34,8 @@ void loadSingle(const unsigned int Fn,const unsigned int *pMem)
|
||||
target_ulong addr = (target_ulong)(long)pMem;
|
||||
FPA11 *fpa11 = GET_FPA11();
|
||||
fpa11->fType[Fn] = typeSingle;
|
||||
fpa11->fpreg[Fn].fSingle = tget32(addr);
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(fpa11->fpreg[Fn].fSingle, addr);
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -46,11 +47,13 @@ void loadDouble(const unsigned int Fn,const unsigned int *pMem)
|
||||
p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
|
||||
fpa11->fType[Fn] = typeDouble;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
p[0] = tget32(addr); /* sign & exponent */
|
||||
p[1] = tget32(addr + 4);
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(p[0], addr); /* sign & exponent */
|
||||
get_user_u32(p[1], addr + 4);
|
||||
#else
|
||||
p[0] = tget32(addr + 4);
|
||||
p[1] = tget32(addr); /* sign & exponent */
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(p[0], addr + 4);
|
||||
get_user_u32(p[1], addr); /* sign & exponent */
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -62,9 +65,10 @@ void loadExtended(const unsigned int Fn,const unsigned int *pMem)
|
||||
unsigned int *p;
|
||||
p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
|
||||
fpa11->fType[Fn] = typeExtended;
|
||||
p[0] = tget32(addr); /* sign & exponent */
|
||||
p[1] = tget32(addr + 8); /* ls bits */
|
||||
p[2] = tget32(addr + 4); /* ms bits */
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(p[0], addr); /* sign & exponent */
|
||||
get_user_u32(p[1], addr + 8); /* ls bits */
|
||||
get_user_u32(p[2], addr + 4); /* ms bits */
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -76,7 +80,8 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
|
||||
unsigned long x;
|
||||
|
||||
p = (unsigned int*)&(fpa11->fpreg[Fn]);
|
||||
x = tget32(addr);
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(x, addr);
|
||||
fpa11->fType[Fn] = (x >> 14) & 0x00000003;
|
||||
|
||||
switch (fpa11->fType[Fn])
|
||||
@ -84,16 +89,18 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
|
||||
case typeSingle:
|
||||
case typeDouble:
|
||||
{
|
||||
p[0] = tget32(addr + 8); /* Single */
|
||||
p[1] = tget32(addr + 4); /* double msw */
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(p[0], addr + 8); /* Single */
|
||||
get_user_u32(p[1], addr + 4); /* double msw */
|
||||
p[2] = 0; /* empty */
|
||||
}
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
{
|
||||
p[1] = tget32(addr + 8);
|
||||
p[2] = tget32(addr + 4); /* msw */
|
||||
/* FIXME - handle failure of get_user() */
|
||||
get_user_u32(p[1], addr + 8);
|
||||
get_user_u32(p[2], addr + 4); /* msw */
|
||||
p[0] = (x & 0x80003fff);
|
||||
}
|
||||
break;
|
||||
@ -121,7 +128,8 @@ void storeSingle(const unsigned int Fn,unsigned int *pMem)
|
||||
default: val = fpa11->fpreg[Fn].fSingle;
|
||||
}
|
||||
|
||||
tput32(addr, p[0]);
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_u32(p[0], addr);
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -144,12 +152,13 @@ void storeDouble(const unsigned int Fn,unsigned int *pMem)
|
||||
|
||||
default: val = fpa11->fpreg[Fn].fDouble;
|
||||
}
|
||||
/* FIXME - handle put_user() failures */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
tput32(addr, p[0]); /* msw */
|
||||
tput32(addr + 4, p[1]); /* lsw */
|
||||
put_user_u32(p[0], addr); /* msw */
|
||||
put_user_u32(p[1], addr + 4); /* lsw */
|
||||
#else
|
||||
tput32(addr, p[1]); /* msw */
|
||||
tput32(addr + 4, p[0]); /* lsw */
|
||||
put_user_u32(p[1], addr); /* msw */
|
||||
put_user_u32(p[0], addr + 4); /* lsw */
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -174,9 +183,10 @@ void storeExtended(const unsigned int Fn,unsigned int *pMem)
|
||||
default: val = fpa11->fpreg[Fn].fExtended;
|
||||
}
|
||||
|
||||
tput32(addr, p[0]); /* sign & exp */
|
||||
tput32(addr + 8, p[1]);
|
||||
tput32(addr + 4, p[2]); /* msw */
|
||||
/* FIXME - handle put_user() failures */
|
||||
put_user_u32(p[0], addr); /* sign & exp */
|
||||
put_user_u32(p[1], addr + 8);
|
||||
put_user_u32(p[2], addr + 4); /* msw */
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -194,17 +204,17 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem)
|
||||
case typeSingle:
|
||||
case typeDouble:
|
||||
{
|
||||
tput32(addr + 8, p[0]); /* single */
|
||||
tput32(addr + 4, p[1]); /* double msw */
|
||||
tput32(addr, nType << 14);
|
||||
put_user_u32(p[0], addr + 8); /* single */
|
||||
put_user_u32(p[1], addr + 4); /* double msw */
|
||||
put_user_u32(nType << 14, addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case typeExtended:
|
||||
{
|
||||
tput32(addr + 4, p[2]); /* msw */
|
||||
tput32(addr + 8, p[1]);
|
||||
tput32(addr, (p[0] & 0x80003fff) | (nType << 14));
|
||||
put_user_u32(p[2], addr + 4); /* msw */
|
||||
put_user_u32(p[1], addr + 8);
|
||||
put_user_u32((p[0] & 0x80003fff) | (nType << 14), addr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user