Commit 53a5960aadd542dd27b8705ac30df154557d5ffc

Authored by pbrook
1 parent 26f69dc0

Avoid accessing guest memory directly in usermode emulation.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1790 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -584,22 +584,41 @@ static inline void stfq_be_p(void *ptr, float64 v)
584 584  
585 585 /* MMU memory access macros */
586 586  
  587 +#if defined(CONFIG_USER_ONLY)
  588 +/* On some host systems the guest address space is reserved on the host.
  589 + * This allows the guest address space to be offset to a convenient location.
  590 + */
  591 +//#define GUEST_BASE 0x20000000
  592 +#define GUEST_BASE 0
  593 +
  594 +/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
  595 +#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
  596 +#define h2g(x) ((target_ulong)(x - GUEST_BASE))
  597 +
  598 +#define saddr(x) g2h(x)
  599 +#define laddr(x) g2h(x)
  600 +
  601 +#else /* !CONFIG_USER_ONLY */
587 602 /* NOTE: we use double casts if pointers and target_ulong have
588 603 different sizes */
589   -#define ldub_raw(p) ldub_p((uint8_t *)(long)(p))
590   -#define ldsb_raw(p) ldsb_p((uint8_t *)(long)(p))
591   -#define lduw_raw(p) lduw_p((uint8_t *)(long)(p))
592   -#define ldsw_raw(p) ldsw_p((uint8_t *)(long)(p))
593   -#define ldl_raw(p) ldl_p((uint8_t *)(long)(p))
594   -#define ldq_raw(p) ldq_p((uint8_t *)(long)(p))
595   -#define ldfl_raw(p) ldfl_p((uint8_t *)(long)(p))
596   -#define ldfq_raw(p) ldfq_p((uint8_t *)(long)(p))
597   -#define stb_raw(p, v) stb_p((uint8_t *)(long)(p), v)
598   -#define stw_raw(p, v) stw_p((uint8_t *)(long)(p), v)
599   -#define stl_raw(p, v) stl_p((uint8_t *)(long)(p), v)
600   -#define stq_raw(p, v) stq_p((uint8_t *)(long)(p), v)
601   -#define stfl_raw(p, v) stfl_p((uint8_t *)(long)(p), v)
602   -#define stfq_raw(p, v) stfq_p((uint8_t *)(long)(p), v)
  604 +#define saddr(x) (uint8_t *)(long)(x)
  605 +#define laddr(x) (uint8_t *)(long)(x)
  606 +#endif
  607 +
  608 +#define ldub_raw(p) ldub_p(laddr((p)))
  609 +#define ldsb_raw(p) ldsb_p(laddr((p)))
  610 +#define lduw_raw(p) lduw_p(laddr((p)))
  611 +#define ldsw_raw(p) ldsw_p(laddr((p)))
  612 +#define ldl_raw(p) ldl_p(laddr((p)))
  613 +#define ldq_raw(p) ldq_p(laddr((p)))
  614 +#define ldfl_raw(p) ldfl_p(laddr((p)))
  615 +#define ldfq_raw(p) ldfq_p(laddr((p)))
  616 +#define stb_raw(p, v) stb_p(saddr((p)), v)
  617 +#define stw_raw(p, v) stw_p(saddr((p)), v)
  618 +#define stl_raw(p, v) stl_p(saddr((p)), v)
  619 +#define stq_raw(p, v) stq_p(saddr((p)), v)
  620 +#define stfl_raw(p, v) stfl_p(saddr((p)), v)
  621 +#define stfq_raw(p, v) stfq_p(saddr((p)), v)
603 622  
604 623  
605 624 #if defined(CONFIG_USER_ONLY)
... ... @@ -648,6 +667,7 @@ static inline void stfq_be_p(void *ptr, float64 v)
648 667 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
649 668 #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
650 669  
  670 +/* ??? These should be the larger of unsigned long and target_ulong. */
651 671 extern unsigned long qemu_real_host_page_size;
652 672 extern unsigned long qemu_host_page_bits;
653 673 extern unsigned long qemu_host_page_size;
... ... @@ -666,9 +686,9 @@ extern unsigned long qemu_host_page_mask;
666 686 #define PAGE_WRITE_ORG 0x0010
667 687  
668 688 void page_dump(FILE *f);
669   -int page_get_flags(unsigned long address);
670   -void page_set_flags(unsigned long start, unsigned long end, int flags);
671   -void page_unprotect_range(uint8_t *data, unsigned long data_size);
  689 +int page_get_flags(target_ulong address);
  690 +void page_set_flags(target_ulong start, target_ulong end, int flags);
  691 +void page_unprotect_range(target_ulong data, target_ulong data_size);
672 692  
673 693 #define SINGLE_CPU_DEFINES
674 694 #ifdef SINGLE_CPU_DEFINES
... ...
cpu-exec.c
... ... @@ -913,7 +913,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
913 913 pc, address, is_write, *(unsigned long *)old_set);
914 914 #endif
915 915 /* XXX: locking issue */
916   - if (is_write && page_unprotect(address, pc, puc)) {
  916 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
917 917 return 1;
918 918 }
919 919  
... ... @@ -964,7 +964,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
964 964 pc, address, is_write, *(unsigned long *)old_set);
965 965 #endif
966 966 /* XXX: locking issue */
967   - if (is_write && page_unprotect(address, pc, puc)) {
  967 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
968 968 return 1;
969 969 }
970 970 /* see if it is an MMU fault */
... ... @@ -1000,7 +1000,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1000 1000 pc, address, is_write, *(unsigned long *)old_set);
1001 1001 #endif
1002 1002 /* XXX: locking issue */
1003   - if (is_write && page_unprotect(address, pc, puc)) {
  1003 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1004 1004 return 1;
1005 1005 }
1006 1006 /* see if it is an MMU fault */
... ... @@ -1036,7 +1036,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1036 1036 pc, address, is_write, *(unsigned long *)old_set);
1037 1037 #endif
1038 1038 /* XXX: locking issue */
1039   - if (is_write && page_unprotect(address, pc, puc)) {
  1039 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1040 1040 return 1;
1041 1041 }
1042 1042  
... ... @@ -1086,7 +1086,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1086 1086 pc, address, is_write, *(unsigned long *)old_set);
1087 1087 #endif
1088 1088 /* XXX: locking issue */
1089   - if (is_write && page_unprotect(address, pc, puc)) {
  1089 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1090 1090 return 1;
1091 1091 }
1092 1092  
... ...
exec-all.h
... ... @@ -93,7 +93,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb,
93 93 void *puc);
94 94 void cpu_resume_from_signal(CPUState *env1, void *puc);
95 95 void cpu_exec_init(CPUState *env);
96   -int page_unprotect(unsigned long address, unsigned long pc, void *puc);
  96 +int page_unprotect(target_ulong address, unsigned long pc, void *puc);
97 97 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
98 98 int is_cpu_write_access);
99 99 void tb_invalidate_page_range(target_ulong start, target_ulong end);
... ...
... ... @@ -34,6 +34,9 @@
34 34  
35 35 #include "cpu.h"
36 36 #include "exec-all.h"
  37 +#if defined(CONFIG_USER_ONLY)
  38 +#include <qemu.h>
  39 +#endif
37 40  
38 41 //#define DEBUG_TB_INVALIDATE
39 42 //#define DEBUG_FLUSH
... ... @@ -810,7 +813,7 @@ static void tb_invalidate_phys_page(target_ulong addr,
810 813  
811 814 /* add the tb in the target page and protect it if necessary */
812 815 static inline void tb_alloc_page(TranslationBlock *tb,
813   - unsigned int n, unsigned int page_addr)
  816 + unsigned int n, target_ulong page_addr)
814 817 {
815 818 PageDesc *p;
816 819 TranslationBlock *last_first_tb;
... ... @@ -826,23 +829,30 @@ static inline void tb_alloc_page(TranslationBlock *tb,
826 829  
827 830 #if defined(CONFIG_USER_ONLY)
828 831 if (p->flags & PAGE_WRITE) {
829   - unsigned long host_start, host_end, addr;
  832 + target_ulong addr;
  833 + PageDesc *p2;
830 834 int prot;
831 835  
832 836 /* force the host page as non writable (writes will have a
833 837 page fault + mprotect overhead) */
834   - host_start = page_addr & qemu_host_page_mask;
835   - host_end = host_start + qemu_host_page_size;
  838 + page_addr &= qemu_host_page_mask;
836 839 prot = 0;
837   - for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
838   - prot |= page_get_flags(addr);
839   - mprotect((void *)host_start, qemu_host_page_size,
  840 + for(addr = page_addr; addr < page_addr + qemu_host_page_size;
  841 + addr += TARGET_PAGE_SIZE) {
  842 +
  843 + p2 = page_find (addr >> TARGET_PAGE_BITS);
  844 + if (!p2)
  845 + continue;
  846 + prot |= p2->flags;
  847 + p2->flags &= ~PAGE_WRITE;
  848 + page_get_flags(addr);
  849 + }
  850 + mprotect(g2h(page_addr), qemu_host_page_size,
840 851 (prot & PAGE_BITS) & ~PAGE_WRITE);
841 852 #ifdef DEBUG_TB_INVALIDATE
842 853 printf("protecting code page: 0x%08lx\n",
843   - host_start);
  854 + page_addr);
844 855 #endif
845   - p->flags &= ~PAGE_WRITE;
846 856 }
847 857 #else
848 858 /* if some code is already present, then the pages are already
... ... @@ -1546,7 +1556,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1546 1556  
1547 1557 /* called from signal handler: invalidate the code and unprotect the
1548 1558 page. Return TRUE if the fault was succesfully handled. */
1549   -int page_unprotect(unsigned long addr, unsigned long pc, void *puc)
  1559 +int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
1550 1560 {
1551 1561 #if !defined(CONFIG_SOFTMMU)
1552 1562 VirtPageDesc *vp;
... ... @@ -1645,7 +1655,7 @@ void page_dump(FILE *f)
1645 1655 }
1646 1656 }
1647 1657  
1648   -int page_get_flags(unsigned long address)
  1658 +int page_get_flags(target_ulong address)
1649 1659 {
1650 1660 PageDesc *p;
1651 1661  
... ... @@ -1658,10 +1668,10 @@ int page_get_flags(unsigned long address)
1658 1668 /* modify the flags of a page and invalidate the code if
1659 1669 necessary. The flag PAGE_WRITE_ORG is positionned automatically
1660 1670 depending on PAGE_WRITE */
1661   -void page_set_flags(unsigned long start, unsigned long end, int flags)
  1671 +void page_set_flags(target_ulong start, target_ulong end, int flags)
1662 1672 {
1663 1673 PageDesc *p;
1664   - unsigned long addr;
  1674 + target_ulong addr;
1665 1675  
1666 1676 start = start & TARGET_PAGE_MASK;
1667 1677 end = TARGET_PAGE_ALIGN(end);
... ... @@ -1684,11 +1694,11 @@ void page_set_flags(unsigned long start, unsigned long end, int flags)
1684 1694  
1685 1695 /* called from signal handler: invalidate the code and unprotect the
1686 1696 page. Return TRUE if the fault was succesfully handled. */
1687   -int page_unprotect(unsigned long address, unsigned long pc, void *puc)
  1697 +int page_unprotect(target_ulong address, unsigned long pc, void *puc)
1688 1698 {
1689 1699 unsigned int page_index, prot, pindex;
1690 1700 PageDesc *p, *p1;
1691   - unsigned long host_start, host_end, addr;
  1701 + target_ulong host_start, host_end, addr;
1692 1702  
1693 1703 host_start = address & qemu_host_page_mask;
1694 1704 page_index = host_start >> TARGET_PAGE_BITS;
... ... @@ -1707,7 +1717,7 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
1707 1717 if (prot & PAGE_WRITE_ORG) {
1708 1718 pindex = (address - host_start) >> TARGET_PAGE_BITS;
1709 1719 if (!(p1[pindex].flags & PAGE_WRITE)) {
1710   - mprotect((void *)host_start, qemu_host_page_size,
  1720 + mprotect((void *)g2h(host_start), qemu_host_page_size,
1711 1721 (prot & PAGE_BITS) | PAGE_WRITE);
1712 1722 p1[pindex].flags |= PAGE_WRITE;
1713 1723 /* and since the content will be modified, we must invalidate
... ... @@ -1723,11 +1733,12 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
1723 1733 }
1724 1734  
1725 1735 /* call this function when system calls directly modify a memory area */
1726   -void page_unprotect_range(uint8_t *data, unsigned long data_size)
  1736 +/* ??? This should be redundant now we have lock_user. */
  1737 +void page_unprotect_range(target_ulong data, target_ulong data_size)
1727 1738 {
1728   - unsigned long start, end, addr;
  1739 + target_ulong start, end, addr;
1729 1740  
1730   - start = (unsigned long)data;
  1741 + start = data;
1731 1742 end = start + data_size;
1732 1743 start &= TARGET_PAGE_MASK;
1733 1744 end = TARGET_PAGE_ALIGN(end);
... ... @@ -1932,6 +1943,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1932 1943 {
1933 1944 int l, flags;
1934 1945 target_ulong page;
  1946 + void * p;
1935 1947  
1936 1948 while (len > 0) {
1937 1949 page = addr & TARGET_PAGE_MASK;
... ... @@ -1944,11 +1956,15 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1944 1956 if (is_write) {
1945 1957 if (!(flags & PAGE_WRITE))
1946 1958 return;
1947   - memcpy((uint8_t *)addr, buf, len);
  1959 + p = lock_user(addr, len, 0);
  1960 + memcpy(p, buf, len);
  1961 + unlock_user(p, addr, len);
1948 1962 } else {
1949 1963 if (!(flags & PAGE_READ))
1950 1964 return;
1951   - memcpy(buf, (uint8_t *)addr, len);
  1965 + p = lock_user(addr, len, 1);
  1966 + memcpy(buf, p, len);
  1967 + unlock_user(p, addr, 0);
1952 1968 }
1953 1969 len -= l;
1954 1970 buf += l;
... ...
linux-user/arm-semi.c
... ... @@ -77,20 +77,20 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
77 77 return code;
78 78 }
79 79  
80   -#define ARG(x) tswap32(args[x])
  80 +#define ARG(n) tget32(args + n * 4)
81 81 uint32_t do_arm_semihosting(CPUState *env)
82 82 {
83   - uint32_t *args;
  83 + target_ulong args;
84 84 char * s;
85 85 int nr;
86 86 uint32_t ret;
87 87 TaskState *ts = env->opaque;
88 88  
89 89 nr = env->regs[0];
90   - args = (uint32_t *)env->regs[1];
  90 + args = env->regs[1];
91 91 switch (nr) {
92 92 case SYS_OPEN:
93   - s = (char *)ARG(0);
  93 + s = (char *)g2h(ARG(0));
94 94 if (ARG(1) >= 12)
95 95 return (uint32_t)-1;
96 96 if (strcmp(s, ":tt") == 0) {
... ... @@ -103,18 +103,23 @@ uint32_t do_arm_semihosting(CPUState *env)
103 103 case SYS_CLOSE:
104 104 return set_swi_errno(ts, close(ARG(0)));
105 105 case SYS_WRITEC:
106   - /* Write to debug console. stderr is near enough. */
107   - return write(STDERR_FILENO, args, 1);
  106 + {
  107 + char c = tget8(args);
  108 + /* Write to debug console. stderr is near enough. */
  109 + return write(STDERR_FILENO, &c, 1);
  110 + }
108 111 case SYS_WRITE0:
109   - s = (char *)args;
110   - return write(STDERR_FILENO, s, strlen(s));
  112 + s = lock_user_string(args);
  113 + ret = write(STDERR_FILENO, s, strlen(s));
  114 + unlock_user(s, args, 0);
  115 + return ret;
111 116 case SYS_WRITE:
112   - ret = set_swi_errno(ts, write(ARG(0), (void *)ARG(1), ARG(2)));
  117 + ret = set_swi_errno(ts, write(ARG(0), g2h(ARG(1)), ARG(2)));
113 118 if (ret == (uint32_t)-1)
114 119 return -1;
115 120 return ARG(2) - ret;
116 121 case SYS_READ:
117   - ret = set_swi_errno(ts, read(ARG(0), (void *)ARG(1), ARG(2)));
  122 + ret = set_swi_errno(ts, read(ARG(0), g2h(ARG(1)), ARG(2)));
118 123 if (ret == (uint32_t)-1)
119 124 return -1;
120 125 return ARG(2) - ret;
... ... @@ -140,20 +145,21 @@ uint32_t do_arm_semihosting(CPUState *env)
140 145 /* XXX: Not implemented. */
141 146 return -1;
142 147 case SYS_REMOVE:
143   - return set_swi_errno(ts, remove((char *)ARG(0)));
  148 + return set_swi_errno(ts, remove((char *)g2h(ARG(0))));
144 149 case SYS_RENAME:
145   - return set_swi_errno(ts, rename((char *)ARG(0), (char *)ARG(2)));
  150 + return set_swi_errno(ts, rename((char *)g2h(ARG(0)),
  151 + (char *)g2h(ARG(2))));
146 152 case SYS_CLOCK:
147 153 return clock() / (CLOCKS_PER_SEC / 100);
148 154 case SYS_TIME:
149 155 return set_swi_errno(ts, time(NULL));
150 156 case SYS_SYSTEM:
151   - return set_swi_errno(ts, system((char *)ARG(0)));
  157 + return set_swi_errno(ts, system((char *)g2h(ARG(0))));
152 158 case SYS_ERRNO:
153 159 return ts->swi_errno;
154 160 case SYS_GET_CMDLINE:
155 161 /* XXX: Not implemented. */
156   - s = (char *)ARG(0);
  162 + s = (char *)g2h(ARG(0));
157 163 *s = 0;
158 164 return -1;
159 165 case SYS_HEAPINFO:
... ... @@ -166,11 +172,11 @@ uint32_t do_arm_semihosting(CPUState *env)
166 172 if (!ts->heap_limit) {
167 173 long ret;
168 174  
169   - ts->heap_base = do_brk(NULL);
  175 + ts->heap_base = do_brk(0);
170 176 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
171 177 /* Try a big heap, and reduce the size if that fails. */
172 178 for (;;) {
173   - ret = do_brk((char *)limit);
  179 + ret = do_brk(limit);
174 180 if (ret != -1)
175 181 break;
176 182 limit = (ts->heap_base >> 1) + (limit >> 1);
... ... @@ -178,7 +184,8 @@ uint32_t do_arm_semihosting(CPUState *env)
178 184 ts->heap_limit = limit;
179 185 }
180 186  
181   - ptr = (uint32_t *)ARG(0);
  187 + page_unprotect_range (ARG(0), 32);
  188 + ptr = (uint32_t *)g2h(ARG(0));
182 189 ptr[0] = tswap32(ts->heap_base);
183 190 ptr[1] = tswap32(ts->heap_limit);
184 191 ptr[2] = tswap32(ts->stack_base);
... ...
linux-user/elfload.c
... ... @@ -97,17 +97,17 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
97 97  
98 98 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
99 99 {
100   - target_long *stack = (void *)infop->start_stack;
  100 + target_long stack = infop->start_stack;
101 101 memset(regs, 0, sizeof(*regs));
102 102 regs->ARM_cpsr = 0x10;
103 103 if (infop->entry & 1)
104 104 regs->ARM_cpsr |= CPSR_T;
105 105 regs->ARM_pc = infop->entry & 0xfffffffe;
106 106 regs->ARM_sp = infop->start_stack;
107   - regs->ARM_r2 = tswapl(stack[2]); /* envp */
108   - regs->ARM_r1 = tswapl(stack[1]); /* argv */
  107 + regs->ARM_r2 = tgetl(stack + 8); /* envp */
  108 + regs->ARM_r1 = tgetl(stack + 4); /* envp */
109 109 /* XXX: it seems that r0 is zeroed after ! */
110   - // regs->ARM_r0 = tswapl(stack[0]); /* argc */
  110 + // regs->ARM_r0 = tgetl(stack); /* argc */
111 111 }
112 112  
113 113 #define USE_ELF_CORE_DUMP
... ... @@ -202,7 +202,7 @@ do { \
202 202 _r->gpr[3] = bprm->argc; \
203 203 _r->gpr[4] = (unsigned long)++pos; \
204 204 for (; tmp != 0; pos++) \
205   - tmp = *pos; \
  205 + tmp = ldl(pos); \
206 206 _r->gpr[5] = (unsigned long)pos; \
207 207 } while (0)
208 208  
... ... @@ -297,7 +297,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
297 297 */
298 298 struct linux_binprm {
299 299 char buf[128];
300   - unsigned long page[MAX_ARG_PAGES];
  300 + void *page[MAX_ARG_PAGES];
301 301 unsigned long p;
302 302 int sh_bang;
303 303 int fd;
... ... @@ -427,37 +427,13 @@ static void bswap_sym(Elf32_Sym *sym)
427 427 }
428 428 #endif
429 429  
430   -static void * get_free_page(void)
431   -{
432   - void * retval;
433   -
434   - /* User-space version of kernel get_free_page. Returns a page-aligned
435   - * page-sized chunk of memory.
436   - */
437   - retval = (void *)target_mmap(0, qemu_host_page_size, PROT_READ|PROT_WRITE,
438   - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
439   -
440   - if((long)retval == -1) {
441   - perror("get_free_page");
442   - exit(-1);
443   - }
444   - else {
445   - return(retval);
446   - }
447   -}
448   -
449   -static void free_page(void * pageaddr)
450   -{
451   - target_munmap((unsigned long)pageaddr, qemu_host_page_size);
452   -}
453   -
454 430 /*
455 431 * 'copy_string()' copies argument/envelope strings from user
456 432 * memory to free pages in kernel mem. These are in a format ready
457 433 * to be put directly into the top of new user memory.
458 434 *
459 435 */
460   -static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
  436 +static unsigned long copy_strings(int argc,char ** argv, void **page,
461 437 unsigned long p)
462 438 {
463 439 char *tmp, *tmp1, *pag = NULL;
... ... @@ -482,10 +458,10 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
482 458 --p; --tmp; --len;
483 459 if (--offset < 0) {
484 460 offset = p % TARGET_PAGE_SIZE;
485   - pag = (char *) page[p/TARGET_PAGE_SIZE];
  461 + pag = (char *)page[p/TARGET_PAGE_SIZE];
486 462 if (!pag) {
487   - pag = (char *)get_free_page();
488   - page[p/TARGET_PAGE_SIZE] = (unsigned long)pag;
  463 + pag = (char *)malloc(TARGET_PAGE_SIZE);
  464 + page[p/TARGET_PAGE_SIZE] = pag;
489 465 if (!pag)
490 466 return 0;
491 467 }
... ... @@ -591,10 +567,20 @@ static int prepare_binprm(struct linux_binprm *bprm)
591 567 }
592 568 }
593 569  
594   -unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
595   - struct image_info * info)
  570 +static inline void memcpy_to_target(target_ulong dest, const void *src,
  571 + unsigned long len)
596 572 {
597   - unsigned long stack_base, size, error;
  573 + void *host_ptr;
  574 +
  575 + host_ptr = lock_user(dest, len, 0);
  576 + memcpy(host_ptr, src, len);
  577 + unlock_user(host_ptr, dest, 1);
  578 +}
  579 +
  580 +unsigned long setup_arg_pages(target_ulong p, struct linux_binprm * bprm,
  581 + struct image_info * info)
  582 +{
  583 + target_ulong stack_base, size, error;
598 584 int i;
599 585  
600 586 /* Create enough stack to hold everything. If we don't use
... ... @@ -627,10 +613,10 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
627 613 if (bprm->page[i]) {
628 614 info->rss++;
629 615  
630   - memcpy((void *)stack_base, (void *)bprm->page[i], TARGET_PAGE_SIZE);
631   - free_page((void *)bprm->page[i]);
  616 + memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE);
  617 + free(bprm->page[i]);
632 618 }
633   - stack_base += TARGET_PAGE_SIZE;
  619 + stack_base += TARGET_PAGE_SIZE;
634 620 }
635 621 return p;
636 622 }
... ... @@ -657,7 +643,6 @@ static void set_brk(unsigned long start, unsigned long end)
657 643 static void padzero(unsigned long elf_bss)
658 644 {
659 645 unsigned long nbyte;
660   - char * fpnt;
661 646  
662 647 /* XXX: this is really a hack : if the real host page size is
663 648 smaller than the target page size, some pages after the end
... ... @@ -679,55 +664,57 @@ static void padzero(unsigned long elf_bss)
679 664 nbyte = elf_bss & (qemu_host_page_size-1);
680 665 if (nbyte) {
681 666 nbyte = qemu_host_page_size - nbyte;
682   - fpnt = (char *) elf_bss;
683 667 do {
684   - *fpnt++ = 0;
  668 + tput8(elf_bss, 0);
  669 + elf_bss++;
685 670 } while (--nbyte);
686 671 }
687 672 }
688 673  
689   -static unsigned int * create_elf_tables(char *p, int argc, int envc,
690   - struct elfhdr * exec,
691   - unsigned long load_addr,
692   - unsigned long load_bias,
693   - unsigned long interp_load_addr, int ibcs,
694   - struct image_info *info)
  674 +
  675 +static unsigned long create_elf_tables(target_ulong p, int argc, int envc,
  676 + struct elfhdr * exec,
  677 + unsigned long load_addr,
  678 + unsigned long load_bias,
  679 + unsigned long interp_load_addr, int ibcs,
  680 + struct image_info *info)
695 681 {
696   - target_ulong *argv, *envp;
697   - target_ulong *sp, *csp;
698   - target_ulong *u_platform;
  682 + target_ulong argv, envp;
  683 + target_ulong sp;
  684 + int size;
  685 + target_ulong u_platform;
699 686 const char *k_platform;
700   - int v;
  687 + const int n = sizeof(target_ulong);
701 688  
702   - /*
703   - * Force 16 byte _final_ alignment here for generality.
704   - */
705   - sp = (unsigned int *) (~15UL & (unsigned long) p);
706   - u_platform = NULL;
  689 + sp = p;
  690 + u_platform = 0;
707 691 k_platform = ELF_PLATFORM;
708 692 if (k_platform) {
709 693 size_t len = strlen(k_platform) + 1;
710   - sp -= (len + sizeof(target_ulong) - 1) / sizeof(target_ulong);
711   - u_platform = (target_ulong *)sp;
712   - __copy_to_user(u_platform, k_platform, len);
  694 + sp -= (len + n - 1) & ~(n - 1);
  695 + u_platform = sp;
  696 + memcpy_to_target(sp, k_platform, len);
713 697 }
714   - csp = sp;
715   - csp -= (DLINFO_ITEMS + 1) * 2;
  698 + /*
  699 + * Force 16 byte _final_ alignment here for generality.
  700 + */
  701 + sp = sp &~ (target_ulong)15;
  702 + size = (DLINFO_ITEMS + 1) * 2;
716 703 if (k_platform)
717   - csp -= 2;
  704 + size += 2;
718 705 #ifdef DLINFO_ARCH_ITEMS
719   - csp -= DLINFO_ARCH_ITEMS*2;
  706 + size += DLINFO_ARCH_ITEMS * 2;
720 707 #endif
721   - csp -= envc+1;
722   - csp -= argc+1;
723   - csp -= (!ibcs ? 3 : 1); /* argc itself */
724   - if ((unsigned long)csp & 15UL)
725   - sp -= ((unsigned long)csp & 15UL) / sizeof(*sp);
  708 + size += envc + argc + 2;
  709 + size += (!ibcs ? 3 : 1); /* argc itself */
  710 + size *= n;
  711 + if (size & 15)
  712 + sp -= 16 - (size & 15);
726 713  
727   -#define NEW_AUX_ENT(id, val) \
728   - sp -= 2; \
729   - put_user (id, sp); \
730   - put_user (val, sp + 1)
  714 +#define NEW_AUX_ENT(id, val) do { \
  715 + sp -= n; tputl(sp, val); \
  716 + sp -= n; tputl(sp, id); \
  717 + } while(0)
731 718 NEW_AUX_ENT (AT_NULL, 0);
732 719  
733 720 /* There must be exactly DLINFO_ITEMS entries here. */
... ... @@ -744,7 +731,7 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
744 731 NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
745 732 NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
746 733 if (k_platform)
747   - NEW_AUX_ENT(AT_PLATFORM, (target_ulong) u_platform);
  734 + NEW_AUX_ENT(AT_PLATFORM, u_platform);
748 735 #ifdef ARCH_DLINFO
749 736 /*
750 737 * ARCH_DLINFO must come last so platform specific code can enforce
... ... @@ -754,39 +741,32 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
754 741 #endif
755 742 #undef NEW_AUX_ENT
756 743  
757   - sp -= envc+1;
  744 + sp -= (envc + 1) * n;
758 745 envp = sp;
759   - sp -= argc+1;
  746 + sp -= (argc + 1) * n;
760 747 argv = sp;
761 748 if (!ibcs) {
762   - put_user((target_ulong)envp,--sp);
763   - put_user((target_ulong)argv,--sp);
  749 + sp -= n; tputl(sp, envp);
  750 + sp -= n; tputl(sp, argv);
764 751 }
765   - put_user(argc,--sp);
766   - info->arg_start = (unsigned int)((unsigned long)p & 0xffffffff);
  752 + sp -= n; tputl(sp, argc);
  753 + info->arg_start = p;
767 754 while (argc-->0) {
768   - put_user((target_ulong)p,argv++);
769   - do {
770   - get_user(v, p);
771   - p++;
772   - } while (v != 0);
  755 + tputl(argv, p); argv += n;
  756 + p += target_strlen(p) + 1;
773 757 }
774   - put_user(0,argv);
775   - info->arg_end = info->env_start = (unsigned int)((unsigned long)p & 0xffffffff);
  758 + tputl(argv, 0);
  759 + info->arg_end = info->env_start = p;
776 760 while (envc-->0) {
777   - put_user((target_ulong)p,envp++);
778   - do {
779   - get_user(v, p);
780   - p++;
781   - } while (v != 0);
  761 + tputl(envp, p); envp += n;
  762 + p += target_strlen(p) + 1;
782 763 }
783   - put_user(0,envp);
784   - info->env_end = (unsigned int)((unsigned long)p & 0xffffffff);
  764 + tputl(envp, 0);
  765 + info->env_end = p;
785 766 return sp;
786 767 }
787 768  
788 769  
789   -
790 770 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
791 771 int interpreter_fd,
792 772 unsigned long *interp_load_addr)
... ... @@ -1335,8 +1315,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
1335 1315 #ifdef LOW_ELF_STACK
1336 1316 info->start_stack = bprm->p = elf_stack - 4;
1337 1317 #endif
1338   - bprm->p = (unsigned long)
1339   - create_elf_tables((char *)bprm->p,
  1318 + bprm->p = create_elf_tables(bprm->p,
1340 1319 bprm->argc,
1341 1320 bprm->envc,
1342 1321 &elf_ex,
... ... @@ -1432,6 +1411,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp,
1432 1411 if(retval>=0) {
1433 1412 retval = load_elf_binary(&bprm,regs,infop);
1434 1413 }
  1414 +
1435 1415 if(retval>=0) {
1436 1416 /* success. Initialize important registers */
1437 1417 init_thread(regs, infop);
... ... @@ -1440,7 +1420,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp,
1440 1420  
1441 1421 /* Something went wrong, return the inode and free the argument pages*/
1442 1422 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1443   - free_page((void *)bprm.page[i]);
  1423 + free(bprm.page[i]);
1444 1424 }
1445 1425 return(retval);
1446 1426 }
... ...
linux-user/ioctls.h
... ... @@ -55,7 +55,7 @@
55 55 IOCTL(KDMKTONE, 0, TYPE_INT)
56 56 IOCTL(KDGKBTYPE, IOC_R, MK_PTR(TYPE_CHAR))
57 57 IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry)))
58   - IOCTL(KDGKBSENT, IOC_RW, TYPE_PTRVOID)
  58 + IOCTL(KDGKBSENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbsentry)))
59 59  
60 60 IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
61 61 IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT))
... ...
linux-user/main.c
... ... @@ -152,21 +152,25 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
152 152 int flags)
153 153 {
154 154 unsigned int e1, e2;
  155 + uint32_t *p;
155 156 e1 = (addr << 16) | (limit & 0xffff);
156 157 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
157 158 e2 |= flags;
158   - stl((uint8_t *)ptr, e1);
159   - stl((uint8_t *)ptr + 4, e2);
  159 + p = ptr;
  160 + p[0] = tswapl(e1);
  161 + p[1] = tswapl(e2);
160 162 }
161 163  
162 164 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
163 165 unsigned long addr, unsigned int sel)
164 166 {
165 167 unsigned int e1, e2;
  168 + uint32_t *p;
166 169 e1 = (addr & 0xffff) | (sel << 16);
167 170 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
168   - stl((uint8_t *)ptr, e1);
169   - stl((uint8_t *)ptr + 4, e2);
  171 + p = ptr;
  172 + p[0] = tswapl(e1);
  173 + p[1] = tswapl(e2);
170 174 }
171 175  
172 176 uint64_t gdt_table[6];
... ... @@ -343,7 +347,7 @@ void cpu_loop(CPUARMState *env)
343 347  
344 348 /* we handle the FPU emulation here, as Linux */
345 349 /* we get the opcode */
346   - opcode = ldl_raw((uint8_t *)env->regs[15]);
  350 + opcode = tget32(env->regs[15]);
347 351  
348 352 if (EmulateAll(opcode, &ts->fpa, env) == 0) {
349 353 info.si_signo = SIGILL;
... ... @@ -364,20 +368,20 @@ void cpu_loop(CPUARMState *env)
364 368 /* system call */
365 369 if (trapnr == EXCP_BKPT) {
366 370 if (env->thumb) {
367   - insn = lduw((void *)(env->regs[15]));
  371 + insn = tget16(env->regs[15]);
368 372 n = insn & 0xff;
369 373 env->regs[15] += 2;
370 374 } else {
371   - insn = ldl((void *)(env->regs[15]));
  375 + insn = tget32(env->regs[15]);
372 376 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
373 377 env->regs[15] += 4;
374 378 }
375 379 } else {
376 380 if (env->thumb) {
377   - insn = lduw((void *)(env->regs[15] - 2));
  381 + insn = tget16(env->regs[15] - 2);
378 382 n = insn & 0xff;
379 383 } else {
380   - insn = ldl((void *)(env->regs[15] - 4));
  384 + insn = tget32(env->regs[15] - 4);
381 385 n = insn & 0xffffff;
382 386 }
383 387 }
... ... @@ -475,16 +479,16 @@ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
475 479 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
476 480 {
477 481 unsigned int i;
478   - uint32_t *sp_ptr;
  482 + target_ulong sp_ptr;
479 483  
480   - sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]);
  484 + sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
481 485 #if defined(DEBUG_WIN)
482 486 printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
483 487 (int)sp_ptr, cwp1);
484 488 #endif
485 489 for(i = 0; i < 16; i++) {
486   - put_user(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
487   - sp_ptr++;
  490 + tputl(sp_ptr, env->regbase[get_reg_index(env, cwp1, 8 + i)]);
  491 + sp_ptr += sizeof(target_ulong);
488 492 }
489 493 }
490 494  
... ... @@ -500,22 +504,21 @@ static void save_window(CPUSPARCState *env)
500 504 static void restore_window(CPUSPARCState *env)
501 505 {
502 506 unsigned int new_wim, i, cwp1;
503   - uint32_t *sp_ptr, reg;
  507 + target_ulong sp_ptr;
504 508  
505 509 new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
506 510 ((1LL << NWINDOWS) - 1);
507 511  
508 512 /* restore the invalid window */
509 513 cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
510   - sp_ptr = (uint32_t *)(env->regbase[get_reg_index(env, cwp1, 6)]);
  514 + sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
511 515 #if defined(DEBUG_WIN)
512 516 printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
513 517 (int)sp_ptr, cwp1);
514 518 #endif
515 519 for(i = 0; i < 16; i++) {
516   - get_user(reg, sp_ptr);
517   - env->regbase[get_reg_index(env, cwp1, 8 + i)] = reg;
518   - sp_ptr++;
  520 + env->regbase[get_reg_index(env, cwp1, 8 + i)] = tgetl(sp_ptr);
  521 + sp_ptr += sizeof(target_ulong);
519 522 }
520 523 env->wim = new_wim;
521 524 }
... ... @@ -1304,15 +1307,9 @@ void cpu_loop(CPUMIPSState *env)
1304 1307 if (nb_args >= 5) {
1305 1308 sp_reg = env->gpr[29];
1306 1309 /* these arguments are taken from the stack */
1307   - if (get_user(arg5, (target_ulong *)(sp_reg + 16))) {
1308   - ret = -EFAULT;
1309   - goto fail;
1310   - }
  1310 + arg5 = tgetl(sp_reg + 16);
1311 1311 if (nb_args >= 6) {
1312   - if (get_user(arg6, (target_ulong *)(sp_reg + 20))) {
1313   - ret = -EFAULT;
1314   - goto fail;
1315   - }
  1312 + arg6 = tgetl(sp_reg + 20);
1316 1313 } else {
1317 1314 arg6 = 0;
1318 1315 }
... ... @@ -1347,8 +1344,7 @@ void cpu_loop(CPUMIPSState *env)
1347 1344 {
1348 1345 uint32_t insn, op;
1349 1346  
1350   - if (get_user(insn, (uint32_t *)env->PC) < 0)
1351   - goto sigill;
  1347 + insn = tget32(env->PC);
1352 1348 op = insn >> 26;
1353 1349 // printf("insn=%08x op=%02x\n", insn, op);
1354 1350 /* XXX: totally dummy FP ops just to be able to launch
... ... @@ -1531,7 +1527,7 @@ int main(int argc, char **argv)
1531 1527 fprintf(logfile, "entry 0x%08lx\n" , info->entry);
1532 1528 }
1533 1529  
1534   - target_set_brk((char *)info->brk);
  1530 + target_set_brk(info->brk);
1535 1531 syscall_init();
1536 1532 signal_init();
1537 1533  
... ... @@ -1566,7 +1562,7 @@ int main(int argc, char **argv)
1566 1562 env->eip = regs->eip;
1567 1563  
1568 1564 /* linux interrupt setup */
1569   - env->idt.base = (long)idt_table;
  1565 + env->idt.base = h2g(idt_table);
1570 1566 env->idt.limit = sizeof(idt_table) - 1;
1571 1567 set_idt(0, 0);
1572 1568 set_idt(1, 0);
... ... @@ -1591,7 +1587,7 @@ int main(int argc, char **argv)
1591 1587 set_idt(0x80, 3);
1592 1588  
1593 1589 /* linux segment setup */
1594   - env->gdt.base = (long)gdt_table;
  1590 + env->gdt.base = h2g(gdt_table);
1595 1591 env->gdt.limit = sizeof(gdt_table) - 1;
1596 1592 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1597 1593 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
... ...
linux-user/mmap.c
... ... @@ -29,10 +29,10 @@
29 29  
30 30 //#define DEBUG_MMAP
31 31  
32   -/* NOTE: all the constants are the HOST ones */
33   -int target_mprotect(unsigned long start, unsigned long len, int prot)
  32 +/* NOTE: all the constants are the HOST ones, but addresses are target. */
  33 +int target_mprotect(target_ulong start, target_ulong len, int prot)
34 34 {
35   - unsigned long end, host_start, host_end, addr;
  35 + target_ulong end, host_start, host_end, addr;
36 36 int prot1, ret;
37 37  
38 38 #ifdef DEBUG_MMAP
... ... @@ -67,7 +67,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
67 67 }
68 68 end = host_end;
69 69 }
70   - ret = mprotect((void *)host_start, qemu_host_page_size, prot1 & PAGE_BITS);
  70 + ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & PAGE_BITS);
71 71 if (ret != 0)
72 72 return ret;
73 73 host_start += qemu_host_page_size;
... ... @@ -77,7 +77,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
77 77 for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
78 78 prot1 |= page_get_flags(addr);
79 79 }
80   - ret = mprotect((void *)(host_end - qemu_host_page_size), qemu_host_page_size,
  80 + ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size,
81 81 prot1 & PAGE_BITS);
82 82 if (ret != 0)
83 83 return ret;
... ... @@ -86,7 +86,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
86 86  
87 87 /* handle the pages in the middle */
88 88 if (host_start < host_end) {
89   - ret = mprotect((void *)host_start, host_end - host_start, prot);
  89 + ret = mprotect(g2h(host_start), host_end - host_start, prot);
90 90 if (ret != 0)
91 91 return ret;
92 92 }
... ... @@ -95,28 +95,31 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
95 95 }
96 96  
97 97 /* map an incomplete host page */
98   -int mmap_frag(unsigned long host_start,
99   - unsigned long start, unsigned long end,
100   - int prot, int flags, int fd, unsigned long offset)
  98 +static int mmap_frag(target_ulong real_start,
  99 + target_ulong start, target_ulong end,
  100 + int prot, int flags, int fd, target_ulong offset)
101 101 {
102   - unsigned long host_end, ret, addr;
  102 + target_ulong real_end, ret, addr;
  103 + void *host_start;
103 104 int prot1, prot_new;
104 105  
105   - host_end = host_start + qemu_host_page_size;
  106 + real_end = real_start + qemu_host_page_size;
  107 + host_start = g2h(real_start);
106 108  
107 109 /* get the protection of the target pages outside the mapping */
108 110 prot1 = 0;
109   - for(addr = host_start; addr < host_end; addr++) {
  111 + for(addr = real_start; addr < real_end; addr++) {
110 112 if (addr < start || addr >= end)
111 113 prot1 |= page_get_flags(addr);
112 114 }
113 115  
114 116 if (prot1 == 0) {
115 117 /* no page was there, so we allocate one */
116   - ret = (long)mmap((void *)host_start, qemu_host_page_size, prot,
  118 + ret = (long)mmap(host_start, qemu_host_page_size, prot,
117 119 flags | MAP_ANONYMOUS, -1, 0);
118 120 if (ret == -1)
119 121 return ret;
  122 + prot1 = prot;
120 123 }
121 124 prot1 &= PAGE_BITS;
122 125  
... ... @@ -130,31 +133,35 @@ int mmap_frag(unsigned long host_start,
130 133  
131 134 /* adjust protection to be able to read */
132 135 if (!(prot1 & PROT_WRITE))
133   - mprotect((void *)host_start, qemu_host_page_size, prot1 | PROT_WRITE);
  136 + mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE);
134 137  
135 138 /* read the corresponding file data */
136   - pread(fd, (void *)start, end - start, offset);
  139 + pread(fd, g2h(start), end - start, offset);
137 140  
138 141 /* put final protection */
139 142 if (prot_new != (prot1 | PROT_WRITE))
140   - mprotect((void *)host_start, qemu_host_page_size, prot_new);
  143 + mprotect(host_start, qemu_host_page_size, prot_new);
141 144 } else {
142 145 /* just update the protection */
143 146 if (prot_new != prot1) {
144   - mprotect((void *)host_start, qemu_host_page_size, prot_new);
  147 + mprotect(host_start, qemu_host_page_size, prot_new);
145 148 }
146 149 }
147 150 return 0;
148 151 }
149 152  
150 153 /* NOTE: all the constants are the HOST ones */
151   -long target_mmap(unsigned long start, unsigned long len, int prot,
152   - int flags, int fd, unsigned long offset)
  154 +long target_mmap(target_ulong start, target_ulong len, int prot,
  155 + int flags, int fd, target_ulong offset)
153 156 {
154   - unsigned long ret, end, host_start, host_end, retaddr, host_offset, host_len;
  157 + target_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
  158 + long host_start;
155 159 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
156 160 defined(__ia64)
157   - static unsigned long last_start = 0x40000000;
  161 + static target_ulong last_start = 0x40000000;
  162 +#elif defined(__CYGWIN__)
  163 + /* Cygwin doesn't have a whole lot of address space. */
  164 + static target_ulong last_start = 0x18000000;
158 165 #endif
159 166  
160 167 #ifdef DEBUG_MMAP
... ... @@ -191,45 +198,49 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
191 198 len = TARGET_PAGE_ALIGN(len);
192 199 if (len == 0)
193 200 return start;
194   - host_start = start & qemu_host_page_mask;
  201 + real_start = start & qemu_host_page_mask;
195 202  
196 203 if (!(flags & MAP_FIXED)) {
197 204 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
198   - defined(__ia64)
  205 + defined(__ia64) || defined(__CYGWIN__)
199 206 /* tell the kenel to search at the same place as i386 */
200   - if (host_start == 0) {
201   - host_start = last_start;
  207 + if (real_start == 0) {
  208 + real_start = last_start;
202 209 last_start += HOST_PAGE_ALIGN(len);
203 210 }
204 211 #endif
205 212 if (qemu_host_page_size != qemu_real_host_page_size) {
206 213 /* NOTE: this code is only for debugging with '-p' option */
  214 + /* ??? Can also occur when TARGET_PAGE_SIZE > host page size. */
207 215 /* reserve a memory area */
  216 + /* ??? This needs fixing for remapping. */
  217 +abort();
208 218 host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
209   - host_start = (long)mmap((void *)host_start, host_len, PROT_NONE,
  219 + real_start = (long)mmap(g2h(real_start), host_len, PROT_NONE,
210 220 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
211   - if (host_start == -1)
212   - return host_start;
213   - host_end = host_start + host_len;
214   - start = HOST_PAGE_ALIGN(host_start);
  221 + if (real_start == -1)
  222 + return real_start;
  223 + real_end = real_start + host_len;
  224 + start = HOST_PAGE_ALIGN(real_start);
215 225 end = start + HOST_PAGE_ALIGN(len);
216   - if (start > host_start)
217   - munmap((void *)host_start, start - host_start);
218   - if (end < host_end)
219   - munmap((void *)end, host_end - end);
  226 + if (start > real_start)
  227 + munmap((void *)real_start, start - real_start);
  228 + if (end < real_end)
  229 + munmap((void *)end, real_end - end);
220 230 /* use it as a fixed mapping */
221 231 flags |= MAP_FIXED;
222 232 } else {
223 233 /* if not fixed, no need to do anything */
224 234 host_offset = offset & qemu_host_page_mask;
225 235 host_len = len + offset - host_offset;
226   - start = (long)mmap((void *)host_start, host_len,
227   - prot, flags, fd, host_offset);
228   - if (start == -1)
229   - return start;
  236 + host_start = (long)mmap(real_start ? g2h(real_start) : NULL,
  237 + host_len, prot, flags, fd, host_offset);
  238 + if (host_start == -1)
  239 + return host_start;
230 240 /* update start so that it points to the file position at 'offset' */
231 241 if (!(flags & MAP_ANONYMOUS))
232   - start += offset - host_offset;
  242 + host_start += offset - host_offset;
  243 + start = h2g(host_start);
233 244 goto the_end1;
234 245 }
235 246 }
... ... @@ -239,7 +250,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
239 250 return -1;
240 251 }
241 252 end = start + len;
242   - host_end = HOST_PAGE_ALIGN(end);
  253 + real_end = HOST_PAGE_ALIGN(end);
243 254  
244 255 /* worst case: we cannot map the file because the offset is not
245 256 aligned, so we read it */
... ... @@ -257,7 +268,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
257 268 -1, 0);
258 269 if (retaddr == -1)
259 270 return retaddr;
260   - pread(fd, (void *)start, len, offset);
  271 + pread(fd, g2h(start), len, offset);
261 272 if (!(prot & PROT_WRITE)) {
262 273 ret = target_mprotect(start, len, prot);
263 274 if (ret != 0)
... ... @@ -267,40 +278,40 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
267 278 }
268 279  
269 280 /* handle the start of the mapping */
270   - if (start > host_start) {
271   - if (host_end == host_start + qemu_host_page_size) {
  281 + if (start > real_start) {
  282 + if (real_end == real_start + qemu_host_page_size) {
272 283 /* one single host page */
273   - ret = mmap_frag(host_start, start, end,
  284 + ret = mmap_frag(real_start, start, end,
274 285 prot, flags, fd, offset);
275 286 if (ret == -1)
276 287 return ret;
277 288 goto the_end1;
278 289 }
279   - ret = mmap_frag(host_start, start, host_start + qemu_host_page_size,
  290 + ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,
280 291 prot, flags, fd, offset);
281 292 if (ret == -1)
282 293 return ret;
283   - host_start += qemu_host_page_size;
  294 + real_start += qemu_host_page_size;
284 295 }
285 296 /* handle the end of the mapping */
286   - if (end < host_end) {
287   - ret = mmap_frag(host_end - qemu_host_page_size,
288   - host_end - qemu_host_page_size, host_end,
  297 + if (end < real_end) {
  298 + ret = mmap_frag(real_end - qemu_host_page_size,
  299 + real_end - qemu_host_page_size, real_end,
289 300 prot, flags, fd,
290   - offset + host_end - qemu_host_page_size - start);
  301 + offset + real_end - qemu_host_page_size - start);
291 302 if (ret == -1)
292 303 return ret;
293   - host_end -= qemu_host_page_size;
  304 + real_end -= qemu_host_page_size;
294 305 }
295 306  
296 307 /* map the middle (easier) */
297   - if (host_start < host_end) {
  308 + if (real_start < real_end) {
298 309 unsigned long offset1;
299 310 if (flags & MAP_ANONYMOUS)
300 311 offset1 = 0;
301 312 else
302   - offset1 = offset + host_start - start;
303   - ret = (long)mmap((void *)host_start, host_end - host_start,
  313 + offset1 = offset + real_start - start;
  314 + ret = (long)mmap(g2h(real_start), real_end - real_start,
304 315 prot, flags, fd, offset1);
305 316 if (ret == -1)
306 317 return ret;
... ... @@ -316,9 +327,9 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
316 327 return start;
317 328 }
318 329  
319   -int target_munmap(unsigned long start, unsigned long len)
  330 +int target_munmap(target_ulong start, target_ulong len)
320 331 {
321   - unsigned long end, host_start, host_end, addr;
  332 + target_ulong end, real_start, real_end, addr;
322 333 int prot, ret;
323 334  
324 335 #ifdef DEBUG_MMAP
... ... @@ -330,36 +341,36 @@ int target_munmap(unsigned long start, unsigned long len)
330 341 if (len == 0)
331 342 return -EINVAL;
332 343 end = start + len;
333   - host_start = start & qemu_host_page_mask;
334   - host_end = HOST_PAGE_ALIGN(end);
  344 + real_start = start & qemu_host_page_mask;
  345 + real_end = HOST_PAGE_ALIGN(end);
335 346  
336   - if (start > host_start) {
  347 + if (start > real_start) {
337 348 /* handle host page containing start */
338 349 prot = 0;
339   - for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
  350 + for(addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) {
340 351 prot |= page_get_flags(addr);
341 352 }
342   - if (host_end == host_start + qemu_host_page_size) {
343   - for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
  353 + if (real_end == real_start + qemu_host_page_size) {
  354 + for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
344 355 prot |= page_get_flags(addr);
345 356 }
346   - end = host_end;
  357 + end = real_end;
347 358 }
348 359 if (prot != 0)
349   - host_start += qemu_host_page_size;
  360 + real_start += qemu_host_page_size;
350 361 }
351   - if (end < host_end) {
  362 + if (end < real_end) {
352 363 prot = 0;
353   - for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
  364 + for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) {
354 365 prot |= page_get_flags(addr);
355 366 }
356 367 if (prot != 0)
357   - host_end -= qemu_host_page_size;
  368 + real_end -= qemu_host_page_size;
358 369 }
359 370  
360 371 /* unmap what we can */
361   - if (host_start < host_end) {
362   - ret = munmap((void *)host_start, host_end - host_start);
  372 + if (real_start < real_end) {
  373 + ret = munmap((void *)real_start, real_end - real_start);
363 374 if (ret != 0)
364 375 return ret;
365 376 }
... ... @@ -370,25 +381,26 @@ int target_munmap(unsigned long start, unsigned long len)
370 381  
371 382 /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
372 383 blocks which have been allocated starting on a host page */
373   -long target_mremap(unsigned long old_addr, unsigned long old_size,
374   - unsigned long new_size, unsigned long flags,
375   - unsigned long new_addr)
  384 +long target_mremap(target_ulong old_addr, target_ulong old_size,
  385 + target_ulong new_size, unsigned long flags,
  386 + target_ulong new_addr)
376 387 {
377 388 int prot;
378 389  
379 390 /* XXX: use 5 args syscall */
380   - new_addr = (long)mremap((void *)old_addr, old_size, new_size, flags);
  391 + new_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags);
381 392 if (new_addr == -1)
382 393 return new_addr;
  394 + new_addr = h2g(new_addr);
383 395 prot = page_get_flags(old_addr);
384 396 page_set_flags(old_addr, old_addr + old_size, 0);
385 397 page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
386 398 return new_addr;
387 399 }
388 400  
389   -int target_msync(unsigned long start, unsigned long len, int flags)
  401 +int target_msync(target_ulong start, target_ulong len, int flags)
390 402 {
391   - unsigned long end;
  403 + target_ulong end;
392 404  
393 405 if (start & ~TARGET_PAGE_MASK)
394 406 return -EINVAL;
... ... @@ -400,6 +412,6 @@ int target_msync(unsigned long start, unsigned long len, int flags)
400 412 return 0;
401 413  
402 414 start &= qemu_host_page_mask;
403   - return msync((void *)start, end - start, flags);
  415 + return msync(g2h(start), end - start, flags);
404 416 }
405 417  
... ...
linux-user/qemu.h
... ... @@ -69,7 +69,7 @@ typedef struct TaskState {
69 69 int swi_errno;
70 70 #endif
71 71 #ifdef TARGET_I386
72   - struct target_vm86plus_struct *target_v86;
  72 + target_ulong target_v86;
73 73 struct vm86_saved_state vm86_saved_regs;
74 74 struct target_vm86plus_struct vm86plus;
75 75 uint32_t v86flags;
... ... @@ -84,8 +84,8 @@ extern TaskState *first_task_state;
84 84 int elf_exec(const char * filename, char ** argv, char ** envp,
85 85 struct target_pt_regs * regs, struct image_info *infop);
86 86  
87   -void target_set_brk(char *new_brk);
88   -long do_brk(char *new_brk);
  87 +void target_set_brk(target_ulong new_brk);
  88 +long do_brk(target_ulong new_brk);
89 89 void syscall_init(void);
90 90 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
91 91 long arg4, long arg5, long arg6);
... ... @@ -112,19 +112,18 @@ long do_rt_sigreturn(CPUState *env);
112 112 void save_v86_state(CPUX86State *env);
113 113 void handle_vm86_trap(CPUX86State *env, int trapno);
114 114 void handle_vm86_fault(CPUX86State *env);
115   -int do_vm86(CPUX86State *env, long subfunction,
116   - struct target_vm86plus_struct * target_v86);
  115 +int do_vm86(CPUX86State *env, long subfunction, target_ulong v86_addr);
117 116 #endif
118 117  
119 118 /* mmap.c */
120   -int target_mprotect(unsigned long start, unsigned long len, int prot);
121   -long target_mmap(unsigned long start, unsigned long len, int prot,
122   - int flags, int fd, unsigned long offset);
123   -int target_munmap(unsigned long start, unsigned long len);
124   -long target_mremap(unsigned long old_addr, unsigned long old_size,
125   - unsigned long new_size, unsigned long flags,
126   - unsigned long new_addr);
127   -int target_msync(unsigned long start, unsigned long len, int flags);
  119 +int target_mprotect(target_ulong start, target_ulong len, int prot);
  120 +long target_mmap(target_ulong start, target_ulong len, int prot,
  121 + int flags, int fd, target_ulong offset);
  122 +int target_munmap(target_ulong start, target_ulong len);
  123 +long target_mremap(target_ulong old_addr, target_ulong old_size,
  124 + target_ulong new_size, unsigned long flags,
  125 + target_ulong new_addr);
  126 +int target_msync(target_ulong start, target_ulong len, int flags);
128 127  
129 128 /* user access */
130 129  
... ... @@ -133,21 +132,22 @@ int target_msync(unsigned long start, unsigned long len, int flags);
133 132  
134 133 #define access_ok(type,addr,size) (1)
135 134  
  135 +/* NOTE get_user and put_user use host addresses. */
136 136 #define __put_user(x,ptr)\
137 137 ({\
138 138 int size = sizeof(*ptr);\
139 139 switch(size) {\
140 140 case 1:\
141   - stb(ptr, (typeof(*ptr))(x));\
  141 + *(uint8_t *)(ptr) = (typeof(*ptr))(x);\
142 142 break;\
143 143 case 2:\
144   - stw(ptr, (typeof(*ptr))(x));\
  144 + *(uint16_t *)(ptr) = tswap16((typeof(*ptr))(x));\
145 145 break;\
146 146 case 4:\
147   - stl(ptr, (typeof(*ptr))(x));\
  147 + *(uint32_t *)(ptr) = tswap32((typeof(*ptr))(x));\
148 148 break;\
149 149 case 8:\
150   - stq(ptr, (typeof(*ptr))(x));\
  150 + *(uint64_t *)(ptr) = tswap64((typeof(*ptr))(x));\
151 151 break;\
152 152 default:\
153 153 abort();\
... ... @@ -160,16 +160,16 @@ int target_msync(unsigned long start, unsigned long len, int flags);
160 160 int size = sizeof(*ptr);\
161 161 switch(size) {\
162 162 case 1:\
163   - x = (typeof(*ptr))ldub((void *)ptr);\
  163 + x = (typeof(*ptr))*(uint8_t *)(ptr);\
164 164 break;\
165 165 case 2:\
166   - x = (typeof(*ptr))lduw((void *)ptr);\
  166 + x = (typeof(*ptr))tswap16(*(uint16_t *)(ptr));\
167 167 break;\
168 168 case 4:\
169   - x = (typeof(*ptr))ldl((void *)ptr);\
  169 + x = (typeof(*ptr))tswap32(*(uint32_t *)(ptr));\
170 170 break;\
171 171 case 8:\
172   - x = (typeof(*ptr))ldq((void *)ptr);\
  172 + x = (typeof(*ptr))tswap64(*(uint64_t *)(ptr));\
173 173 break;\
174 174 default:\
175 175 abort();\
... ... @@ -177,26 +177,6 @@ int target_msync(unsigned long start, unsigned long len, int flags);
177 177 0;\
178 178 })
179 179  
180   -static inline unsigned long __copy_to_user(void *dst, const void *src,
181   - unsigned long size)
182   -{
183   - memcpy(dst, src, size);
184   - return 0;
185   -}
186   -
187   -static inline unsigned long __copy_from_user(void *dst, const void *src,
188   - unsigned long size)
189   -{
190   - memcpy(dst, src, size);
191   - return 0;
192   -}
193   -
194   -static inline unsigned long __clear_user(void *dst, unsigned long size)
195   -{
196   - memset(dst, 0, size);
197   - return 0;
198   -}
199   -
200 180 #define put_user(x,ptr)\
201 181 ({\
202 182 int __ret;\
... ... @@ -217,30 +197,77 @@ static inline unsigned long __clear_user(void *dst, unsigned long size)
217 197 __ret;\
218 198 })
219 199  
220   -static inline unsigned long copy_to_user(void *dst, const void *src,
221   - unsigned long size)
  200 +/* Functions for accessing guest memory. The tget and tput functions
  201 + read/write single values, byteswapping as neccessary. The lock_user
  202 + gets a pointer to a contiguous area of guest memory, but does not perform
  203 + and byteswapping. lock_user may return either a pointer to the guest
  204 + memory, or a temporary buffer. */
  205 +
  206 +/* Lock an area of guest memory into the host. If copy is true then the
  207 + host area will have the same contents as the guest. */
  208 +static inline void *lock_user(target_ulong guest_addr, long len, int copy)
222 209 {
223   - if (access_ok(VERIFY_WRITE, dst, size))
224   - return __copy_to_user(dst, src, size);
  210 +#ifdef DEBUG_REMAP
  211 + void *addr;
  212 + addr = malloc(len);
  213 + if (copy)
  214 + memcpy(addr, g2h(guest_addr), len);
225 215 else
226   - return size;
  216 + memset(addr, 0, len);
  217 + return addr;
  218 +#else
  219 + return g2h(guest_addr);
  220 +#endif
227 221 }
228 222  
229   -static inline unsigned long copy_from_user(void *dst, const void *src,
230   - unsigned long size)
  223 +/* Unlock an area of guest memory. The first LEN bytes must be flushed back
  224 + to guest memory. */
  225 +static inline void unlock_user(void *host_addr, target_ulong guest_addr,
  226 + long len)
231 227 {
232   - if (access_ok(VERIFY_READ, src, size))
233   - return __copy_from_user(dst, src, size);
234   - else
235   - return size;
  228 +#ifdef DEBUG_REMAP
  229 + if (host_addr == g2h(guest_addr))
  230 + return;
  231 + if (len > 0)
  232 + memcpy(g2h(guest_addr), host_addr, len);
  233 + free(host_addr);
  234 +#endif
236 235 }
237 236  
238   -static inline unsigned long clear_user(void *dst, unsigned long size)
  237 +/* Return the length of a string in target memory. */
  238 +static inline int target_strlen(target_ulong ptr)
239 239 {
240   - if (access_ok(VERIFY_WRITE, dst, size))
241   - return __clear_user(dst, size);
242   - else
243   - return size;
  240 + return strlen(g2h(ptr));
  241 +}
  242 +
  243 +/* Like lock_user but for null terminated strings. */
  244 +static inline void *lock_user_string(target_ulong guest_addr)
  245 +{
  246 + long len;
  247 + len = target_strlen(guest_addr) + 1;
  248 + return lock_user(guest_addr, len, 1);
244 249 }
245 250  
  251 +/* Helper macros for locking/ulocking a target struct. */
  252 +#define lock_user_struct(host_ptr, guest_addr, copy) \
  253 + host_ptr = lock_user(guest_addr, sizeof(*host_ptr), copy)
  254 +#define unlock_user_struct(host_ptr, guest_addr, copy) \
  255 + unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
  256 +
  257 +#define tget8(addr) ldub(addr)
  258 +#define tput8(addr, val) stb(addr, val)
  259 +#define tget16(addr) lduw(addr)
  260 +#define tput16(addr, val) stw(addr, val)
  261 +#define tget32(addr) ldl(addr)
  262 +#define tput32(addr, val) stl(addr, val)
  263 +#define tget64(addr) ldq(addr)
  264 +#define tput64(addr, val) stq(addr, val)
  265 +#if TARGET_LONG_BITS == 64
  266 +#define tgetl(addr) ldq(addr)
  267 +#define tputl(addr, val) stq(addr, val)
  268 +#else
  269 +#define tgetl(addr) ldl(addr)
  270 +#define tputl(addr, val) stl(addr, val)
  271 +#endif
  272 +
246 273 #endif /* QEMU_H */
... ...
linux-user/signal.c
... ... @@ -135,7 +135,7 @@ void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
135 135  
136 136 host_to_target_sigset_internal(&d1, s);
137 137 for(i = 0;i < TARGET_NSIG_WORDS; i++)
138   - __put_user(d1.sig[i], &d->sig[i]);
  138 + d->sig[i] = tswapl(d1.sig[i]);
139 139 }
140 140  
141 141 void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
... ... @@ -168,7 +168,7 @@ void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
168 168 int i;
169 169  
170 170 for(i = 0;i < TARGET_NSIG_WORDS; i++)
171   - __get_user(s1.sig[i], &s->sig[i]);
  171 + s1.sig[i] = tswapl(s->sig[i]);
172 172 target_to_host_sigset_internal(d, &s1);
173 173 }
174 174  
... ... @@ -647,7 +647,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
647 647 ka->sa.sa_restorer) {
648 648 esp = (unsigned long) ka->sa.sa_restorer;
649 649 }
650   - return (void *)((esp - frame_size) & -8ul);
  650 + return g2h((esp - frame_size) & -8ul);
651 651 }
652 652  
653 653 static void setup_frame(int sig, struct emulated_sigaction *ka,
... ... @@ -694,7 +694,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
694 694 goto give_sigsegv;
695 695  
696 696 /* Set up registers for signal handler */
697   - env->regs[R_ESP] = (unsigned long) frame;
  697 + env->regs[R_ESP] = h2g(frame);
698 698 env->eip = (unsigned long) ka->sa._sa_handler;
699 699  
700 700 cpu_x86_load_seg(env, R_DS, __USER_DS);
... ... @@ -835,7 +835,7 @@ badframe:
835 835  
836 836 long do_sigreturn(CPUX86State *env)
837 837 {
838   - struct sigframe *frame = (struct sigframe *)(env->regs[R_ESP] - 8);
  838 + struct sigframe *frame = (struct sigframe *)g2h(env->regs[R_ESP] - 8);
839 839 target_sigset_t target_set;
840 840 sigset_t set;
841 841 int eax, i;
... ... @@ -866,7 +866,7 @@ badframe:
866 866  
867 867 long do_rt_sigreturn(CPUX86State *env)
868 868 {
869   - struct rt_sigframe *frame = (struct rt_sigframe *)(env->regs[R_ESP] - 4);
  869 + struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);
870 870 sigset_t set;
871 871 // stack_t st;
872 872 int eax;
... ... @@ -1029,7 +1029,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1029 1029 /*
1030 1030 * ATPCS B01 mandates 8-byte alignment
1031 1031 */
1032   - return (void *)((sp - framesize) & ~7);
  1032 + return g2h((sp - framesize) & ~7);
1033 1033 }
1034 1034  
1035 1035 static int
... ... @@ -1084,7 +1084,7 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1084 1084 }
1085 1085  
1086 1086 env->regs[0] = usig;
1087   - env->regs[13] = (target_ulong)frame;
  1087 + env->regs[13] = h2g(frame);
1088 1088 env->regs[14] = retcode;
1089 1089 env->regs[15] = handler & (thumb ? ~1 : ~3);
1090 1090  
... ... @@ -1130,7 +1130,7 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1130 1130 err |= copy_siginfo_to_user(&frame->info, info);
1131 1131  
1132 1132 /* Clear all the bits of the ucontext we don't use. */
1133   - err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
  1133 + memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));
1134 1134  
1135 1135 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
1136 1136 env, set->sig[0]);
... ... @@ -1202,7 +1202,7 @@ long do_sigreturn(CPUState *env)
1202 1202 if (env->regs[13] & 7)
1203 1203 goto badframe;
1204 1204  
1205   - frame = (struct sigframe *)env->regs[13];
  1205 + frame = (struct sigframe *)g2h(env->regs[13]);
1206 1206  
1207 1207 #if 0
1208 1208 if (verify_area(VERIFY_READ, frame, sizeof (*frame)))
... ... @@ -1378,7 +1378,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
1378 1378 sp = current->sas_ss_sp + current->sas_ss_size;
1379 1379 }
1380 1380 #endif
1381   - return (void *)(sp - framesize);
  1381 + return g2h(sp - framesize);
1382 1382 }
1383 1383  
1384 1384 static int
... ... @@ -1461,10 +1461,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1461 1461 goto sigsegv;
1462 1462  
1463 1463 /* 3. signal handler back-trampoline and parameters */
1464   - env->regwptr[UREG_FP] = (target_ulong) sf;
  1464 + env->regwptr[UREG_FP] = h2g(sf);
1465 1465 env->regwptr[UREG_I0] = sig;
1466   - env->regwptr[UREG_I1] = (target_ulong) &sf->info;
1467   - env->regwptr[UREG_I2] = (target_ulong) &sf->info;
  1466 + env->regwptr[UREG_I1] = h2g(&sf->info);
  1467 + env->regwptr[UREG_I2] = h2g(&sf->info);
1468 1468  
1469 1469 /* 4. signal handler */
1470 1470 env->pc = (unsigned long) ka->sa._sa_handler;
... ... @@ -1473,7 +1473,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1473 1473 if (ka->sa.sa_restorer)
1474 1474 env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
1475 1475 else {
1476   - env->regwptr[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
  1476 + env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2);
1477 1477  
1478 1478 /* mov __NR_sigreturn, %g1 */
1479 1479 err |= __put_user(0x821020d8, &sf->insns[0]);
... ... @@ -1548,7 +1548,7 @@ long do_sigreturn(CPUState *env)
1548 1548 target_ulong fpu_save;
1549 1549 int err, i;
1550 1550  
1551   - sf = (struct target_signal_frame *) env->regwptr[UREG_FP];
  1551 + sf = (struct target_signal_frame *)g2h(env->regwptr[UREG_FP]);
1552 1552 #if 0
1553 1553 fprintf(stderr, "sigreturn\n");
1554 1554 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
... ...
linux-user/syscall.c
... ... @@ -252,44 +252,43 @@ static inline int is_error(long ret)
252 252 return (unsigned long)ret >= (unsigned long)(-4096);
253 253 }
254 254  
255   -static char *target_brk;
256   -static char *target_original_brk;
  255 +static target_ulong target_brk;
  256 +static target_ulong target_original_brk;
257 257  
258   -void target_set_brk(char *new_brk)
  258 +void target_set_brk(target_ulong new_brk)
259 259 {
260   - target_brk = new_brk;
261   - target_original_brk = new_brk;
  260 + target_original_brk = target_brk = new_brk;
262 261 }
263 262  
264   -long do_brk(char *new_brk)
  263 +long do_brk(target_ulong new_brk)
265 264 {
266   - char *brk_page;
  265 + target_ulong brk_page;
267 266 long mapped_addr;
268 267 int new_alloc_size;
269 268  
270 269 if (!new_brk)
271   - return (long)target_brk;
  270 + return target_brk;
272 271 if (new_brk < target_original_brk)
273 272 return -ENOMEM;
274 273  
275   - brk_page = (char *)HOST_PAGE_ALIGN((unsigned long)target_brk);
  274 + brk_page = HOST_PAGE_ALIGN(target_brk);
276 275  
277 276 /* If the new brk is less than this, set it and we're done... */
278 277 if (new_brk < brk_page) {
279 278 target_brk = new_brk;
280   - return (long)target_brk;
  279 + return target_brk;
281 280 }
282 281  
283 282 /* We need to allocate more memory after the brk... */
284 283 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
285   - mapped_addr = get_errno(target_mmap((unsigned long)brk_page, new_alloc_size,
  284 + mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
286 285 PROT_READ|PROT_WRITE,
287 286 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
288 287 if (is_error(mapped_addr)) {
289 288 return mapped_addr;
290 289 } else {
291 290 target_brk = new_brk;
292   - return (long)target_brk;
  291 + return target_brk;
293 292 }
294 293 }
295 294  
... ... @@ -354,9 +353,12 @@ static inline long host_to_target_clock_t(long ticks)
354 353 #endif
355 354 }
356 355  
357   -static inline void host_to_target_rusage(struct target_rusage *target_rusage,
  356 +static inline void host_to_target_rusage(target_ulong target_addr,
358 357 const struct rusage *rusage)
359 358 {
  359 + struct target_rusage *target_rusage;
  360 +
  361 + lock_user_struct(target_rusage, target_addr, 0);
360 362 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
361 363 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
362 364 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec);
... ... @@ -375,35 +377,64 @@ static inline void host_to_target_rusage(struct target_rusage *target_rusage,
375 377 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
376 378 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
377 379 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw);
  380 + unlock_user_struct(target_rusage, target_addr, 1);
378 381 }
379 382  
380   -static inline void target_to_host_timeval(struct timeval *tv,
381   - const struct target_timeval *target_tv)
  383 +static inline void target_to_host_timeval(struct timeval *tv,
  384 + target_ulong target_addr)
382 385 {
  386 + struct target_timeval *target_tv;
  387 +
  388 + lock_user_struct(target_tv, target_addr, 1);
383 389 tv->tv_sec = tswapl(target_tv->tv_sec);
384 390 tv->tv_usec = tswapl(target_tv->tv_usec);
  391 + unlock_user_struct(target_tv, target_addr, 0);
385 392 }
386 393  
387   -static inline void host_to_target_timeval(struct target_timeval *target_tv,
  394 +static inline void host_to_target_timeval(target_ulong target_addr,
388 395 const struct timeval *tv)
389 396 {
  397 + struct target_timeval *target_tv;
  398 +
  399 + lock_user_struct(target_tv, target_addr, 0);
390 400 target_tv->tv_sec = tswapl(tv->tv_sec);
391 401 target_tv->tv_usec = tswapl(tv->tv_usec);
  402 + unlock_user_struct(target_tv, target_addr, 1);
392 403 }
393 404  
394 405  
395 406 static long do_select(long n,
396   - target_long *target_rfds, target_long *target_wfds,
397   - target_long *target_efds, struct target_timeval *target_tv)
  407 + target_ulong rfd_p, target_ulong wfd_p,
  408 + target_ulong efd_p, target_ulong target_tv)
398 409 {
399 410 fd_set rfds, wfds, efds;
400 411 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
  412 + target_long *target_rfds, *target_wfds, *target_efds;
401 413 struct timeval tv, *tv_ptr;
402 414 long ret;
  415 + int ok;
403 416  
404   - rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
405   - wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
406   - efds_ptr = target_to_host_fds(&efds, target_efds, n);
  417 + if (rfd_p) {
  418 + target_rfds = lock_user(rfd_p, sizeof(target_long) * n, 1);
  419 + rfds_ptr = target_to_host_fds(&rfds, target_rfds, n);
  420 + } else {
  421 + target_rfds = NULL;
  422 + rfds_ptr = NULL;
  423 + }
  424 + if (wfd_p) {
  425 + target_wfds = lock_user(wfd_p, sizeof(target_long) * n, 1);
  426 + wfds_ptr = target_to_host_fds(&wfds, target_wfds, n);
  427 + } else {
  428 + target_wfds = NULL;
  429 + wfds_ptr = NULL;
  430 + }
  431 + if (efd_p) {
  432 + target_efds = lock_user(efd_p, sizeof(target_long) * n, 1);
  433 + efds_ptr = target_to_host_fds(&efds, target_efds, n);
  434 + } else {
  435 + target_efds = NULL;
  436 + efds_ptr = NULL;
  437 + }
407 438  
408 439 if (target_tv) {
409 440 target_to_host_timeval(&tv, target_tv);
... ... @@ -412,7 +443,9 @@ static long do_select(long n,
412 443 tv_ptr = NULL;
413 444 }
414 445 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
415   - if (!is_error(ret)) {
  446 + ok = !is_error(ret);
  447 +
  448 + if (ok) {
416 449 host_to_target_fds(target_rfds, rfds_ptr, n);
417 450 host_to_target_fds(target_wfds, wfds_ptr, n);
418 451 host_to_target_fds(target_efds, efds_ptr, n);
... ... @@ -421,25 +454,41 @@ static long do_select(long n,
421 454 host_to_target_timeval(target_tv, &tv);
422 455 }
423 456 }
  457 + if (target_rfds)
  458 + unlock_user(target_rfds, rfd_p, ok ? sizeof(target_long) * n : 0);
  459 + if (target_wfds)
  460 + unlock_user(target_wfds, wfd_p, ok ? sizeof(target_long) * n : 0);
  461 + if (target_efds)
  462 + unlock_user(target_efds, efd_p, ok ? sizeof(target_long) * n : 0);
  463 +
424 464 return ret;
425 465 }
426 466  
427 467 static inline void target_to_host_sockaddr(struct sockaddr *addr,
428   - struct target_sockaddr *target_addr,
  468 + target_ulong target_addr,
429 469 socklen_t len)
430 470 {
431   - memcpy(addr, target_addr, len);
432   - addr->sa_family = tswap16(target_addr->sa_family);
  471 + struct target_sockaddr *target_saddr;
  472 +
  473 + target_saddr = lock_user(target_addr, len, 1);
  474 + memcpy(addr, target_saddr, len);
  475 + addr->sa_family = tswap16(target_saddr->sa_family);
  476 + unlock_user(target_saddr, target_addr, 0);
433 477 }
434 478  
435   -static inline void host_to_target_sockaddr(struct target_sockaddr *target_addr,
  479 +static inline void host_to_target_sockaddr(target_ulong target_addr,
436 480 struct sockaddr *addr,
437 481 socklen_t len)
438 482 {
439   - memcpy(target_addr, addr, len);
440   - target_addr->sa_family = tswap16(addr->sa_family);
  483 + struct target_sockaddr *target_saddr;
  484 +
  485 + target_saddr = lock_user(target_addr, len, 0);
  486 + memcpy(target_saddr, addr, len);
  487 + target_saddr->sa_family = tswap16(addr->sa_family);
  488 + unlock_user(target_saddr, target_addr, len);
441 489 }
442 490  
  491 +/* ??? Should this also swap msgh->name? */
443 492 static inline void target_to_host_cmsg(struct msghdr *msgh,
444 493 struct target_msghdr *target_msgh)
445 494 {
... ... @@ -484,6 +533,7 @@ static inline void target_to_host_cmsg(struct msghdr *msgh,
484 533 msgh->msg_controllen = space;
485 534 }
486 535  
  536 +/* ??? Should this also swap msgh->name? */
487 537 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
488 538 struct msghdr *msgh)
489 539 {
... ... @@ -528,7 +578,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
528 578 }
529 579  
530 580 static long do_setsockopt(int sockfd, int level, int optname,
531   - void *optval, socklen_t optlen)
  581 + target_ulong optval, socklen_t optlen)
532 582 {
533 583 int val, ret;
534 584  
... ... @@ -538,8 +588,7 @@ static long do_setsockopt(int sockfd, int level, int optname,
538 588 if (optlen < sizeof(uint32_t))
539 589 return -EINVAL;
540 590  
541   - if (get_user(val, (uint32_t *)optval))
542   - return -EFAULT;
  591 + val = tget32(optval);
543 592 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
544 593 break;
545 594 case SOL_IP:
... ... @@ -561,11 +610,9 @@ static long do_setsockopt(int sockfd, int level, int optname,
561 610 case IP_MULTICAST_LOOP:
562 611 val = 0;
563 612 if (optlen >= sizeof(uint32_t)) {
564   - if (get_user(val, (uint32_t *)optval))
565   - return -EFAULT;
  613 + val = tget32(optval);
566 614 } else if (optlen >= 1) {
567   - if (get_user(val, (uint8_t *)optval))
568   - return -EFAULT;
  615 + val = tget8(optval);
569 616 }
570 617 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
571 618 break;
... ... @@ -598,8 +645,8 @@ static long do_setsockopt(int sockfd, int level, int optname,
598 645 case SO_SNDTIMEO:
599 646 if (optlen < sizeof(uint32_t))
600 647 return -EINVAL;
601   - if (get_user(val, (uint32_t *)optval))
602   - return -EFAULT;
  648 +
  649 + val = tget32(optval);
603 650 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
604 651 break;
605 652 default:
... ... @@ -615,7 +662,7 @@ static long do_setsockopt(int sockfd, int level, int optname,
615 662 }
616 663  
617 664 static long do_getsockopt(int sockfd, int level, int optname,
618   - void *optval, socklen_t *optlen)
  665 + target_ulong optval, target_ulong optlen)
619 666 {
620 667 int len, lv, val, ret;
621 668  
... ... @@ -636,8 +683,7 @@ static long do_getsockopt(int sockfd, int level, int optname,
636 683 case SOL_TCP:
637 684 /* TCP options all take an 'int' value. */
638 685 int_case:
639   - if (get_user(len, optlen))
640   - return -EFAULT;
  686 + len = tget32(optlen);
641 687 if (len < 0)
642 688 return -EINVAL;
643 689 lv = sizeof(int);
... ... @@ -647,10 +693,11 @@ static long do_getsockopt(int sockfd, int level, int optname,
647 693 val = tswap32(val);
648 694 if (len > lv)
649 695 len = lv;
650   - if (copy_to_user(optval, &val, len))
651   - return -EFAULT;
652   - if (put_user(len, optlen))
653   - return -EFAULT;
  696 + if (len == 4)
  697 + tput32(optval, val);
  698 + else
  699 + tput8(optval, val);
  700 + tput32(optlen, len);
654 701 break;
655 702 case SOL_IP:
656 703 switch(optname) {
... ... @@ -669,8 +716,7 @@ static long do_getsockopt(int sockfd, int level, int optname,
669 716 #endif
670 717 case IP_MULTICAST_TTL:
671 718 case IP_MULTICAST_LOOP:
672   - if (get_user(len, optlen))
673   - return -EFAULT;
  719 + len = tget32(optlen);
674 720 if (len < 0)
675 721 return -EINVAL;
676 722 lv = sizeof(int);
... ... @@ -678,20 +724,14 @@ static long do_getsockopt(int sockfd, int level, int optname,
678 724 if (ret < 0)
679 725 return ret;
680 726 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
681   - unsigned char ucval = val;
682 727 len = 1;
683   - if (put_user(len, optlen))
684   - return -EFAULT;
685   - if (copy_to_user(optval,&ucval,1))
686   - return -EFAULT;
  728 + tput32(optlen, len);
  729 + tput8(optval, val);
687 730 } else {
688   - val = tswap32(val);
689 731 if (len > sizeof(int))
690 732 len = sizeof(int);
691   - if (put_user(len, optlen))
692   - return -EFAULT;
693   - if (copy_to_user(optval, &val, len))
694   - return -EFAULT;
  733 + tput32(optlen, len);
  734 + tput32(optval, val);
695 735 }
696 736 break;
697 737 default:
... ... @@ -708,25 +748,57 @@ static long do_getsockopt(int sockfd, int level, int optname,
708 748 return ret;
709 749 }
710 750  
711   -static long do_socketcall(int num, int32_t *vptr)
  751 +static void lock_iovec(struct iovec *vec, target_ulong target_addr,
  752 + int count, int copy)
  753 +{
  754 + struct target_iovec *target_vec;
  755 + target_ulong base;
  756 + int i;
  757 +
  758 + target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
  759 + for(i = 0;i < count; i++) {
  760 + base = tswapl(target_vec[i].iov_base);
  761 + vec[i].iov_len = tswapl(target_vec[i].iov_len);
  762 + vec[i].iov_base = lock_user(base, vec[i].iov_len, copy);
  763 + }
  764 + unlock_user (target_vec, target_addr, 0);
  765 +}
  766 +
  767 +static void unlock_iovec(struct iovec *vec, target_ulong target_addr,
  768 + int count, int copy)
  769 +{
  770 + struct target_iovec *target_vec;
  771 + target_ulong base;
  772 + int i;
  773 +
  774 + target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1);
  775 + for(i = 0;i < count; i++) {
  776 + base = tswapl(target_vec[i].iov_base);
  777 + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
  778 + }
  779 + unlock_user (target_vec, target_addr, 0);
  780 +}
  781 +
  782 +static long do_socketcall(int num, target_ulong vptr)
712 783 {
713 784 long ret;
  785 + const int n = sizeof(target_ulong);
714 786  
715 787 switch(num) {
716 788 case SOCKOP_socket:
717 789 {
718   - int domain = tswap32(vptr[0]);
719   - int type = tswap32(vptr[1]);
720   - int protocol = tswap32(vptr[2]);
  790 + int domain = tgetl(vptr);
  791 + int type = tgetl(vptr + n);
  792 + int protocol = tgetl(vptr + 2 * n);
721 793  
722 794 ret = get_errno(socket(domain, type, protocol));
723 795 }
724 796 break;
725 797 case SOCKOP_bind:
726 798 {
727   - int sockfd = tswap32(vptr[0]);
728   - void *target_addr = (void *)tswap32(vptr[1]);
729   - socklen_t addrlen = tswap32(vptr[2]);
  799 + int sockfd = tgetl(vptr);
  800 + target_ulong target_addr = tgetl(vptr + n);
  801 + socklen_t addrlen = tgetl(vptr + 2 * n);
730 802 void *addr = alloca(addrlen);
731 803  
732 804 target_to_host_sockaddr(addr, target_addr, addrlen);
... ... @@ -735,9 +807,9 @@ static long do_socketcall(int num, int32_t *vptr)
735 807 break;
736 808 case SOCKOP_connect:
737 809 {
738   - int sockfd = tswap32(vptr[0]);
739   - void *target_addr = (void *)tswap32(vptr[1]);
740   - socklen_t addrlen = tswap32(vptr[2]);
  810 + int sockfd = tgetl(vptr);
  811 + target_ulong target_addr = tgetl(vptr + n);
  812 + socklen_t addrlen = tgetl(vptr + 2 * n);
741 813 void *addr = alloca(addrlen);
742 814  
743 815 target_to_host_sockaddr(addr, target_addr, addrlen);
... ... @@ -746,128 +818,142 @@ static long do_socketcall(int num, int32_t *vptr)
746 818 break;
747 819 case SOCKOP_listen:
748 820 {
749   - int sockfd = tswap32(vptr[0]);
750   - int backlog = tswap32(vptr[1]);
  821 + int sockfd = tgetl(vptr);
  822 + int backlog = tgetl(vptr + n);
751 823  
752 824 ret = get_errno(listen(sockfd, backlog));
753 825 }
754 826 break;
755 827 case SOCKOP_accept:
756 828 {
757   - int sockfd = tswap32(vptr[0]);
758   - void *target_addr = (void *)tswap32(vptr[1]);
759   - uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
760   - socklen_t addrlen = tswap32(*target_addrlen);
  829 + int sockfd = tgetl(vptr);
  830 + target_ulong target_addr = tgetl(vptr + n);
  831 + target_ulong target_addrlen = tgetl(vptr + 2 * n);
  832 + socklen_t addrlen = tget32(target_addrlen);
761 833 void *addr = alloca(addrlen);
762 834  
763 835 ret = get_errno(accept(sockfd, addr, &addrlen));
764 836 if (!is_error(ret)) {
765 837 host_to_target_sockaddr(target_addr, addr, addrlen);
766   - *target_addrlen = tswap32(addrlen);
  838 + tput32(target_addrlen, addrlen);
767 839 }
768 840 }
769 841 break;
770 842 case SOCKOP_getsockname:
771 843 {
772   - int sockfd = tswap32(vptr[0]);
773   - void *target_addr = (void *)tswap32(vptr[1]);
774   - uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
775   - socklen_t addrlen = tswap32(*target_addrlen);
  844 + int sockfd = tgetl(vptr);
  845 + target_ulong target_addr = tgetl(vptr + n);
  846 + target_ulong target_addrlen = tgetl(vptr + 2 * n);
  847 + socklen_t addrlen = tget32(target_addrlen);
776 848 void *addr = alloca(addrlen);
777 849  
778 850 ret = get_errno(getsockname(sockfd, addr, &addrlen));
779 851 if (!is_error(ret)) {
780 852 host_to_target_sockaddr(target_addr, addr, addrlen);
781   - *target_addrlen = tswap32(addrlen);
  853 + tput32(target_addrlen, addrlen);
782 854 }
783 855 }
784 856 break;
785 857 case SOCKOP_getpeername:
786 858 {
787   - int sockfd = tswap32(vptr[0]);
788   - void *target_addr = (void *)tswap32(vptr[1]);
789   - uint32_t *target_addrlen = (void *)tswap32(vptr[2]);
790   - socklen_t addrlen = tswap32(*target_addrlen);
  859 + int sockfd = tgetl(vptr);
  860 + target_ulong target_addr = tgetl(vptr + n);
  861 + target_ulong target_addrlen = tgetl(vptr + 2 * n);
  862 + socklen_t addrlen = tget32(target_addrlen);
791 863 void *addr = alloca(addrlen);
792 864  
793 865 ret = get_errno(getpeername(sockfd, addr, &addrlen));
794 866 if (!is_error(ret)) {
795 867 host_to_target_sockaddr(target_addr, addr, addrlen);
796   - *target_addrlen = tswap32(addrlen);
  868 + tput32(target_addrlen, addrlen);
797 869 }
798 870 }
799 871 break;
800 872 case SOCKOP_socketpair:
801 873 {
802   - int domain = tswap32(vptr[0]);
803   - int type = tswap32(vptr[1]);
804   - int protocol = tswap32(vptr[2]);
805   - int32_t *target_tab = (void *)tswap32(vptr[3]);
  874 + int domain = tgetl(vptr);
  875 + int type = tgetl(vptr + n);
  876 + int protocol = tgetl(vptr + 2 * n);
  877 + target_ulong target_tab = tgetl(vptr + 3 * n);
806 878 int tab[2];
807 879  
808 880 ret = get_errno(socketpair(domain, type, protocol, tab));
809 881 if (!is_error(ret)) {
810   - target_tab[0] = tswap32(tab[0]);
811   - target_tab[1] = tswap32(tab[1]);
  882 + tput32(target_tab, tab[0]);
  883 + tput32(target_tab + 4, tab[1]);
812 884 }
813 885 }
814 886 break;
815 887 case SOCKOP_send:
816 888 {
817   - int sockfd = tswap32(vptr[0]);
818   - void *msg = (void *)tswap32(vptr[1]);
819   - size_t len = tswap32(vptr[2]);
820   - int flags = tswap32(vptr[3]);
  889 + int sockfd = tgetl(vptr);
  890 + target_ulong msg = tgetl(vptr + n);
  891 + size_t len = tgetl(vptr + 2 * n);
  892 + int flags = tgetl(vptr + 3 * n);
  893 + void *host_msg;
821 894  
822   - ret = get_errno(send(sockfd, msg, len, flags));
  895 + host_msg = lock_user(msg, len, 1);
  896 + ret = get_errno(send(sockfd, host_msg, len, flags));
  897 + unlock_user(host_msg, msg, 0);
823 898 }
824 899 break;
825 900 case SOCKOP_recv:
826 901 {
827   - int sockfd = tswap32(vptr[0]);
828   - void *msg = (void *)tswap32(vptr[1]);
829   - size_t len = tswap32(vptr[2]);
830   - int flags = tswap32(vptr[3]);
  902 + int sockfd = tgetl(vptr);
  903 + target_ulong msg = tgetl(vptr + n);
  904 + size_t len = tgetl(vptr + 2 * n);
  905 + int flags = tgetl(vptr + 3 * n);
  906 + void *host_msg;
831 907  
832   - ret = get_errno(recv(sockfd, msg, len, flags));
  908 + host_msg = lock_user(msg, len, 0);
  909 + ret = get_errno(recv(sockfd, host_msg, len, flags));
  910 + unlock_user(host_msg, msg, ret);
833 911 }
834 912 break;
835 913 case SOCKOP_sendto:
836 914 {
837   - int sockfd = tswap32(vptr[0]);
838   - void *msg = (void *)tswap32(vptr[1]);
839   - size_t len = tswap32(vptr[2]);
840   - int flags = tswap32(vptr[3]);
841   - void *target_addr = (void *)tswap32(vptr[4]);
842   - socklen_t addrlen = tswap32(vptr[5]);
  915 + int sockfd = tgetl(vptr);
  916 + target_ulong msg = tgetl(vptr + n);
  917 + size_t len = tgetl(vptr + 2 * n);
  918 + int flags = tgetl(vptr + 3 * n);
  919 + target_ulong target_addr = tgetl(vptr + 4 * n);
  920 + socklen_t addrlen = tgetl(vptr + 5 * n);
843 921 void *addr = alloca(addrlen);
  922 + void *host_msg;
844 923  
  924 + host_msg = lock_user(msg, len, 1);
845 925 target_to_host_sockaddr(addr, target_addr, addrlen);
846   - ret = get_errno(sendto(sockfd, msg, len, flags, addr, addrlen));
  926 + ret = get_errno(sendto(sockfd, host_msg, len, flags, addr, addrlen));
  927 + unlock_user(host_msg, msg, 0);
847 928 }
848 929 break;
849 930 case SOCKOP_recvfrom:
850 931 {
851   - int sockfd = tswap32(vptr[0]);
852   - void *msg = (void *)tswap32(vptr[1]);
853   - size_t len = tswap32(vptr[2]);
854   - int flags = tswap32(vptr[3]);
855   - void *target_addr = (void *)tswap32(vptr[4]);
856   - uint32_t *target_addrlen = (void *)tswap32(vptr[5]);
857   - socklen_t addrlen = tswap32(*target_addrlen);
  932 + int sockfd = tgetl(vptr);
  933 + target_ulong msg = tgetl(vptr + n);
  934 + size_t len = tgetl(vptr + 2 * n);
  935 + int flags = tgetl(vptr + 3 * n);
  936 + target_ulong target_addr = tgetl(vptr + 4 * n);
  937 + target_ulong target_addrlen = tgetl(vptr + 5 * n);
  938 + socklen_t addrlen = tget32(target_addrlen);
858 939 void *addr = alloca(addrlen);
  940 + void *host_msg;
859 941  
860   - ret = get_errno(recvfrom(sockfd, msg, len, flags, addr, &addrlen));
  942 + host_msg = lock_user(msg, len, 0);
  943 + ret = get_errno(recvfrom(sockfd, host_msg, len, flags, addr, &addrlen));
861 944 if (!is_error(ret)) {
862 945 host_to_target_sockaddr(target_addr, addr, addrlen);
863   - *target_addrlen = tswap32(addrlen);
  946 + tput32(target_addrlen, addrlen);
  947 + unlock_user(host_msg, msg, len);
  948 + } else {
  949 + unlock_user(host_msg, msg, 0);
864 950 }
865 951 }
866 952 break;
867 953 case SOCKOP_shutdown:
868 954 {
869   - int sockfd = tswap32(vptr[0]);
870   - int how = tswap32(vptr[1]);
  955 + int sockfd = tgetl(vptr);
  956 + int how = tgetl(vptr + n);
871 957  
872 958 ret = get_errno(shutdown(sockfd, how));
873 959 }
... ... @@ -876,32 +962,39 @@ static long do_socketcall(int num, int32_t *vptr)
876 962 case SOCKOP_recvmsg:
877 963 {
878 964 int fd;
  965 + target_ulong target_msg;
879 966 struct target_msghdr *msgp;
880 967 struct msghdr msg;
881   - int flags, count, i;
  968 + int flags, count;
882 969 struct iovec *vec;
883   - struct target_iovec *target_vec;
884   -
885   - msgp = (void *)tswap32(vptr[1]);
886   - msg.msg_name = (void *)tswapl(msgp->msg_name);
887   - msg.msg_namelen = tswapl(msgp->msg_namelen);
  970 + target_ulong target_vec;
  971 + int send = (num == SOCKOP_sendmsg);
  972 +
  973 + target_msg = tgetl(vptr + n);
  974 + lock_user_struct(msgp, target_msg, 1);
  975 + if (msgp->msg_name) {
  976 + msg.msg_namelen = tswap32(msgp->msg_namelen);
  977 + msg.msg_name = alloca(msg.msg_namelen);
  978 + target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
  979 + msg.msg_namelen);
  980 + } else {
  981 + msg.msg_name = NULL;
  982 + msg.msg_namelen = 0;
  983 + }
888 984 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
889 985 msg.msg_control = alloca(msg.msg_controllen);
890 986 msg.msg_flags = tswap32(msgp->msg_flags);
891 987  
892 988 count = tswapl(msgp->msg_iovlen);
893 989 vec = alloca(count * sizeof(struct iovec));
894   - target_vec = (void *)tswapl(msgp->msg_iov);
895   - for(i = 0;i < count; i++) {
896   - vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
897   - vec[i].iov_len = tswapl(target_vec[i].iov_len);
898   - }
  990 + target_vec = tswapl(msgp->msg_iov);
  991 + lock_iovec(vec, target_vec, count, send);
899 992 msg.msg_iovlen = count;
900 993 msg.msg_iov = vec;
901 994  
902   - fd = tswap32(vptr[0]);
903   - flags = tswap32(vptr[2]);
904   - if (num == SOCKOP_sendmsg) {
  995 + fd = tgetl(vptr);
  996 + flags = tgetl(vptr + 2 * n);
  997 + if (send) {
905 998 target_to_host_cmsg(&msg, msgp);
906 999 ret = get_errno(sendmsg(fd, &msg, flags));
907 1000 } else {
... ... @@ -909,26 +1002,27 @@ static long do_socketcall(int num, int32_t *vptr)
909 1002 if (!is_error(ret))
910 1003 host_to_target_cmsg(msgp, &msg);
911 1004 }
  1005 + unlock_iovec(vec, target_vec, count, !send);
912 1006 }
913 1007 break;
914 1008 case SOCKOP_setsockopt:
915 1009 {
916   - int sockfd = tswap32(vptr[0]);
917   - int level = tswap32(vptr[1]);
918   - int optname = tswap32(vptr[2]);
919   - void *optval = (void *)tswap32(vptr[3]);
920   - socklen_t optlen = tswap32(vptr[4]);
  1010 + int sockfd = tgetl(vptr);
  1011 + int level = tgetl(vptr + n);
  1012 + int optname = tgetl(vptr + 2 * n);
  1013 + target_ulong optval = tgetl(vptr + 3 * n);
  1014 + socklen_t optlen = tgetl(vptr + 4 * n);
921 1015  
922 1016 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
923 1017 }
924 1018 break;
925 1019 case SOCKOP_getsockopt:
926 1020 {
927   - int sockfd = tswap32(vptr[0]);
928   - int level = tswap32(vptr[1]);
929   - int optname = tswap32(vptr[2]);
930   - void *optval = (void *)tswap32(vptr[3]);
931   - uint32_t *poptlen = (void *)tswap32(vptr[4]);
  1021 + int sockfd = tgetl(vptr);
  1022 + int level = tgetl(vptr + n);
  1023 + int optname = tgetl(vptr + 2 * n);
  1024 + target_ulong optval = tgetl(vptr + 3 * n);
  1025 + target_ulong poptlen = tgetl(vptr + 4 * n);
932 1026  
933 1027 ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
934 1028 }
... ... @@ -949,6 +1043,7 @@ static struct shm_region {
949 1043 uint32_t size;
950 1044 } shm_regions[N_SHM_REGIONS];
951 1045  
  1046 +/* ??? This only works with linear mappings. */
952 1047 static long do_ipc(long call, long first, long second, long third,
953 1048 long ptr, long fifth)
954 1049 {
... ... @@ -1065,12 +1160,15 @@ IOCTLEntry ioctl_entries[] = {
1065 1160 { 0, 0, },
1066 1161 };
1067 1162  
  1163 +/* ??? Implement proper locking for ioctls. */
1068 1164 static long do_ioctl(long fd, long cmd, long arg)
1069 1165 {
1070 1166 const IOCTLEntry *ie;
1071 1167 const argtype *arg_type;
1072 1168 long ret;
1073 1169 uint8_t buf_temp[MAX_STRUCT_SIZE];
  1170 + int target_size;
  1171 + void *argptr;
1074 1172  
1075 1173 ie = ioctl_entries;
1076 1174 for(;;) {
... ... @@ -1098,23 +1196,32 @@ static long do_ioctl(long fd, long cmd, long arg)
1098 1196 break;
1099 1197 case TYPE_PTR:
1100 1198 arg_type++;
  1199 + target_size = thunk_type_size(arg_type, 0);
1101 1200 switch(ie->access) {
1102 1201 case IOC_R:
1103 1202 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1104 1203 if (!is_error(ret)) {
1105   - thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
  1204 + argptr = lock_user(arg, target_size, 0);
  1205 + thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
  1206 + unlock_user(argptr, arg, target_size);
1106 1207 }
1107 1208 break;
1108 1209 case IOC_W:
1109   - thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
  1210 + argptr = lock_user(arg, target_size, 1);
  1211 + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
  1212 + unlock_user(argptr, arg, 0);
1110 1213 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1111 1214 break;
1112 1215 default:
1113 1216 case IOC_RW:
1114   - thunk_convert(buf_temp, (void *)arg, arg_type, THUNK_HOST);
  1217 + argptr = lock_user(arg, target_size, 1);
  1218 + thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
  1219 + unlock_user(argptr, arg, 0);
1115 1220 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1116 1221 if (!is_error(ret)) {
1117   - thunk_convert((void *)arg, buf_temp, arg_type, THUNK_TARGET);
  1222 + argptr = lock_user(arg, target_size, 0);
  1223 + thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
  1224 + unlock_user(argptr, arg, target_size);
1118 1225 }
1119 1226 break;
1120 1227 }
... ... @@ -1338,35 +1445,41 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
1338 1445 /* NOTE: there is really one LDT for all the threads */
1339 1446 uint8_t *ldt_table;
1340 1447  
1341   -static int read_ldt(void *ptr, unsigned long bytecount)
  1448 +static int read_ldt(target_ulong ptr, unsigned long bytecount)
1342 1449 {
1343 1450 int size;
  1451 + void *p;
1344 1452  
1345 1453 if (!ldt_table)
1346 1454 return 0;
1347 1455 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1348 1456 if (size > bytecount)
1349 1457 size = bytecount;
1350   - memcpy(ptr, ldt_table, size);
  1458 + p = lock_user(ptr, size, 0);
  1459 + /* ??? Shoudl this by byteswapped? */
  1460 + memcpy(p, ldt_table, size);
  1461 + unlock_user(p, ptr, size);
1351 1462 return size;
1352 1463 }
1353 1464  
1354 1465 /* XXX: add locking support */
1355 1466 static int write_ldt(CPUX86State *env,
1356   - void *ptr, unsigned long bytecount, int oldmode)
  1467 + target_ulong ptr, unsigned long bytecount, int oldmode)
1357 1468 {
1358 1469 struct target_modify_ldt_ldt_s ldt_info;
  1470 + struct target_modify_ldt_ldt_s *target_ldt_info;
1359 1471 int seg_32bit, contents, read_exec_only, limit_in_pages;
1360 1472 int seg_not_present, useable;
1361 1473 uint32_t *lp, entry_1, entry_2;
1362 1474  
1363 1475 if (bytecount != sizeof(ldt_info))
1364 1476 return -EINVAL;
1365   - memcpy(&ldt_info, ptr, sizeof(ldt_info));
1366   - tswap32s(&ldt_info.entry_number);
1367   - tswapls((long *)&ldt_info.base_addr);
1368   - tswap32s(&ldt_info.limit);
1369   - tswap32s(&ldt_info.flags);
  1477 + lock_user_struct(target_ldt_info, ptr, 1);
  1478 + ldt_info.entry_number = tswap32(target_ldt_info->entry_number);
  1479 + ldt_info.base_addr = tswapl(target_ldt_info->base_addr);
  1480 + ldt_info.limit = tswap32(target_ldt_info->limit);
  1481 + ldt_info.flags = tswap32(target_ldt_info->flags);
  1482 + unlock_user_struct(target_ldt_info, ptr, 0);
1370 1483  
1371 1484 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1372 1485 return -EINVAL;
... ... @@ -1389,7 +1502,7 @@ static int write_ldt(CPUX86State *env,
1389 1502 if (!ldt_table)
1390 1503 return -ENOMEM;
1391 1504 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE);
1392   - env->ldt.base = (long)ldt_table;
  1505 + env->ldt.base = h2g(ldt_table);
1393 1506 env->ldt.limit = 0xffff;
1394 1507 }
1395 1508  
... ... @@ -1432,7 +1545,7 @@ install:
1432 1545 }
1433 1546  
1434 1547 /* specific and weird i386 syscalls */
1435   -int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
  1548 +int do_modify_ldt(CPUX86State *env, int func, target_ulong ptr, unsigned long bytecount)
1436 1549 {
1437 1550 int ret = -ENOSYS;
1438 1551  
... ... @@ -1523,31 +1636,35 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1523 1636 return ret;
1524 1637 }
1525 1638  
1526   -static long do_fcntl(int fd, int cmd, unsigned long arg)
  1639 +static long do_fcntl(int fd, int cmd, target_ulong arg)
1527 1640 {
1528 1641 struct flock fl;
1529   - struct target_flock *target_fl = (void *)arg;
  1642 + struct target_flock *target_fl;
1530 1643 long ret;
1531   -
  1644 +
1532 1645 switch(cmd) {
1533 1646 case TARGET_F_GETLK:
1534 1647 ret = fcntl(fd, cmd, &fl);
1535 1648 if (ret == 0) {
  1649 + lock_user_struct(target_fl, arg, 0);
1536 1650 target_fl->l_type = tswap16(fl.l_type);
1537 1651 target_fl->l_whence = tswap16(fl.l_whence);
1538 1652 target_fl->l_start = tswapl(fl.l_start);
1539 1653 target_fl->l_len = tswapl(fl.l_len);
1540 1654 target_fl->l_pid = tswapl(fl.l_pid);
  1655 + unlock_user_struct(target_fl, arg, 1);
1541 1656 }
1542 1657 break;
1543 1658  
1544 1659 case TARGET_F_SETLK:
1545 1660 case TARGET_F_SETLKW:
  1661 + lock_user_struct(target_fl, arg, 1);
1546 1662 fl.l_type = tswap16(target_fl->l_type);
1547 1663 fl.l_whence = tswap16(target_fl->l_whence);
1548 1664 fl.l_start = tswapl(target_fl->l_start);
1549 1665 fl.l_len = tswapl(target_fl->l_len);
1550 1666 fl.l_pid = tswapl(target_fl->l_pid);
  1667 + unlock_user_struct(target_fl, arg, 0);
1551 1668 ret = fcntl(fd, cmd, &fl);
1552 1669 break;
1553 1670  
... ... @@ -1690,12 +1807,35 @@ static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
1690 1807 }
1691 1808 #endif
1692 1809  
  1810 +static inline void target_to_host_timespec(struct timespec *host_ts,
  1811 + target_ulong target_addr)
  1812 +{
  1813 + struct target_timespec *target_ts;
  1814 +
  1815 + lock_user_struct(target_ts, target_addr, 1);
  1816 + host_ts->tv_sec = tswapl(target_ts->tv_sec);
  1817 + host_ts->tv_nsec = tswapl(target_ts->tv_nsec);
  1818 + unlock_user_struct(target_ts, target_addr, 0);
  1819 +}
  1820 +
  1821 +static inline void host_to_target_timespec(target_ulong target_addr,
  1822 + struct timespec *host_ts)
  1823 +{
  1824 + struct target_timespec *target_ts;
  1825 +
  1826 + lock_user_struct(target_ts, target_addr, 0);
  1827 + target_ts->tv_sec = tswapl(host_ts->tv_sec);
  1828 + target_ts->tv_nsec = tswapl(host_ts->tv_nsec);
  1829 + unlock_user_struct(target_ts, target_addr, 1);
  1830 +}
  1831 +
1693 1832 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1694 1833 long arg4, long arg5, long arg6)
1695 1834 {
1696 1835 long ret;
1697 1836 struct stat st;
1698 1837 struct statfs stfs;
  1838 + void *p;
1699 1839  
1700 1840 #ifdef DEBUG
1701 1841 gemu_log("syscall %d", num);
... ... @@ -1711,89 +1851,140 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1711 1851 ret = 0; /* avoid warning */
1712 1852 break;
1713 1853 case TARGET_NR_read:
1714   - page_unprotect_range((void *)arg2, arg3);
1715   - ret = get_errno(read(arg1, (void *)arg2, arg3));
  1854 + page_unprotect_range(arg2, arg3);
  1855 + p = lock_user(arg2, arg3, 0);
  1856 + ret = get_errno(read(arg1, p, arg3));
  1857 + unlock_user(p, arg2, ret);
1716 1858 break;
1717 1859 case TARGET_NR_write:
1718   - ret = get_errno(write(arg1, (void *)arg2, arg3));
  1860 + p = lock_user(arg2, arg3, 1);
  1861 + ret = get_errno(write(arg1, p, arg3));
  1862 + unlock_user(p, arg2, 0);
1719 1863 break;
1720 1864 case TARGET_NR_open:
1721   - ret = get_errno(open(path((const char *)arg1),
  1865 + p = lock_user_string(arg1);
  1866 + ret = get_errno(open(path(p),
1722 1867 target_to_host_bitmask(arg2, fcntl_flags_tbl),
1723 1868 arg3));
  1869 + unlock_user(p, arg1, 0);
1724 1870 break;
1725 1871 case TARGET_NR_close:
1726 1872 ret = get_errno(close(arg1));
1727 1873 break;
1728 1874 case TARGET_NR_brk:
1729   - ret = do_brk((char *)arg1);
  1875 + ret = do_brk(arg1);
1730 1876 break;
1731 1877 case TARGET_NR_fork:
1732 1878 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1733 1879 break;
1734 1880 case TARGET_NR_waitpid:
1735 1881 {
1736   - int *status = (int *)arg2;
1737   - ret = get_errno(waitpid(arg1, status, arg3));
1738   - if (!is_error(ret) && status)
1739   - tswapls((long *)&status);
  1882 + int status;
  1883 + ret = get_errno(waitpid(arg1, &status, arg3));
  1884 + if (!is_error(ret) && arg2)
  1885 + tput32(arg2, status);
1740 1886 }
1741 1887 break;
1742 1888 case TARGET_NR_creat:
1743   - ret = get_errno(creat((const char *)arg1, arg2));
  1889 + p = lock_user_string(arg1);
  1890 + ret = get_errno(creat(p, arg2));
  1891 + unlock_user(p, arg1, 0);
1744 1892 break;
1745 1893 case TARGET_NR_link:
1746   - ret = get_errno(link((const char *)arg1, (const char *)arg2));
  1894 + {
  1895 + void * p2;
  1896 + p = lock_user_string(arg1);
  1897 + p2 = lock_user_string(arg2);
  1898 + ret = get_errno(link(p, p2));
  1899 + unlock_user(p2, arg2, 0);
  1900 + unlock_user(p, arg1, 0);
  1901 + }
1747 1902 break;
1748 1903 case TARGET_NR_unlink:
1749   - ret = get_errno(unlink((const char *)arg1));
  1904 + p = lock_user_string(arg1);
  1905 + ret = get_errno(unlink(p));
  1906 + unlock_user(p, arg1, 0);
1750 1907 break;
1751 1908 case TARGET_NR_execve:
1752 1909 {
1753 1910 char **argp, **envp;
1754 1911 int argc, envc;
1755   - uint32_t *p;
  1912 + target_ulong gp;
  1913 + target_ulong guest_argp;
  1914 + target_ulong guest_envp;
  1915 + target_ulong addr;
1756 1916 char **q;
1757 1917  
1758 1918 argc = 0;
1759   - for (p = (void *)arg2; *p; p++)
  1919 + guest_argp = arg2;
  1920 + for (gp = guest_argp; tgetl(gp); gp++)
1760 1921 argc++;
1761 1922 envc = 0;
1762   - for (p = (void *)arg3; *p; p++)
  1923 + guest_envp = arg3;
  1924 + for (gp = guest_envp; tgetl(gp); gp++)
1763 1925 envc++;
1764 1926  
1765 1927 argp = alloca((argc + 1) * sizeof(void *));
1766 1928 envp = alloca((envc + 1) * sizeof(void *));
1767 1929  
1768   - for (p = (void *)arg2, q = argp; *p; p++, q++)
1769   - *q = (void *)tswap32(*p);
  1930 + for (gp = guest_argp, q = argp; ;
  1931 + gp += sizeof(target_ulong), q++) {
  1932 + addr = tgetl(gp);
  1933 + if (!addr)
  1934 + break;
  1935 + *q = lock_user_string(addr);
  1936 + }
1770 1937 *q = NULL;
1771 1938  
1772   - for (p = (void *)arg3, q = envp; *p; p++, q++)
1773   - *q = (void *)tswap32(*p);
  1939 + for (gp = guest_envp, q = envp; ;
  1940 + gp += sizeof(target_ulong), q++) {
  1941 + addr = tgetl(gp);
  1942 + if (!addr)
  1943 + break;
  1944 + *q = lock_user_string(addr);
  1945 + }
1774 1946 *q = NULL;
1775 1947  
1776   - ret = get_errno(execve((const char *)arg1, argp, envp));
  1948 + p = lock_user_string(arg1);
  1949 + ret = get_errno(execve(p, argp, envp));
  1950 + unlock_user(p, arg1, 0);
  1951 +
  1952 + for (gp = guest_argp, q = argp; *q;
  1953 + gp += sizeof(target_ulong), q++) {
  1954 + addr = tgetl(gp);
  1955 + unlock_user(*q, addr, 0);
  1956 + }
  1957 + for (gp = guest_envp, q = envp; *q;
  1958 + gp += sizeof(target_ulong), q++) {
  1959 + addr = tgetl(gp);
  1960 + unlock_user(*q, addr, 0);
  1961 + }
1777 1962 }
1778 1963 break;
1779 1964 case TARGET_NR_chdir:
1780   - ret = get_errno(chdir((const char *)arg1));
  1965 + p = lock_user_string(arg1);
  1966 + ret = get_errno(chdir(p));
  1967 + unlock_user(p, arg1, 0);
1781 1968 break;
1782 1969 #ifdef TARGET_NR_time
1783 1970 case TARGET_NR_time:
1784 1971 {
1785   - int *time_ptr = (int *)arg1;
1786   - ret = get_errno(time((time_t *)time_ptr));
1787   - if (!is_error(ret) && time_ptr)
1788   - tswap32s(time_ptr);
  1972 + time_t host_time;
  1973 + ret = get_errno(time(&host_time));
  1974 + if (!is_error(ret) && arg1)
  1975 + tputl(arg1, host_time);
1789 1976 }
1790 1977 break;
1791 1978 #endif
1792 1979 case TARGET_NR_mknod:
1793   - ret = get_errno(mknod((const char *)arg1, arg2, arg3));
  1980 + p = lock_user_string(arg1);
  1981 + ret = get_errno(mknod(p, arg2, arg3));
  1982 + unlock_user(p, arg1, 0);
1794 1983 break;
1795 1984 case TARGET_NR_chmod:
1796   - ret = get_errno(chmod((const char *)arg1, arg2));
  1985 + p = lock_user_string(arg1);
  1986 + ret = get_errno(chmod(p, arg2));
  1987 + unlock_user(p, arg1, 0);
1797 1988 break;
1798 1989 #ifdef TARGET_NR_break
1799 1990 case TARGET_NR_break:
... ... @@ -1813,14 +2004,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1813 2004 /* need to look at the data field */
1814 2005 goto unimplemented;
1815 2006 case TARGET_NR_umount:
1816   - ret = get_errno(umount((const char *)arg1));
  2007 + p = lock_user_string(arg1);
  2008 + ret = get_errno(umount(p));
  2009 + unlock_user(p, arg1, 0);
1817 2010 break;
1818 2011 case TARGET_NR_stime:
1819 2012 {
1820   - int *time_ptr = (int *)arg1;
1821   - if (time_ptr)
1822   - tswap32s(time_ptr);
1823   - ret = get_errno(stime((time_t *)time_ptr));
  2013 + time_t host_time;
  2014 + host_time = tgetl(arg1);
  2015 + ret = get_errno(stime(&host_time));
1824 2016 }
1825 2017 break;
1826 2018 case TARGET_NR_ptrace:
... ... @@ -1837,30 +2029,36 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1837 2029 break;
1838 2030 case TARGET_NR_utime:
1839 2031 {
1840   - struct utimbuf tbuf, *tbuf1;
1841   - struct target_utimbuf *target_tbuf = (void *)arg2;
1842   - if (target_tbuf) {
1843   - get_user(tbuf.actime, &target_tbuf->actime);
1844   - get_user(tbuf.modtime, &target_tbuf->modtime);
1845   - tbuf1 = &tbuf;
  2032 + struct utimbuf tbuf, *host_tbuf;
  2033 + struct target_utimbuf *target_tbuf;
  2034 + if (arg2) {
  2035 + lock_user_struct(target_tbuf, arg2, 1);
  2036 + tbuf.actime = tswapl(target_tbuf->actime);
  2037 + tbuf.modtime = tswapl(target_tbuf->modtime);
  2038 + unlock_user_struct(target_tbuf, arg2, 0);
  2039 + host_tbuf = &tbuf;
1846 2040 } else {
1847   - tbuf1 = NULL;
  2041 + host_tbuf = NULL;
1848 2042 }
1849   - ret = get_errno(utime((const char *)arg1, tbuf1));
  2043 + p = lock_user_string(arg1);
  2044 + ret = get_errno(utime(p, host_tbuf));
  2045 + unlock_user(p, arg1, 0);
1850 2046 }
1851 2047 break;
1852 2048 case TARGET_NR_utimes:
1853 2049 {
1854   - struct target_timeval *target_tvp = (struct target_timeval *)arg2;
1855 2050 struct timeval *tvp, tv[2];
1856   - if (target_tvp) {
1857   - target_to_host_timeval(&tv[0], &target_tvp[0]);
1858   - target_to_host_timeval(&tv[1], &target_tvp[1]);
  2051 + if (arg2) {
  2052 + target_to_host_timeval(&tv[0], arg2);
  2053 + target_to_host_timeval(&tv[1],
  2054 + arg2 + sizeof (struct target_timeval));
1859 2055 tvp = tv;
1860 2056 } else {
1861 2057 tvp = NULL;
1862 2058 }
1863   - ret = get_errno(utimes((const char *)arg1, tvp));
  2059 + p = lock_user_string(arg1);
  2060 + ret = get_errno(utimes(p, tvp));
  2061 + unlock_user(p, arg1, 0);
1864 2062 }
1865 2063 break;
1866 2064 #ifdef TARGET_NR_stty
... ... @@ -1872,7 +2070,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1872 2070 goto unimplemented;
1873 2071 #endif
1874 2072 case TARGET_NR_access:
1875   - ret = get_errno(access((const char *)arg1, arg2));
  2073 + p = lock_user_string(arg1);
  2074 + ret = get_errno(access(p, arg2));
  2075 + unlock_user(p, arg1, 0);
1876 2076 break;
1877 2077 case TARGET_NR_nice:
1878 2078 ret = get_errno(nice(arg1));
... ... @@ -1889,33 +2089,45 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1889 2089 ret = get_errno(kill(arg1, arg2));
1890 2090 break;
1891 2091 case TARGET_NR_rename:
1892   - ret = get_errno(rename((const char *)arg1, (const char *)arg2));
  2092 + {
  2093 + void *p2;
  2094 + p = lock_user_string(arg1);
  2095 + p2 = lock_user_string(arg2);
  2096 + ret = get_errno(rename(p, p2));
  2097 + unlock_user(p2, arg2, 0);
  2098 + unlock_user(p, arg1, 0);
  2099 + }
1893 2100 break;
1894 2101 case TARGET_NR_mkdir:
1895   - ret = get_errno(mkdir((const char *)arg1, arg2));
  2102 + p = lock_user_string(arg1);
  2103 + ret = get_errno(mkdir(p, arg2));
  2104 + unlock_user(p, arg1, 0);
1896 2105 break;
1897 2106 case TARGET_NR_rmdir:
1898   - ret = get_errno(rmdir((const char *)arg1));
  2107 + p = lock_user_string(arg1);
  2108 + ret = get_errno(rmdir(p));
  2109 + unlock_user(p, arg1, 0);
1899 2110 break;
1900 2111 case TARGET_NR_dup:
1901 2112 ret = get_errno(dup(arg1));
1902 2113 break;
1903 2114 case TARGET_NR_pipe:
1904 2115 {
1905   - int *pipe_ptr = (int *)arg1;
1906   - ret = get_errno(pipe(pipe_ptr));
  2116 + int host_pipe[2];
  2117 + ret = get_errno(pipe(host_pipe));
1907 2118 if (!is_error(ret)) {
1908   - tswap32s(&pipe_ptr[0]);
1909   - tswap32s(&pipe_ptr[1]);
  2119 + tput32(arg1, host_pipe[0]);
  2120 + tput32(arg1 + 4, host_pipe[1]);
1910 2121 }
1911 2122 }
1912 2123 break;
1913 2124 case TARGET_NR_times:
1914 2125 {
1915   - struct target_tms *tmsp = (void *)arg1;
  2126 + struct target_tms *tmsp;
1916 2127 struct tms tms;
1917 2128 ret = get_errno(times(&tms));
1918   - if (tmsp) {
  2129 + if (arg1) {
  2130 + tmsp = lock_user(arg1, sizeof(struct target_tms), 0);
1919 2131 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
1920 2132 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
1921 2133 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime));
... ... @@ -1935,7 +2147,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1935 2147 case TARGET_NR_acct:
1936 2148 goto unimplemented;
1937 2149 case TARGET_NR_umount2:
1938   - ret = get_errno(umount2((const char *)arg1, arg2));
  2150 + p = lock_user_string(arg1);
  2151 + ret = get_errno(umount2(p, arg2));
  2152 + unlock_user(p, arg1, 0);
1939 2153 break;
1940 2154 #ifdef TARGET_NR_lock
1941 2155 case TARGET_NR_lock:
... ... @@ -1966,7 +2180,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1966 2180 ret = get_errno(umask(arg1));
1967 2181 break;
1968 2182 case TARGET_NR_chroot:
1969   - ret = get_errno(chroot((const char *)arg1));
  2183 + p = lock_user_string(arg1);
  2184 + ret = get_errno(chroot(p));
  2185 + unlock_user(p, arg1, 0);
1970 2186 break;
1971 2187 case TARGET_NR_ustat:
1972 2188 goto unimplemented;
... ... @@ -1984,29 +2200,49 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1984 2200 break;
1985 2201 case TARGET_NR_sigaction:
1986 2202 {
1987   - struct target_old_sigaction *old_act = (void *)arg2;
1988   - struct target_old_sigaction *old_oact = (void *)arg3;
  2203 + struct target_old_sigaction *old_act;
1989 2204 struct target_sigaction act, oact, *pact;
1990   - if (old_act) {
  2205 + if (arg2) {
  2206 + lock_user_struct(old_act, arg2, 1);
1991 2207 act._sa_handler = old_act->_sa_handler;
1992 2208 target_siginitset(&act.sa_mask, old_act->sa_mask);
1993 2209 act.sa_flags = old_act->sa_flags;
1994 2210 act.sa_restorer = old_act->sa_restorer;
  2211 + unlock_user_struct(old_act, arg2, 0);
1995 2212 pact = &act;
1996 2213 } else {
1997 2214 pact = NULL;
1998 2215 }
1999 2216 ret = get_errno(do_sigaction(arg1, pact, &oact));
2000   - if (!is_error(ret) && old_oact) {
2001   - old_oact->_sa_handler = oact._sa_handler;
2002   - old_oact->sa_mask = oact.sa_mask.sig[0];
2003   - old_oact->sa_flags = oact.sa_flags;
2004   - old_oact->sa_restorer = oact.sa_restorer;
  2217 + if (!is_error(ret) && arg3) {
  2218 + lock_user_struct(old_act, arg3, 0);
  2219 + old_act->_sa_handler = oact._sa_handler;
  2220 + old_act->sa_mask = oact.sa_mask.sig[0];
  2221 + old_act->sa_flags = oact.sa_flags;
  2222 + old_act->sa_restorer = oact.sa_restorer;
  2223 + unlock_user_struct(old_act, arg3, 1);
2005 2224 }
2006 2225 }
2007 2226 break;
2008 2227 case TARGET_NR_rt_sigaction:
2009   - ret = get_errno(do_sigaction(arg1, (void *)arg2, (void *)arg3));
  2228 + {
  2229 + struct target_sigaction *act;
  2230 + struct target_sigaction *oact;
  2231 +
  2232 + if (arg2)
  2233 + lock_user_struct(act, arg2, 1);
  2234 + else
  2235 + act = NULL;
  2236 + if (arg3)
  2237 + lock_user_struct(oact, arg3, 0);
  2238 + else
  2239 + oact = NULL;
  2240 + ret = get_errno(do_sigaction(arg1, act, oact));
  2241 + if (arg2)
  2242 + unlock_user_struct(act, arg2, 0);
  2243 + if (arg3)
  2244 + unlock_user_struct(oact, arg3, 1);
  2245 + }
2010 2246 break;
2011 2247 case TARGET_NR_sgetmask:
2012 2248 {
... ... @@ -2033,9 +2269,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2033 2269 {
2034 2270 int how = arg1;
2035 2271 sigset_t set, oldset, *set_ptr;
2036   - target_ulong *pset = (void *)arg2, *poldset = (void *)arg3;
2037 2272  
2038   - if (pset) {
  2273 + if (arg2) {
2039 2274 switch(how) {
2040 2275 case TARGET_SIG_BLOCK:
2041 2276 how = SIG_BLOCK;
... ... @@ -2050,15 +2285,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2050 2285 ret = -EINVAL;
2051 2286 goto fail;
2052 2287 }
2053   - target_to_host_old_sigset(&set, pset);
  2288 + p = lock_user(arg2, sizeof(target_sigset_t), 1);
  2289 + target_to_host_old_sigset(&set, p);
  2290 + unlock_user(p, arg2, 0);
2054 2291 set_ptr = &set;
2055 2292 } else {
2056 2293 how = 0;
2057 2294 set_ptr = NULL;
2058 2295 }
2059 2296 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset));
2060   - if (!is_error(ret) && poldset) {
2061   - host_to_target_old_sigset(poldset, &oldset);
  2297 + if (!is_error(ret) && arg3) {
  2298 + p = lock_user(arg3, sizeof(target_sigset_t), 0);
  2299 + host_to_target_old_sigset(p, &oldset);
  2300 + unlock_user(p, arg3, sizeof(target_sigset_t));
2062 2301 }
2063 2302 }
2064 2303 break;
... ... @@ -2066,10 +2305,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2066 2305 {
2067 2306 int how = arg1;
2068 2307 sigset_t set, oldset, *set_ptr;
2069   - target_sigset_t *pset = (void *)arg2;
2070   - target_sigset_t *poldset = (void *)arg3;
2071 2308  
2072   - if (pset) {
  2309 + if (arg2) {
2073 2310 switch(how) {
2074 2311 case TARGET_SIG_BLOCK:
2075 2312 how = SIG_BLOCK;
... ... @@ -2084,15 +2321,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2084 2321 ret = -EINVAL;
2085 2322 goto fail;
2086 2323 }
2087   - target_to_host_sigset(&set, pset);
  2324 + p = lock_user(arg2, sizeof(target_sigset_t), 1);
  2325 + target_to_host_sigset(&set, p);
  2326 + unlock_user(p, arg2, 0);
2088 2327 set_ptr = &set;
2089 2328 } else {
2090 2329 how = 0;
2091 2330 set_ptr = NULL;
2092 2331 }
2093 2332 ret = get_errno(sigprocmask(how, set_ptr, &oldset));
2094   - if (!is_error(ret) && poldset) {
2095   - host_to_target_sigset(poldset, &oldset);
  2333 + if (!is_error(ret) && arg3) {
  2334 + p = lock_user(arg3, sizeof(target_sigset_t), 0);
  2335 + host_to_target_sigset(p, &oldset);
  2336 + unlock_user(p, arg3, sizeof(target_sigset_t));
2096 2337 }
2097 2338 }
2098 2339 break;
... ... @@ -2101,7 +2342,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2101 2342 sigset_t set;
2102 2343 ret = get_errno(sigpending(&set));
2103 2344 if (!is_error(ret)) {
2104   - host_to_target_old_sigset((target_ulong *)arg1, &set);
  2345 + p = lock_user(arg1, sizeof(target_sigset_t), 0);
  2346 + host_to_target_old_sigset(p, &set);
  2347 + unlock_user(p, arg1, sizeof(target_sigset_t));
2105 2348 }
2106 2349 }
2107 2350 break;
... ... @@ -2110,51 +2353,59 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2110 2353 sigset_t set;
2111 2354 ret = get_errno(sigpending(&set));
2112 2355 if (!is_error(ret)) {
2113   - host_to_target_sigset((target_sigset_t *)arg1, &set);
  2356 + p = lock_user(arg1, sizeof(target_sigset_t), 0);
  2357 + host_to_target_sigset(p, &set);
  2358 + unlock_user(p, arg1, sizeof(target_sigset_t));
2114 2359 }
2115 2360 }
2116 2361 break;
2117 2362 case TARGET_NR_sigsuspend:
2118 2363 {
2119 2364 sigset_t set;
2120   - target_to_host_old_sigset(&set, (target_ulong *)arg1);
  2365 + p = lock_user(arg1, sizeof(target_sigset_t), 1);
  2366 + target_to_host_old_sigset(&set, p);
  2367 + unlock_user(p, arg1, 0);
2121 2368 ret = get_errno(sigsuspend(&set));
2122 2369 }
2123 2370 break;
2124 2371 case TARGET_NR_rt_sigsuspend:
2125 2372 {
2126 2373 sigset_t set;
2127   - target_to_host_sigset(&set, (target_sigset_t *)arg1);
  2374 + p = lock_user(arg1, sizeof(target_sigset_t), 1);
  2375 + target_to_host_sigset(&set, p);
  2376 + unlock_user(p, arg1, 0);
2128 2377 ret = get_errno(sigsuspend(&set));
2129 2378 }
2130 2379 break;
2131 2380 case TARGET_NR_rt_sigtimedwait:
2132 2381 {
2133   - target_sigset_t *target_set = (void *)arg1;
2134   - target_siginfo_t *target_uinfo = (void *)arg2;
2135   - struct target_timespec *target_uts = (void *)arg3;
2136 2382 sigset_t set;
2137 2383 struct timespec uts, *puts;
2138 2384 siginfo_t uinfo;
2139 2385  
2140   - target_to_host_sigset(&set, target_set);
2141   - if (target_uts) {
  2386 + p = lock_user(arg1, sizeof(target_sigset_t), 1);
  2387 + target_to_host_sigset(&set, p);
  2388 + unlock_user(p, arg1, 0);
  2389 + if (arg3) {
2142 2390 puts = &uts;
2143   - puts->tv_sec = tswapl(target_uts->tv_sec);
2144   - puts->tv_nsec = tswapl(target_uts->tv_nsec);
  2391 + target_to_host_timespec(puts, arg3);
2145 2392 } else {
2146 2393 puts = NULL;
2147 2394 }
2148 2395 ret = get_errno(sigtimedwait(&set, &uinfo, puts));
2149   - if (!is_error(ret) && target_uinfo) {
2150   - host_to_target_siginfo(target_uinfo, &uinfo);
  2396 + if (!is_error(ret) && arg2) {
  2397 + p = lock_user(arg2, sizeof(target_sigset_t), 0);
  2398 + host_to_target_siginfo(p, &uinfo);
  2399 + unlock_user(p, arg2, sizeof(target_sigset_t));
2151 2400 }
2152 2401 }
2153 2402 break;
2154 2403 case TARGET_NR_rt_sigqueueinfo:
2155 2404 {
2156 2405 siginfo_t uinfo;
2157   - target_to_host_siginfo(&uinfo, (target_siginfo_t *)arg3);
  2406 + p = lock_user(arg3, sizeof(target_sigset_t), 1);
  2407 + target_to_host_siginfo(&uinfo, p);
  2408 + unlock_user(p, arg1, 0);
2158 2409 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
2159 2410 }
2160 2411 break;
... ... @@ -2167,16 +2418,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2167 2418 ret = do_rt_sigreturn(cpu_env);
2168 2419 break;
2169 2420 case TARGET_NR_sethostname:
2170   - ret = get_errno(sethostname((const char *)arg1, arg2));
  2421 + p = lock_user_string(arg1);
  2422 + ret = get_errno(sethostname(p, arg2));
  2423 + unlock_user(p, arg1, 0);
2171 2424 break;
2172 2425 case TARGET_NR_setrlimit:
2173 2426 {
2174 2427 /* XXX: convert resource ? */
2175 2428 int resource = arg1;
2176   - struct target_rlimit *target_rlim = (void *)arg2;
  2429 + struct target_rlimit *target_rlim;
2177 2430 struct rlimit rlim;
  2431 + lock_user_struct(target_rlim, arg2, 1);
2178 2432 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2179 2433 rlim.rlim_max = tswapl(target_rlim->rlim_max);
  2434 + unlock_user_struct(target_rlim, arg2, 0);
2180 2435 ret = get_errno(setrlimit(resource, &rlim));
2181 2436 }
2182 2437 break;
... ... @@ -2184,72 +2439,91 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2184 2439 {
2185 2440 /* XXX: convert resource ? */
2186 2441 int resource = arg1;
2187   - struct target_rlimit *target_rlim = (void *)arg2;
  2442 + struct target_rlimit *target_rlim;
2188 2443 struct rlimit rlim;
2189 2444  
2190 2445 ret = get_errno(getrlimit(resource, &rlim));
2191 2446 if (!is_error(ret)) {
2192   - target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2193   - target_rlim->rlim_max = tswapl(rlim.rlim_max);
  2447 + lock_user_struct(target_rlim, arg2, 0);
  2448 + rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
  2449 + rlim.rlim_max = tswapl(target_rlim->rlim_max);
  2450 + unlock_user_struct(target_rlim, arg2, 1);
2194 2451 }
2195 2452 }
2196 2453 break;
2197 2454 case TARGET_NR_getrusage:
2198 2455 {
2199 2456 struct rusage rusage;
2200   - struct target_rusage *target_rusage = (void *)arg2;
2201 2457 ret = get_errno(getrusage(arg1, &rusage));
2202 2458 if (!is_error(ret)) {
2203   - host_to_target_rusage(target_rusage, &rusage);
  2459 + host_to_target_rusage(arg2, &rusage);
2204 2460 }
2205 2461 }
2206 2462 break;
2207 2463 case TARGET_NR_gettimeofday:
2208 2464 {
2209   - struct target_timeval *target_tv = (void *)arg1;
2210 2465 struct timeval tv;
2211 2466 ret = get_errno(gettimeofday(&tv, NULL));
2212 2467 if (!is_error(ret)) {
2213   - host_to_target_timeval(target_tv, &tv);
  2468 + host_to_target_timeval(arg1, &tv);
2214 2469 }
2215 2470 }
2216 2471 break;
2217 2472 case TARGET_NR_settimeofday:
2218 2473 {
2219   - struct target_timeval *target_tv = (void *)arg1;
2220 2474 struct timeval tv;
2221   - target_to_host_timeval(&tv, target_tv);
  2475 + target_to_host_timeval(&tv, arg1);
2222 2476 ret = get_errno(settimeofday(&tv, NULL));
2223 2477 }
2224 2478 break;
2225 2479 #ifdef TARGET_NR_select
2226 2480 case TARGET_NR_select:
2227 2481 {
2228   - struct target_sel_arg_struct *sel = (void *)arg1;
2229   - sel->n = tswapl(sel->n);
2230   - sel->inp = tswapl(sel->inp);
2231   - sel->outp = tswapl(sel->outp);
2232   - sel->exp = tswapl(sel->exp);
2233   - sel->tvp = tswapl(sel->tvp);
2234   - ret = do_select(sel->n, (void *)sel->inp, (void *)sel->outp,
2235   - (void *)sel->exp, (void *)sel->tvp);
  2482 + struct target_sel_arg_struct *sel;
  2483 + target_ulong inp, outp, exp, tvp;
  2484 + long nsel;
  2485 +
  2486 + lock_user_struct(sel, arg1, 1);
  2487 + nsel = tswapl(sel->n);
  2488 + inp = tswapl(sel->inp);
  2489 + outp = tswapl(sel->outp);
  2490 + exp = tswapl(sel->exp);
  2491 + tvp = tswapl(sel->tvp);
  2492 + unlock_user_struct(sel, arg1, 0);
  2493 + ret = do_select(nsel, inp, outp, exp, tvp);
2236 2494 }
2237 2495 break;
2238 2496 #endif
2239 2497 case TARGET_NR_symlink:
2240   - ret = get_errno(symlink((const char *)arg1, (const char *)arg2));
  2498 + {
  2499 + void *p2;
  2500 + p = lock_user_string(arg1);
  2501 + p2 = lock_user_string(arg2);
  2502 + ret = get_errno(symlink(p, p2));
  2503 + unlock_user(p2, arg2, 0);
  2504 + unlock_user(p, arg1, 0);
  2505 + }
2241 2506 break;
2242 2507 #ifdef TARGET_NR_oldlstat
2243 2508 case TARGET_NR_oldlstat:
2244 2509 goto unimplemented;
2245 2510 #endif
2246 2511 case TARGET_NR_readlink:
2247   - ret = get_errno(readlink(path((const char *)arg1), (char *)arg2, arg3));
  2512 + {
  2513 + void *p2;
  2514 + p = lock_user_string(arg1);
  2515 + p2 = lock_user(arg2, arg3, 0);
  2516 + ret = get_errno(readlink(path(p), p2, arg3));
  2517 + unlock_user(p2, arg2, ret);
  2518 + unlock_user(p, arg1, 0);
  2519 + }
2248 2520 break;
2249 2521 case TARGET_NR_uselib:
2250 2522 goto unimplemented;
2251 2523 case TARGET_NR_swapon:
2252   - ret = get_errno(swapon((const char *)arg1, arg2));
  2524 + p = lock_user_string(arg1);
  2525 + ret = get_errno(swapon(p, arg2));
  2526 + unlock_user(p, arg1, 0);
2253 2527 break;
2254 2528 case TARGET_NR_reboot:
2255 2529 goto unimplemented;
... ... @@ -2258,14 +2532,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2258 2532 case TARGET_NR_mmap:
2259 2533 #if defined(TARGET_I386) || defined(TARGET_ARM)
2260 2534 {
2261   - uint32_t v1, v2, v3, v4, v5, v6, *vptr;
2262   - vptr = (uint32_t *)arg1;
2263   - v1 = tswap32(vptr[0]);
2264   - v2 = tswap32(vptr[1]);
2265   - v3 = tswap32(vptr[2]);
2266   - v4 = tswap32(vptr[3]);
2267   - v5 = tswap32(vptr[4]);
2268   - v6 = tswap32(vptr[5]);
  2535 + target_ulong *v;
  2536 + target_ulong v1, v2, v3, v4, v5, v6;
  2537 + v = lock_user(arg1, 6 * sizeof(target_ulong), 1);
  2538 + v1 = tswapl(v[0]);
  2539 + v2 = tswapl(v[1]);
  2540 + v3 = tswapl(v[2]);
  2541 + v4 = tswapl(v[3]);
  2542 + v5 = tswapl(v[4]);
  2543 + v6 = tswapl(v[5]);
  2544 + unlock_user(v, arg1, 0);
2269 2545 ret = get_errno(target_mmap(v1, v2, v3,
2270 2546 target_to_host_bitmask(v4, mmap_flags_tbl),
2271 2547 v5, v6));
... ... @@ -2299,14 +2575,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2299 2575 case TARGET_NR_mremap:
2300 2576 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
2301 2577 break;
  2578 + /* ??? msync/mlock/munlock are broken for softmmu. */
2302 2579 case TARGET_NR_msync:
2303   - ret = get_errno(msync((void *)arg1, arg2, arg3));
  2580 + ret = get_errno(msync(g2h(arg1), arg2, arg3));
2304 2581 break;
2305 2582 case TARGET_NR_mlock:
2306   - ret = get_errno(mlock((void *)arg1, arg2));
  2583 + ret = get_errno(mlock(g2h(arg1), arg2));
2307 2584 break;
2308 2585 case TARGET_NR_munlock:
2309   - ret = get_errno(munlock((void *)arg1, arg2));
  2586 + ret = get_errno(munlock(g2h(arg1), arg2));
2310 2587 break;
2311 2588 case TARGET_NR_mlockall:
2312 2589 ret = get_errno(mlockall(arg1));
... ... @@ -2315,7 +2592,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2315 2592 ret = get_errno(munlockall());
2316 2593 break;
2317 2594 case TARGET_NR_truncate:
2318   - ret = get_errno(truncate((const char *)arg1, arg2));
  2595 + p = lock_user_string(arg1);
  2596 + ret = get_errno(truncate(p, arg2));
  2597 + unlock_user(p, arg1, 0);
2319 2598 break;
2320 2599 case TARGET_NR_ftruncate:
2321 2600 ret = get_errno(ftruncate(arg1, arg2));
... ... @@ -2334,11 +2613,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2334 2613 goto unimplemented;
2335 2614 #endif
2336 2615 case TARGET_NR_statfs:
2337   - ret = get_errno(statfs(path((const char *)arg1), &stfs));
  2616 + p = lock_user_string(arg1);
  2617 + ret = get_errno(statfs(path(p), &stfs));
  2618 + unlock_user(p, arg1, 0);
2338 2619 convert_statfs:
2339 2620 if (!is_error(ret)) {
2340   - struct target_statfs *target_stfs = (void *)arg2;
  2621 + struct target_statfs *target_stfs;
2341 2622  
  2623 + lock_user_struct(target_stfs, arg2, 0);
  2624 + /* ??? put_user is probably wrong. */
2342 2625 put_user(stfs.f_type, &target_stfs->f_type);
2343 2626 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2344 2627 put_user(stfs.f_blocks, &target_stfs->f_blocks);
... ... @@ -2348,6 +2631,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2348 2631 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2349 2632 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2350 2633 put_user(stfs.f_namelen, &target_stfs->f_namelen);
  2634 + unlock_user_struct(target_stfs, arg2, 1);
2351 2635 }
2352 2636 break;
2353 2637 case TARGET_NR_fstatfs:
... ... @@ -2355,11 +2639,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2355 2639 goto convert_statfs;
2356 2640 #ifdef TARGET_NR_statfs64
2357 2641 case TARGET_NR_statfs64:
2358   - ret = get_errno(statfs(path((const char *)arg1), &stfs));
  2642 + p = lock_user_string(arg1);
  2643 + ret = get_errno(statfs(path(p), &stfs));
  2644 + unlock_user(p, arg1, 0);
2359 2645 convert_statfs64:
2360 2646 if (!is_error(ret)) {
2361   - struct target_statfs64 *target_stfs = (void *)arg3;
2362   -
  2647 + struct target_statfs64 *target_stfs;
  2648 +
  2649 + lock_user_struct(target_stfs, arg3, 0);
  2650 + /* ??? put_user is probably wrong. */
2363 2651 put_user(stfs.f_type, &target_stfs->f_type);
2364 2652 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2365 2653 put_user(stfs.f_blocks, &target_stfs->f_blocks);
... ... @@ -2369,6 +2657,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2369 2657 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2370 2658 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2371 2659 put_user(stfs.f_namelen, &target_stfs->f_namelen);
  2660 + unlock_user_struct(target_stfs, arg3, 0);
2372 2661 }
2373 2662 break;
2374 2663 case TARGET_NR_fstatfs64:
... ... @@ -2380,60 +2669,63 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2380 2669 goto unimplemented;
2381 2670 #endif
2382 2671 case TARGET_NR_socketcall:
2383   - ret = do_socketcall(arg1, (int32_t *)arg2);
  2672 + ret = do_socketcall(arg1, arg2);
2384 2673 break;
2385 2674 case TARGET_NR_syslog:
2386 2675 goto unimplemented;
2387 2676 case TARGET_NR_setitimer:
2388 2677 {
2389   - struct target_itimerval *target_value = (void *)arg2;
2390   - struct target_itimerval *target_ovalue = (void *)arg3;
2391 2678 struct itimerval value, ovalue, *pvalue;
2392 2679  
2393   - if (target_value) {
  2680 + if (arg2) {
2394 2681 pvalue = &value;
2395 2682 target_to_host_timeval(&pvalue->it_interval,
2396   - &target_value->it_interval);
  2683 + arg2);
2397 2684 target_to_host_timeval(&pvalue->it_value,
2398   - &target_value->it_value);
  2685 + arg2 + sizeof(struct target_timeval));
2399 2686 } else {
2400 2687 pvalue = NULL;
2401 2688 }
2402 2689 ret = get_errno(setitimer(arg1, pvalue, &ovalue));
2403   - if (!is_error(ret) && target_ovalue) {
2404   - host_to_target_timeval(&target_ovalue->it_interval,
  2690 + if (!is_error(ret) && arg3) {
  2691 + host_to_target_timeval(arg3,
2405 2692 &ovalue.it_interval);
2406   - host_to_target_timeval(&target_ovalue->it_value,
  2693 + host_to_target_timeval(arg3 + sizeof(struct target_timeval),
2407 2694 &ovalue.it_value);
2408 2695 }
2409 2696 }
2410 2697 break;
2411 2698 case TARGET_NR_getitimer:
2412 2699 {
2413   - struct target_itimerval *target_value = (void *)arg2;
2414 2700 struct itimerval value;
2415 2701  
2416 2702 ret = get_errno(getitimer(arg1, &value));
2417   - if (!is_error(ret) && target_value) {
2418   - host_to_target_timeval(&target_value->it_interval,
  2703 + if (!is_error(ret) && arg2) {
  2704 + host_to_target_timeval(arg2,
2419 2705 &value.it_interval);
2420   - host_to_target_timeval(&target_value->it_value,
  2706 + host_to_target_timeval(arg2 + sizeof(struct target_timeval),
2421 2707 &value.it_value);
2422 2708 }
2423 2709 }
2424 2710 break;
2425 2711 case TARGET_NR_stat:
2426   - ret = get_errno(stat(path((const char *)arg1), &st));
  2712 + p = lock_user_string(arg1);
  2713 + ret = get_errno(stat(path(p), &st));
  2714 + unlock_user(p, arg1, 0);
2427 2715 goto do_stat;
2428 2716 case TARGET_NR_lstat:
2429   - ret = get_errno(lstat(path((const char *)arg1), &st));
  2717 + p = lock_user_string(arg1);
  2718 + ret = get_errno(lstat(path(p), &st));
  2719 + unlock_user(p, arg1, 0);
2430 2720 goto do_stat;
2431 2721 case TARGET_NR_fstat:
2432 2722 {
2433 2723 ret = get_errno(fstat(arg1, &st));
2434 2724 do_stat:
2435 2725 if (!is_error(ret)) {
2436   - struct target_stat *target_st = (void *)arg2;
  2726 + struct target_stat *target_st;
  2727 +
  2728 + lock_user_struct(target_st, arg2, 0);
2437 2729 target_st->st_dev = tswap16(st.st_dev);
2438 2730 target_st->st_ino = tswapl(st.st_ino);
2439 2731 #if defined(TARGET_PPC)
... ... @@ -2453,6 +2745,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2453 2745 target_st->target_st_atime = tswapl(st.st_atime);
2454 2746 target_st->target_st_mtime = tswapl(st.st_mtime);
2455 2747 target_st->target_st_ctime = tswapl(st.st_ctime);
  2748 + unlock_user_struct(target_st, arg2, 1);
2456 2749 }
2457 2750 }
2458 2751 break;
... ... @@ -2479,9 +2772,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2479 2772 case TARGET_NR_wait4:
2480 2773 {
2481 2774 int status;
2482   - target_long *status_ptr = (void *)arg2;
  2775 + target_long status_ptr = arg2;
2483 2776 struct rusage rusage, *rusage_ptr;
2484   - struct target_rusage *target_rusage = (void *)arg4;
  2777 + target_ulong target_rusage = arg4;
2485 2778 if (target_rusage)
2486 2779 rusage_ptr = &rusage;
2487 2780 else
... ... @@ -2489,7 +2782,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2489 2782 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2490 2783 if (!is_error(ret)) {
2491 2784 if (status_ptr)
2492   - *status_ptr = tswap32(status);
  2785 + tputl(status_ptr, status);
2493 2786 if (target_rusage) {
2494 2787 host_to_target_rusage(target_rusage, &rusage);
2495 2788 }
... ... @@ -2497,15 +2790,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2497 2790 }
2498 2791 break;
2499 2792 case TARGET_NR_swapoff:
2500   - ret = get_errno(swapoff((const char *)arg1));
  2793 + p = lock_user_string(arg1);
  2794 + ret = get_errno(swapoff(p));
  2795 + unlock_user(p, arg1, 0);
2501 2796 break;
2502 2797 case TARGET_NR_sysinfo:
2503 2798 {
2504   - struct target_sysinfo *target_value = (void *)arg1;
  2799 + struct target_sysinfo *target_value;
2505 2800 struct sysinfo value;
2506 2801 ret = get_errno(sysinfo(&value));
2507   - if (!is_error(ret) && target_value)
  2802 + if (!is_error(ret) && arg1)
2508 2803 {
  2804 + /* ??? __put_user is probably wrong. */
  2805 + lock_user_struct(target_value, arg1, 0);
2509 2806 __put_user(value.uptime, &target_value->uptime);
2510 2807 __put_user(value.loads[0], &target_value->loads[0]);
2511 2808 __put_user(value.loads[1], &target_value->loads[1]);
... ... @@ -2520,6 +2817,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2520 2817 __put_user(value.totalhigh, &target_value->totalhigh);
2521 2818 __put_user(value.freehigh, &target_value->freehigh);
2522 2819 __put_user(value.mem_unit, &target_value->mem_unit);
  2820 + unlock_user_struct(target_value, arg1, 1);
2523 2821 }
2524 2822 }
2525 2823 break;
... ... @@ -2540,30 +2838,33 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2540 2838 break;
2541 2839 #endif
2542 2840 case TARGET_NR_setdomainname:
2543   - ret = get_errno(setdomainname((const char *)arg1, arg2));
  2841 + p = lock_user_string(arg1);
  2842 + ret = get_errno(setdomainname(p, arg2));
  2843 + unlock_user(p, arg1, 0);
2544 2844 break;
2545 2845 case TARGET_NR_uname:
2546 2846 /* no need to transcode because we use the linux syscall */
2547 2847 {
2548 2848 struct new_utsname * buf;
2549 2849  
2550   - buf = (struct new_utsname *)arg1;
  2850 + lock_user_struct(buf, arg1, 0);
2551 2851 ret = get_errno(sys_uname(buf));
2552 2852 if (!is_error(ret)) {
2553 2853 /* Overrite the native machine name with whatever is being
2554 2854 emulated. */
2555 2855 strcpy (buf->machine, UNAME_MACHINE);
2556 2856 }
  2857 + unlock_user_struct(buf, arg1, 1);
2557 2858 }
2558 2859 break;
2559 2860 #ifdef TARGET_I386
2560 2861 case TARGET_NR_modify_ldt:
2561   - ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
  2862 + ret = get_errno(do_modify_ldt(cpu_env, arg1, arg2, arg3));
2562 2863 break;
2563 2864 case TARGET_NR_vm86old:
2564 2865 goto unimplemented;
2565 2866 case TARGET_NR_vm86:
2566   - ret = do_vm86(cpu_env, arg1, (void *)arg2);
  2867 + ret = do_vm86(cpu_env, arg1, arg2);
2567 2868 break;
2568 2869 #endif
2569 2870 case TARGET_NR_adjtimex:
... ... @@ -2594,20 +2895,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2594 2895 {
2595 2896 #if defined (__x86_64__)
2596 2897 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2597   - *(int64_t *)arg4 = ret;
  2898 + tput64(arg4, ret);
2598 2899 #else
2599 2900 int64_t res;
2600 2901 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2601   - *(int64_t *)arg4 = tswap64(res);
  2902 + tput64(arg4, res);
2602 2903 #endif
2603 2904 }
2604 2905 break;
2605 2906 case TARGET_NR_getdents:
2606 2907 #if TARGET_LONG_SIZE != 4
  2908 + goto unimplemented;
2607 2909 #warning not supported
2608 2910 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
2609 2911 {
2610   - struct target_dirent *target_dirp = (void *)arg2;
  2912 + struct target_dirent *target_dirp;
2611 2913 struct dirent *dirp;
2612 2914 long count = arg3;
2613 2915  
... ... @@ -2625,6 +2927,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2625 2927  
2626 2928 count1 = 0;
2627 2929 de = dirp;
  2930 + target_dirp = lock_user(arg2, count, 0);
2628 2931 tde = target_dirp;
2629 2932 while (len > 0) {
2630 2933 reclen = de->d_reclen;
... ... @@ -2644,13 +2947,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2644 2947 }
2645 2948 ret = count1;
2646 2949 }
  2950 + unlock_user(target_dirp, arg2, ret);
2647 2951 free(dirp);
2648 2952 }
2649 2953 #else
2650 2954 {
2651   - struct dirent *dirp = (void *)arg2;
  2955 + struct dirent *dirp;
2652 2956 long count = arg3;
2653 2957  
  2958 + dirp = lock_user(arg2, count, 0);
2654 2959 ret = get_errno(sys_getdents(arg1, dirp, count));
2655 2960 if (!is_error(ret)) {
2656 2961 struct dirent *de;
... ... @@ -2668,14 +2973,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2668 2973 len -= reclen;
2669 2974 }
2670 2975 }
  2976 + unlock_user(dirp, arg2, ret);
2671 2977 }
2672 2978 #endif
2673 2979 break;
2674 2980 #ifdef TARGET_NR_getdents64
2675 2981 case TARGET_NR_getdents64:
2676 2982 {
2677   - struct dirent64 *dirp = (void *)arg2;
  2983 + struct dirent64 *dirp;
2678 2984 long count = arg3;
  2985 + dirp = lock_user(arg2, count, 0);
2679 2986 ret = get_errno(sys_getdents64(arg1, dirp, count));
2680 2987 if (!is_error(ret)) {
2681 2988 struct dirent64 *de;
... ... @@ -2693,21 +3000,22 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2693 3000 len -= reclen;
2694 3001 }
2695 3002 }
  3003 + unlock_user(dirp, arg2, ret);
2696 3004 }
2697 3005 break;
2698 3006 #endif /* TARGET_NR_getdents64 */
2699 3007 case TARGET_NR__newselect:
2700   - ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4,
2701   - (void *)arg5);
  3008 + ret = do_select(arg1, arg2, arg3, arg4, arg5);
2702 3009 break;
2703 3010 case TARGET_NR_poll:
2704 3011 {
2705   - struct target_pollfd *target_pfd = (void *)arg1;
  3012 + struct target_pollfd *target_pfd;
2706 3013 unsigned int nfds = arg2;
2707 3014 int timeout = arg3;
2708 3015 struct pollfd *pfd;
2709 3016 unsigned int i;
2710 3017  
  3018 + target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1);
2711 3019 pfd = alloca(sizeof(struct pollfd) * nfds);
2712 3020 for(i = 0; i < nfds; i++) {
2713 3021 pfd[i].fd = tswap32(target_pfd[i].fd);
... ... @@ -2718,7 +3026,10 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2718 3026 for(i = 0; i < nfds; i++) {
2719 3027 target_pfd[i].revents = tswap16(pfd[i].revents);
2720 3028 }
  3029 + ret += nfds * (sizeof(struct target_pollfd)
  3030 + - sizeof(struct pollfd));
2721 3031 }
  3032 + unlock_user(target_pfd, arg1, ret);
2722 3033 }
2723 3034 break;
2724 3035 case TARGET_NR_flock:
... ... @@ -2729,31 +3040,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2729 3040 case TARGET_NR_readv:
2730 3041 {
2731 3042 int count = arg3;
2732   - int i;
2733 3043 struct iovec *vec;
2734   - struct target_iovec *target_vec = (void *)arg2;
2735 3044  
2736 3045 vec = alloca(count * sizeof(struct iovec));
2737   - for(i = 0;i < count; i++) {
2738   - vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2739   - vec[i].iov_len = tswapl(target_vec[i].iov_len);
2740   - }
  3046 + lock_iovec(vec, arg2, count, 0);
2741 3047 ret = get_errno(readv(arg1, vec, count));
  3048 + unlock_iovec(vec, arg2, count, 1);
2742 3049 }
2743 3050 break;
2744 3051 case TARGET_NR_writev:
2745 3052 {
2746 3053 int count = arg3;
2747   - int i;
2748 3054 struct iovec *vec;
2749   - struct target_iovec *target_vec = (void *)arg2;
2750 3055  
2751 3056 vec = alloca(count * sizeof(struct iovec));
2752   - for(i = 0;i < count; i++) {
2753   - vec[i].iov_base = (void *)tswapl(target_vec[i].iov_base);
2754   - vec[i].iov_len = tswapl(target_vec[i].iov_len);
2755   - }
  3057 + lock_iovec(vec, arg2, count, 1);
2756 3058 ret = get_errno(writev(arg1, vec, count));
  3059 + unlock_iovec(vec, arg2, count, 0);
2757 3060 }
2758 3061 break;
2759 3062 case TARGET_NR_getsid:
... ... @@ -2768,27 +3071,34 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2768 3071 return -ENOTDIR;
2769 3072 case TARGET_NR_sched_setparam:
2770 3073 {
2771   - struct sched_param *target_schp = (void *)arg2;
  3074 + struct sched_param *target_schp;
2772 3075 struct sched_param schp;
  3076 +
  3077 + lock_user_struct(target_schp, arg2, 1);
2773 3078 schp.sched_priority = tswap32(target_schp->sched_priority);
  3079 + unlock_user_struct(target_schp, arg2, 0);
2774 3080 ret = get_errno(sched_setparam(arg1, &schp));
2775 3081 }
2776 3082 break;
2777 3083 case TARGET_NR_sched_getparam:
2778 3084 {
2779   - struct sched_param *target_schp = (void *)arg2;
  3085 + struct sched_param *target_schp;
2780 3086 struct sched_param schp;
2781 3087 ret = get_errno(sched_getparam(arg1, &schp));
2782 3088 if (!is_error(ret)) {
  3089 + lock_user_struct(target_schp, arg2, 0);
2783 3090 target_schp->sched_priority = tswap32(schp.sched_priority);
  3091 + unlock_user_struct(target_schp, arg2, 1);
2784 3092 }
2785 3093 }
2786 3094 break;
2787 3095 case TARGET_NR_sched_setscheduler:
2788 3096 {
2789   - struct sched_param *target_schp = (void *)arg3;
  3097 + struct sched_param *target_schp;
2790 3098 struct sched_param schp;
  3099 + lock_user_struct(target_schp, arg3, 1);
2791 3100 schp.sched_priority = tswap32(target_schp->sched_priority);
  3101 + unlock_user_struct(target_schp, arg3, 0);
2792 3102 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2793 3103 }
2794 3104 break;
... ... @@ -2806,26 +3116,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2806 3116 break;
2807 3117 case TARGET_NR_sched_rr_get_interval:
2808 3118 {
2809   - struct target_timespec *target_ts = (void *)arg2;
2810 3119 struct timespec ts;
2811 3120 ret = get_errno(sched_rr_get_interval(arg1, &ts));
2812 3121 if (!is_error(ret)) {
2813   - target_ts->tv_sec = tswapl(ts.tv_sec);
2814   - target_ts->tv_nsec = tswapl(ts.tv_nsec);
  3122 + host_to_target_timespec(arg2, &ts);
2815 3123 }
2816 3124 }
2817 3125 break;
2818 3126 case TARGET_NR_nanosleep:
2819 3127 {
2820   - struct target_timespec *target_req = (void *)arg1;
2821   - struct target_timespec *target_rem = (void *)arg2;
2822 3128 struct timespec req, rem;
2823   - req.tv_sec = tswapl(target_req->tv_sec);
2824   - req.tv_nsec = tswapl(target_req->tv_nsec);
  3129 + target_to_host_timespec(&req, arg1);
2825 3130 ret = get_errno(nanosleep(&req, &rem));
2826   - if (is_error(ret) && target_rem) {
2827   - target_rem->tv_sec = tswapl(rem.tv_sec);
2828   - target_rem->tv_nsec = tswapl(rem.tv_nsec);
  3131 + if (is_error(ret) && arg2) {
  3132 + host_to_target_timespec(arg2, &rem);
2829 3133 }
2830 3134 }
2831 3135 break;
... ... @@ -2837,15 +3141,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2837 3141 goto unimplemented;
2838 3142 #ifdef TARGET_NR_pread
2839 3143 case TARGET_NR_pread:
2840   - page_unprotect_range((void *)arg2, arg3);
2841   - ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
  3144 + page_unprotect_range(arg2, arg3);
  3145 + p = lock_user(arg2, arg3, 0);
  3146 + ret = get_errno(pread(arg1, p, arg3, arg4));
  3147 + unlock_user(p, arg2, ret);
2842 3148 break;
2843 3149 case TARGET_NR_pwrite:
2844   - ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
  3150 + p = lock_user(arg2, arg3, 1);
  3151 + ret = get_errno(pwrite(arg1, p, arg3, arg4));
  3152 + unlock_user(p, arg2, 0);
2845 3153 break;
2846 3154 #endif
2847 3155 case TARGET_NR_getcwd:
2848   - ret = get_errno(sys_getcwd1((char *)arg1, arg2));
  3156 + p = lock_user(arg1, arg2, 0);
  3157 + ret = get_errno(sys_getcwd1(p, arg2));
  3158 + unlock_user(p, arg1, ret);
2849 3159 break;
2850 3160 case TARGET_NR_capget:
2851 3161 goto unimplemented;
... ... @@ -2874,16 +3184,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2874 3184 struct rlimit rlim;
2875 3185 ret = get_errno(getrlimit(arg1, &rlim));
2876 3186 if (!is_error(ret)) {
2877   - struct target_rlimit *target_rlim = (void *)arg2;
  3187 + struct target_rlimit *target_rlim;
  3188 + lock_user_struct(target_rlim, arg2, 0);
2878 3189 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2879 3190 target_rlim->rlim_max = tswapl(rlim.rlim_max);
  3191 + unlock_user_struct(target_rlim, arg2, 1);
2880 3192 }
2881 3193 break;
2882 3194 }
2883 3195 #endif
2884 3196 #ifdef TARGET_NR_truncate64
2885 3197 case TARGET_NR_truncate64:
2886   - ret = target_truncate64(cpu_env, (const char *)arg1, arg2, arg3, arg4);
  3198 + p = lock_user_string(arg1);
  3199 + ret = target_truncate64(cpu_env, p, arg2, arg3, arg4);
  3200 + unlock_user(p, arg1, 0);
2887 3201 break;
2888 3202 #endif
2889 3203 #ifdef TARGET_NR_ftruncate64
... ... @@ -2893,12 +3207,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2893 3207 #endif
2894 3208 #ifdef TARGET_NR_stat64
2895 3209 case TARGET_NR_stat64:
2896   - ret = get_errno(stat(path((const char *)arg1), &st));
  3210 + p = lock_user_string(arg1);
  3211 + ret = get_errno(stat(path(p), &st));
  3212 + unlock_user(p, arg1, 0);
2897 3213 goto do_stat64;
2898 3214 #endif
2899 3215 #ifdef TARGET_NR_lstat64
2900 3216 case TARGET_NR_lstat64:
2901   - ret = get_errno(lstat(path((const char *)arg1), &st));
  3217 + p = lock_user_string(arg1);
  3218 + ret = get_errno(lstat(path(p), &st));
  3219 + unlock_user(p, arg1, 0);
2902 3220 goto do_stat64;
2903 3221 #endif
2904 3222 #ifdef TARGET_NR_fstat64
... ... @@ -2909,8 +3227,10 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2909 3227 if (!is_error(ret)) {
2910 3228 #ifdef TARGET_ARM
2911 3229 if (((CPUARMState *)cpu_env)->eabi) {
2912   - struct target_eabi_stat64 *target_st = (void *)arg2;
  3230 + struct target_eabi_stat64 *target_st;
  3231 + lock_user_struct(target_st, arg2, 1);
2913 3232 memset(target_st, 0, sizeof(struct target_eabi_stat64));
  3233 + /* put_user is probably wrong. */
2914 3234 put_user(st.st_dev, &target_st->st_dev);
2915 3235 put_user(st.st_ino, &target_st->st_ino);
2916 3236 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
... ... @@ -2928,11 +3248,14 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2928 3248 put_user(st.st_atime, &target_st->target_st_atime);
2929 3249 put_user(st.st_mtime, &target_st->target_st_mtime);
2930 3250 put_user(st.st_ctime, &target_st->target_st_ctime);
  3251 + unlock_user_struct(target_st, arg2, 0);
2931 3252 } else
2932 3253 #endif
2933 3254 {
2934   - struct target_stat64 *target_st = (void *)arg2;
  3255 + struct target_stat64 *target_st;
  3256 + lock_user_struct(target_st, arg2, 1);
2935 3257 memset(target_st, 0, sizeof(struct target_stat64));
  3258 + /* ??? put_user is probably wrong. */
2936 3259 put_user(st.st_dev, &target_st->st_dev);
2937 3260 put_user(st.st_ino, &target_st->st_ino);
2938 3261 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
... ... @@ -2950,6 +3273,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2950 3273 put_user(st.st_atime, &target_st->target_st_atime);
2951 3274 put_user(st.st_mtime, &target_st->target_st_mtime);
2952 3275 put_user(st.st_ctime, &target_st->target_st_ctime);
  3276 + unlock_user_struct(target_st, arg2, 0);
2953 3277 }
2954 3278 }
2955 3279 }
... ... @@ -2957,7 +3281,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2957 3281 #endif
2958 3282 #ifdef USE_UID16
2959 3283 case TARGET_NR_lchown:
2960   - ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
  3284 + p = lock_user_string(arg1);
  3285 + ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
  3286 + unlock_user(p, arg1, 0);
2961 3287 break;
2962 3288 case TARGET_NR_getuid:
2963 3289 ret = get_errno(high2lowuid(getuid()));
... ... @@ -2980,28 +3306,32 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2980 3306 case TARGET_NR_getgroups:
2981 3307 {
2982 3308 int gidsetsize = arg1;
2983   - uint16_t *target_grouplist = (void *)arg2;
  3309 + uint16_t *target_grouplist;
2984 3310 gid_t *grouplist;
2985 3311 int i;
2986 3312  
2987 3313 grouplist = alloca(gidsetsize * sizeof(gid_t));
2988 3314 ret = get_errno(getgroups(gidsetsize, grouplist));
2989 3315 if (!is_error(ret)) {
  3316 + target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
2990 3317 for(i = 0;i < gidsetsize; i++)
2991 3318 target_grouplist[i] = tswap16(grouplist[i]);
  3319 + unlock_user(target_grouplist, arg2, gidsetsize * 2);
2992 3320 }
2993 3321 }
2994 3322 break;
2995 3323 case TARGET_NR_setgroups:
2996 3324 {
2997 3325 int gidsetsize = arg1;
2998   - uint16_t *target_grouplist = (void *)arg2;
  3326 + uint16_t *target_grouplist;
2999 3327 gid_t *grouplist;
3000 3328 int i;
3001 3329  
3002 3330 grouplist = alloca(gidsetsize * sizeof(gid_t));
  3331 + target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
3003 3332 for(i = 0;i < gidsetsize; i++)
3004 3333 grouplist[i] = tswap16(target_grouplist[i]);
  3334 + unlock_user(target_grouplist, arg2, 0);
3005 3335 ret = get_errno(setgroups(gidsetsize, grouplist));
3006 3336 }
3007 3337 break;
... ... @@ -3018,12 +3348,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3018 3348 #ifdef TARGET_NR_getresuid
3019 3349 case TARGET_NR_getresuid:
3020 3350 {
3021   - int ruid, euid, suid;
  3351 + uid_t ruid, euid, suid;
3022 3352 ret = get_errno(getresuid(&ruid, &euid, &suid));
3023 3353 if (!is_error(ret)) {
3024   - *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
3025   - *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
3026   - *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
  3354 + tput16(arg1, tswap16(high2lowuid(ruid)));
  3355 + tput16(arg2, tswap16(high2lowuid(euid)));
  3356 + tput16(arg3, tswap16(high2lowuid(suid)));
3027 3357 }
3028 3358 }
3029 3359 break;
... ... @@ -3038,18 +3368,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3038 3368 #ifdef TARGET_NR_getresgid
3039 3369 case TARGET_NR_getresgid:
3040 3370 {
3041   - int rgid, egid, sgid;
  3371 + gid_t rgid, egid, sgid;
3042 3372 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3043 3373 if (!is_error(ret)) {
3044   - *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
3045   - *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
3046   - *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
  3374 + tput16(arg1, tswap16(high2lowgid(rgid)));
  3375 + tput16(arg2, tswap16(high2lowgid(egid)));
  3376 + tput16(arg3, tswap16(high2lowgid(sgid)));
3047 3377 }
3048 3378 }
3049 3379 break;
3050 3380 #endif
3051 3381 case TARGET_NR_chown:
3052   - ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
  3382 + p = lock_user_string(arg1);
  3383 + ret = get_errno(chown(p, low2highuid(arg2), low2highgid(arg3)));
  3384 + unlock_user(p, arg1, 0);
3053 3385 break;
3054 3386 case TARGET_NR_setuid:
3055 3387 ret = get_errno(setuid(low2highuid(arg1)));
... ... @@ -3067,7 +3399,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3067 3399  
3068 3400 #ifdef TARGET_NR_lchown32
3069 3401 case TARGET_NR_lchown32:
3070   - ret = get_errno(lchown((const char *)arg1, arg2, arg3));
  3402 + p = lock_user_string(arg1);
  3403 + ret = get_errno(lchown(p, arg2, arg3));
  3404 + unlock_user(p, arg1, 0);
3071 3405 break;
3072 3406 #endif
3073 3407 #ifdef TARGET_NR_getuid32
... ... @@ -3104,15 +3438,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3104 3438 case TARGET_NR_getgroups32:
3105 3439 {
3106 3440 int gidsetsize = arg1;
3107   - uint32_t *target_grouplist = (void *)arg2;
  3441 + uint32_t *target_grouplist;
3108 3442 gid_t *grouplist;
3109 3443 int i;
3110 3444  
3111 3445 grouplist = alloca(gidsetsize * sizeof(gid_t));
3112 3446 ret = get_errno(getgroups(gidsetsize, grouplist));
3113 3447 if (!is_error(ret)) {
  3448 + target_grouplist = lock_user(arg2, gidsetsize * 4, 0);
3114 3449 for(i = 0;i < gidsetsize; i++)
3115   - put_user(grouplist[i], &target_grouplist[i]);
  3450 + target_grouplist[i] = tswap32(grouplist[i]);
  3451 + unlock_user(target_grouplist, arg2, gidsetsize * 4);
3116 3452 }
3117 3453 }
3118 3454 break;
... ... @@ -3121,13 +3457,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3121 3457 case TARGET_NR_setgroups32:
3122 3458 {
3123 3459 int gidsetsize = arg1;
3124   - uint32_t *target_grouplist = (void *)arg2;
  3460 + uint32_t *target_grouplist;
3125 3461 gid_t *grouplist;
3126 3462 int i;
3127 3463  
3128 3464 grouplist = alloca(gidsetsize * sizeof(gid_t));
  3465 + target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
3129 3466 for(i = 0;i < gidsetsize; i++)
3130   - get_user(grouplist[i], &target_grouplist[i]);
  3467 + grouplist[i] = tswap32(target_grouplist[i]);
  3468 + unlock_user(target_grouplist, arg2, 0);
3131 3469 ret = get_errno(setgroups(gidsetsize, grouplist));
3132 3470 }
3133 3471 break;
... ... @@ -3145,12 +3483,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3145 3483 #ifdef TARGET_NR_getresuid32
3146 3484 case TARGET_NR_getresuid32:
3147 3485 {
3148   - int ruid, euid, suid;
  3486 + uid_t ruid, euid, suid;
3149 3487 ret = get_errno(getresuid(&ruid, &euid, &suid));
3150 3488 if (!is_error(ret)) {
3151   - *(uint32_t *)arg1 = tswap32(ruid);
3152   - *(uint32_t *)arg2 = tswap32(euid);
3153   - *(uint32_t *)arg3 = tswap32(suid);
  3489 + tput32(arg1, tswap32(ruid));
  3490 + tput32(arg2, tswap32(euid));
  3491 + tput32(arg3, tswap32(suid));
3154 3492 }
3155 3493 }
3156 3494 break;
... ... @@ -3163,19 +3501,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3163 3501 #ifdef TARGET_NR_getresgid32
3164 3502 case TARGET_NR_getresgid32:
3165 3503 {
3166   - int rgid, egid, sgid;
  3504 + gid_t rgid, egid, sgid;
3167 3505 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3168 3506 if (!is_error(ret)) {
3169   - *(uint32_t *)arg1 = tswap32(rgid);
3170   - *(uint32_t *)arg2 = tswap32(egid);
3171   - *(uint32_t *)arg3 = tswap32(sgid);
  3507 + tput32(arg1, tswap32(rgid));
  3508 + tput32(arg2, tswap32(egid));
  3509 + tput32(arg3, tswap32(sgid));
3172 3510 }
3173 3511 }
3174 3512 break;
3175 3513 #endif
3176 3514 #ifdef TARGET_NR_chown32
3177 3515 case TARGET_NR_chown32:
3178   - ret = get_errno(chown((const char *)arg1, arg2, arg3));
  3516 + p = lock_user_string(arg1);
  3517 + ret = get_errno(chown(p, arg2, arg3));
  3518 + unlock_user(p, arg1, 0);
3179 3519 break;
3180 3520 #endif
3181 3521 #ifdef TARGET_NR_setuid32
... ... @@ -3213,9 +3553,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3213 3553 case TARGET_NR_fcntl64:
3214 3554 {
3215 3555 struct flock64 fl;
3216   - struct target_flock64 *target_fl = (void *)arg3;
  3556 + struct target_flock64 *target_fl;
3217 3557 #ifdef TARGET_ARM
3218   - struct target_eabi_flock64 *target_efl = (void *)arg3;
  3558 + struct target_eabi_flock64 *target_efl;
3219 3559 #endif
3220 3560  
3221 3561 switch(arg2) {
... ... @@ -3224,19 +3564,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3224 3564 if (ret == 0) {
3225 3565 #ifdef TARGET_ARM
3226 3566 if (((CPUARMState *)cpu_env)->eabi) {
  3567 + lock_user_struct(target_efl, arg3, 0);
3227 3568 target_efl->l_type = tswap16(fl.l_type);
3228 3569 target_efl->l_whence = tswap16(fl.l_whence);
3229 3570 target_efl->l_start = tswap64(fl.l_start);
3230 3571 target_efl->l_len = tswap64(fl.l_len);
3231 3572 target_efl->l_pid = tswapl(fl.l_pid);
  3573 + unlock_user_struct(target_efl, arg3, 1);
3232 3574 } else
3233 3575 #endif
3234 3576 {
  3577 + lock_user_struct(target_fl, arg3, 0);
3235 3578 target_fl->l_type = tswap16(fl.l_type);
3236 3579 target_fl->l_whence = tswap16(fl.l_whence);
3237 3580 target_fl->l_start = tswap64(fl.l_start);
3238 3581 target_fl->l_len = tswap64(fl.l_len);
3239 3582 target_fl->l_pid = tswapl(fl.l_pid);
  3583 + unlock_user_struct(target_fl, arg3, 1);
3240 3584 }
3241 3585 }
3242 3586 break;
... ... @@ -3245,19 +3589,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3245 3589 case F_SETLKW64:
3246 3590 #ifdef TARGET_ARM
3247 3591 if (((CPUARMState *)cpu_env)->eabi) {
  3592 + lock_user_struct(target_efl, arg3, 1);
3248 3593 fl.l_type = tswap16(target_efl->l_type);
3249 3594 fl.l_whence = tswap16(target_efl->l_whence);
3250 3595 fl.l_start = tswap64(target_efl->l_start);
3251 3596 fl.l_len = tswap64(target_efl->l_len);
3252 3597 fl.l_pid = tswapl(target_efl->l_pid);
  3598 + unlock_user_struct(target_efl, arg3, 0);
3253 3599 } else
3254 3600 #endif
3255 3601 {
  3602 + lock_user_struct(target_fl, arg3, 1);
3256 3603 fl.l_type = tswap16(target_fl->l_type);
3257 3604 fl.l_whence = tswap16(target_fl->l_whence);
3258 3605 fl.l_start = tswap64(target_fl->l_start);
3259 3606 fl.l_len = tswap64(target_fl->l_len);
3260 3607 fl.l_pid = tswapl(target_fl->l_pid);
  3608 + unlock_user_struct(target_fl, arg3, 0);
3261 3609 }
3262 3610 ret = get_errno(fcntl(arg1, arg2, &fl));
3263 3611 break;
... ...
linux-user/syscall_types.h
... ... @@ -68,6 +68,9 @@ STRUCT(dirent,
68 68 STRUCT(kbentry,
69 69 TYPE_CHAR, TYPE_CHAR, TYPE_SHORT)
70 70  
  71 +STRUCT(kbsentry,
  72 + TYPE_CHAR, MK_ARRAY(TYPE_CHAR, 512))
  73 +
71 74 STRUCT(audio_buf_info,
72 75 TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT)
73 76  
... ...
linux-user/vm86.c
... ... @@ -62,25 +62,28 @@ static inline unsigned int vm_getl(uint8_t *segptr, unsigned int reg16)
62 62 void save_v86_state(CPUX86State *env)
63 63 {
64 64 TaskState *ts = env->opaque;
  65 + struct target_vm86plus_struct * target_v86;
65 66  
  67 + lock_user_struct(target_v86, ts->target_v86, 0);
66 68 /* put the VM86 registers in the userspace register structure */
67   - ts->target_v86->regs.eax = tswap32(env->regs[R_EAX]);
68   - ts->target_v86->regs.ebx = tswap32(env->regs[R_EBX]);
69   - ts->target_v86->regs.ecx = tswap32(env->regs[R_ECX]);
70   - ts->target_v86->regs.edx = tswap32(env->regs[R_EDX]);
71   - ts->target_v86->regs.esi = tswap32(env->regs[R_ESI]);
72   - ts->target_v86->regs.edi = tswap32(env->regs[R_EDI]);
73   - ts->target_v86->regs.ebp = tswap32(env->regs[R_EBP]);
74   - ts->target_v86->regs.esp = tswap32(env->regs[R_ESP]);
75   - ts->target_v86->regs.eip = tswap32(env->eip);
76   - ts->target_v86->regs.cs = tswap16(env->segs[R_CS].selector);
77   - ts->target_v86->regs.ss = tswap16(env->segs[R_SS].selector);
78   - ts->target_v86->regs.ds = tswap16(env->segs[R_DS].selector);
79   - ts->target_v86->regs.es = tswap16(env->segs[R_ES].selector);
80   - ts->target_v86->regs.fs = tswap16(env->segs[R_FS].selector);
81   - ts->target_v86->regs.gs = tswap16(env->segs[R_GS].selector);
  69 + target_v86->regs.eax = tswap32(env->regs[R_EAX]);
  70 + target_v86->regs.ebx = tswap32(env->regs[R_EBX]);
  71 + target_v86->regs.ecx = tswap32(env->regs[R_ECX]);
  72 + target_v86->regs.edx = tswap32(env->regs[R_EDX]);
  73 + target_v86->regs.esi = tswap32(env->regs[R_ESI]);
  74 + target_v86->regs.edi = tswap32(env->regs[R_EDI]);
  75 + target_v86->regs.ebp = tswap32(env->regs[R_EBP]);
  76 + target_v86->regs.esp = tswap32(env->regs[R_ESP]);
  77 + target_v86->regs.eip = tswap32(env->eip);
  78 + target_v86->regs.cs = tswap16(env->segs[R_CS].selector);
  79 + target_v86->regs.ss = tswap16(env->segs[R_SS].selector);
  80 + target_v86->regs.ds = tswap16(env->segs[R_DS].selector);
  81 + target_v86->regs.es = tswap16(env->segs[R_ES].selector);
  82 + target_v86->regs.fs = tswap16(env->segs[R_FS].selector);
  83 + target_v86->regs.gs = tswap16(env->segs[R_GS].selector);
82 84 set_flags(env->eflags, ts->v86flags, VIF_MASK | ts->v86mask);
83   - ts->target_v86->regs.eflags = tswap32(env->eflags);
  85 + target_v86->regs.eflags = tswap32(env->eflags);
  86 + unlock_user_struct(target_v86, ts->target_v86, 1);
84 87 #ifdef DEBUG_VM86
85 88 fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",
86 89 env->eflags, env->segs[R_CS].selector, env->eip);
... ... @@ -378,10 +381,10 @@ void handle_vm86_fault(CPUX86State *env)
378 381 }
379 382 }
380 383  
381   -int do_vm86(CPUX86State *env, long subfunction,
382   - struct target_vm86plus_struct * target_v86)
  384 +int do_vm86(CPUX86State *env, long subfunction, target_ulong vm86_addr)
383 385 {
384 386 TaskState *ts = env->opaque;
  387 + struct target_vm86plus_struct * target_v86;
385 388 int ret;
386 389  
387 390 switch (subfunction) {
... ... @@ -402,7 +405,6 @@ int do_vm86(CPUX86State *env, long subfunction,
402 405 goto out;
403 406 }
404 407  
405   - ts->target_v86 = target_v86;
406 408 /* save current CPU regs */
407 409 ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */
408 410 ts->vm86_saved_regs.ebx = env->regs[R_EBX];
... ... @@ -421,6 +423,8 @@ int do_vm86(CPUX86State *env, long subfunction,
421 423 ts->vm86_saved_regs.fs = env->segs[R_FS].selector;
422 424 ts->vm86_saved_regs.gs = env->segs[R_GS].selector;
423 425  
  426 + ts->target_v86 = vm86_addr;
  427 + lock_user_struct(target_v86, vm86_addr, 1);
424 428 /* build vm86 CPU state */
425 429 ts->v86flags = tswap32(target_v86->regs.eflags);
426 430 env->eflags = (env->eflags & ~SAFE_MASK) |
... ... @@ -465,6 +469,7 @@ int do_vm86(CPUX86State *env, long subfunction,
465 469 ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);
466 470 memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
467 471 target_v86->vm86plus.vm86dbg_intxxtab, 32);
  472 + unlock_user_struct(target_v86, vm86_addr, 0);
468 473  
469 474 #ifdef DEBUG_VM86
470 475 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",
... ...
target-arm/nwfpe/fpa11_cpdt.c
... ... @@ -31,48 +31,52 @@
31 31 static inline
32 32 void loadSingle(const unsigned int Fn,const unsigned int *pMem)
33 33 {
  34 + target_ulong addr = (target_ulong)(long)pMem;
34 35 FPA11 *fpa11 = GET_FPA11();
35 36 fpa11->fType[Fn] = typeSingle;
36   - get_user(fpa11->fpreg[Fn].fSingle, pMem);
  37 + fpa11->fpreg[Fn].fSingle = tget32(addr);
37 38 }
38 39  
39 40 static inline
40 41 void loadDouble(const unsigned int Fn,const unsigned int *pMem)
41 42 {
  43 + target_ulong addr = (target_ulong)(long)pMem;
42 44 FPA11 *fpa11 = GET_FPA11();
43 45 unsigned int *p;
44 46 p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
45 47 fpa11->fType[Fn] = typeDouble;
46 48 #ifdef WORDS_BIGENDIAN
47   - get_user(p[0], &pMem[0]); /* sign & exponent */
48   - get_user(p[1], &pMem[1]);
  49 + p[0] = tget32(addr); /* sign & exponent */
  50 + p[1] = tget32(addr + 4);
49 51 #else
50   - get_user(p[0], &pMem[1]);
51   - get_user(p[1], &pMem[0]); /* sign & exponent */
  52 + p[0] = tget32(addr + 4);
  53 + p[1] = tget32(addr); /* sign & exponent */
52 54 #endif
53 55 }
54 56  
55 57 static inline
56 58 void loadExtended(const unsigned int Fn,const unsigned int *pMem)
57 59 {
  60 + target_ulong addr = (target_ulong)(long)pMem;
58 61 FPA11 *fpa11 = GET_FPA11();
59 62 unsigned int *p;
60 63 p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
61 64 fpa11->fType[Fn] = typeExtended;
62   - get_user(p[0], &pMem[0]); /* sign & exponent */
63   - get_user(p[1], &pMem[2]); /* ls bits */
64   - get_user(p[2], &pMem[1]); /* ms bits */
  65 + p[0] = tget32(addr); /* sign & exponent */
  66 + p[1] = tget32(addr + 8); /* ls bits */
  67 + p[2] = tget32(addr + 4); /* ms bits */
65 68 }
66 69  
67 70 static inline
68 71 void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
69 72 {
  73 + target_ulong addr = (target_ulong)(long)pMem;
70 74 FPA11 *fpa11 = GET_FPA11();
71 75 register unsigned int *p;
72 76 unsigned long x;
73 77  
74 78 p = (unsigned int*)&(fpa11->fpreg[Fn]);
75   - get_user(x, &pMem[0]);
  79 + x = tget32(addr);
76 80 fpa11->fType[Fn] = (x >> 14) & 0x00000003;
77 81  
78 82 switch (fpa11->fType[Fn])
... ... @@ -80,16 +84,16 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
80 84 case typeSingle:
81 85 case typeDouble:
82 86 {
83   - get_user(p[0], &pMem[2]); /* Single */
84   - get_user(p[1], &pMem[1]); /* double msw */
  87 + p[0] = tget32(addr + 8); /* Single */
  88 + p[1] = tget32(addr + 4); /* double msw */
85 89 p[2] = 0; /* empty */
86 90 }
87 91 break;
88 92  
89 93 case typeExtended:
90 94 {
91   - get_user(p[1], &pMem[2]);
92   - get_user(p[2], &pMem[1]); /* msw */
  95 + p[1] = tget32(addr + 8);
  96 + p[2] = tget32(addr + 4); /* msw */
93 97 p[0] = (x & 0x80003fff);
94 98 }
95 99 break;
... ... @@ -99,6 +103,7 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
99 103 static inline
100 104 void storeSingle(const unsigned int Fn,unsigned int *pMem)
101 105 {
  106 + target_ulong addr = (target_ulong)(long)pMem;
102 107 FPA11 *fpa11 = GET_FPA11();
103 108 float32 val;
104 109 register unsigned int *p = (unsigned int*)&val;
... ... @@ -116,12 +121,13 @@ void storeSingle(const unsigned int Fn,unsigned int *pMem)
116 121 default: val = fpa11->fpreg[Fn].fSingle;
117 122 }
118 123  
119   - put_user(p[0], pMem);
  124 + tput32(addr, p[0]);
120 125 }
121 126  
122 127 static inline
123 128 void storeDouble(const unsigned int Fn,unsigned int *pMem)
124 129 {
  130 + target_ulong addr = (target_ulong)(long)pMem;
125 131 FPA11 *fpa11 = GET_FPA11();
126 132 float64 val;
127 133 register unsigned int *p = (unsigned int*)&val;
... ... @@ -139,17 +145,18 @@ void storeDouble(const unsigned int Fn,unsigned int *pMem)
139 145 default: val = fpa11->fpreg[Fn].fDouble;
140 146 }
141 147 #ifdef WORDS_BIGENDIAN
142   - put_user(p[0], &pMem[0]); /* msw */
143   - put_user(p[1], &pMem[1]); /* lsw */
  148 + tput32(addr, p[0]); /* msw */
  149 + tput32(addr + 4, p[1]); /* lsw */
144 150 #else
145   - put_user(p[1], &pMem[0]); /* msw */
146   - put_user(p[0], &pMem[1]); /* lsw */
  151 + tput32(addr, p[1]); /* msw */
  152 + tput32(addr + 4, p[0]); /* lsw */
147 153 #endif
148 154 }
149 155  
150 156 static inline
151 157 void storeExtended(const unsigned int Fn,unsigned int *pMem)
152 158 {
  159 + target_ulong addr = (target_ulong)(long)pMem;
153 160 FPA11 *fpa11 = GET_FPA11();
154 161 floatx80 val;
155 162 register unsigned int *p = (unsigned int*)&val;
... ... @@ -167,14 +174,15 @@ void storeExtended(const unsigned int Fn,unsigned int *pMem)
167 174 default: val = fpa11->fpreg[Fn].fExtended;
168 175 }
169 176  
170   - put_user(p[0], &pMem[0]); /* sign & exp */
171   - put_user(p[1], &pMem[2]);
172   - put_user(p[2], &pMem[1]); /* msw */
  177 + tput32(addr, p[0]); /* sign & exp */
  178 + tput32(addr + 8, p[1]);
  179 + tput32(addr + 4, p[2]); /* msw */
173 180 }
174 181  
175 182 static inline
176 183 void storeMultiple(const unsigned int Fn,unsigned int *pMem)
177 184 {
  185 + target_ulong addr = (target_ulong)(long)pMem;
178 186 FPA11 *fpa11 = GET_FPA11();
179 187 register unsigned int nType, *p;
180 188  
... ... @@ -186,17 +194,17 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem)
186 194 case typeSingle:
187 195 case typeDouble:
188 196 {
189   - put_user(p[0], &pMem[2]); /* single */
190   - put_user(p[1], &pMem[1]); /* double msw */
191   - put_user(nType << 14, &pMem[0]);
  197 + tput32(addr + 8, p[0]); /* single */
  198 + tput32(addr + 4, p[1]); /* double msw */
  199 + tput32(addr, nType << 14);
192 200 }
193 201 break;
194 202  
195 203 case typeExtended:
196 204 {
197   - put_user(p[2], &pMem[1]); /* msw */
198   - put_user(p[1], &pMem[2]);
199   - put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
  205 + tput32(addr + 4, p[2]); /* msw */
  206 + tput32(addr + 8, p[1]);
  207 + tput32(addr, (p[0] & 0x80003fff) | (nType << 14));
200 208 }
201 209 break;
202 210 }
... ...