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,22 +584,41 @@ static inline void stfq_be_p(void *ptr, float64 v)
584 584
585 /* MMU memory access macros */ 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 /* NOTE: we use double casts if pointers and target_ulong have 602 /* NOTE: we use double casts if pointers and target_ulong have
588 different sizes */ 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 #if defined(CONFIG_USER_ONLY) 624 #if defined(CONFIG_USER_ONLY)
@@ -648,6 +667,7 @@ static inline void stfq_be_p(void *ptr, float64 v) @@ -648,6 +667,7 @@ static inline void stfq_be_p(void *ptr, float64 v)
648 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) 667 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
649 #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) 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 extern unsigned long qemu_real_host_page_size; 671 extern unsigned long qemu_real_host_page_size;
652 extern unsigned long qemu_host_page_bits; 672 extern unsigned long qemu_host_page_bits;
653 extern unsigned long qemu_host_page_size; 673 extern unsigned long qemu_host_page_size;
@@ -666,9 +686,9 @@ extern unsigned long qemu_host_page_mask; @@ -666,9 +686,9 @@ extern unsigned long qemu_host_page_mask;
666 #define PAGE_WRITE_ORG 0x0010 686 #define PAGE_WRITE_ORG 0x0010
667 687
668 void page_dump(FILE *f); 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 #define SINGLE_CPU_DEFINES 693 #define SINGLE_CPU_DEFINES
674 #ifdef SINGLE_CPU_DEFINES 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,7 +913,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
913 pc, address, is_write, *(unsigned long *)old_set); 913 pc, address, is_write, *(unsigned long *)old_set);
914 #endif 914 #endif
915 /* XXX: locking issue */ 915 /* XXX: locking issue */
916 - if (is_write && page_unprotect(address, pc, puc)) { 916 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
917 return 1; 917 return 1;
918 } 918 }
919 919
@@ -964,7 +964,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -964,7 +964,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
964 pc, address, is_write, *(unsigned long *)old_set); 964 pc, address, is_write, *(unsigned long *)old_set);
965 #endif 965 #endif
966 /* XXX: locking issue */ 966 /* XXX: locking issue */
967 - if (is_write && page_unprotect(address, pc, puc)) { 967 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
968 return 1; 968 return 1;
969 } 969 }
970 /* see if it is an MMU fault */ 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,7 +1000,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1000 pc, address, is_write, *(unsigned long *)old_set); 1000 pc, address, is_write, *(unsigned long *)old_set);
1001 #endif 1001 #endif
1002 /* XXX: locking issue */ 1002 /* XXX: locking issue */
1003 - if (is_write && page_unprotect(address, pc, puc)) { 1003 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1004 return 1; 1004 return 1;
1005 } 1005 }
1006 /* see if it is an MMU fault */ 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,7 +1036,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1036 pc, address, is_write, *(unsigned long *)old_set); 1036 pc, address, is_write, *(unsigned long *)old_set);
1037 #endif 1037 #endif
1038 /* XXX: locking issue */ 1038 /* XXX: locking issue */
1039 - if (is_write && page_unprotect(address, pc, puc)) { 1039 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1040 return 1; 1040 return 1;
1041 } 1041 }
1042 1042
@@ -1086,7 +1086,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1086,7 +1086,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1086 pc, address, is_write, *(unsigned long *)old_set); 1086 pc, address, is_write, *(unsigned long *)old_set);
1087 #endif 1087 #endif
1088 /* XXX: locking issue */ 1088 /* XXX: locking issue */
1089 - if (is_write && page_unprotect(address, pc, puc)) { 1089 + if (is_write && page_unprotect(h2g(address), pc, puc)) {
1090 return 1; 1090 return 1;
1091 } 1091 }
1092 1092
exec-all.h
@@ -93,7 +93,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb, @@ -93,7 +93,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb,
93 void *puc); 93 void *puc);
94 void cpu_resume_from_signal(CPUState *env1, void *puc); 94 void cpu_resume_from_signal(CPUState *env1, void *puc);
95 void cpu_exec_init(CPUState *env); 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 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 97 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
98 int is_cpu_write_access); 98 int is_cpu_write_access);
99 void tb_invalidate_page_range(target_ulong start, target_ulong end); 99 void tb_invalidate_page_range(target_ulong start, target_ulong end);
@@ -34,6 +34,9 @@ @@ -34,6 +34,9 @@
34 34
35 #include "cpu.h" 35 #include "cpu.h"
36 #include "exec-all.h" 36 #include "exec-all.h"
  37 +#if defined(CONFIG_USER_ONLY)
  38 +#include <qemu.h>
  39 +#endif
37 40
38 //#define DEBUG_TB_INVALIDATE 41 //#define DEBUG_TB_INVALIDATE
39 //#define DEBUG_FLUSH 42 //#define DEBUG_FLUSH
@@ -810,7 +813,7 @@ static void tb_invalidate_phys_page(target_ulong addr, @@ -810,7 +813,7 @@ static void tb_invalidate_phys_page(target_ulong addr,
810 813
811 /* add the tb in the target page and protect it if necessary */ 814 /* add the tb in the target page and protect it if necessary */
812 static inline void tb_alloc_page(TranslationBlock *tb, 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 PageDesc *p; 818 PageDesc *p;
816 TranslationBlock *last_first_tb; 819 TranslationBlock *last_first_tb;
@@ -826,23 +829,30 @@ static inline void tb_alloc_page(TranslationBlock *tb, @@ -826,23 +829,30 @@ static inline void tb_alloc_page(TranslationBlock *tb,
826 829
827 #if defined(CONFIG_USER_ONLY) 830 #if defined(CONFIG_USER_ONLY)
828 if (p->flags & PAGE_WRITE) { 831 if (p->flags & PAGE_WRITE) {
829 - unsigned long host_start, host_end, addr; 832 + target_ulong addr;
  833 + PageDesc *p2;
830 int prot; 834 int prot;
831 835
832 /* force the host page as non writable (writes will have a 836 /* force the host page as non writable (writes will have a
833 page fault + mprotect overhead) */ 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 prot = 0; 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 (prot & PAGE_BITS) & ~PAGE_WRITE); 851 (prot & PAGE_BITS) & ~PAGE_WRITE);
841 #ifdef DEBUG_TB_INVALIDATE 852 #ifdef DEBUG_TB_INVALIDATE
842 printf("protecting code page: 0x%08lx\n", 853 printf("protecting code page: 0x%08lx\n",
843 - host_start); 854 + page_addr);
844 #endif 855 #endif
845 - p->flags &= ~PAGE_WRITE;  
846 } 856 }
847 #else 857 #else
848 /* if some code is already present, then the pages are already 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,7 +1556,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1546 1556
1547 /* called from signal handler: invalidate the code and unprotect the 1557 /* called from signal handler: invalidate the code and unprotect the
1548 page. Return TRUE if the fault was succesfully handled. */ 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 #if !defined(CONFIG_SOFTMMU) 1561 #if !defined(CONFIG_SOFTMMU)
1552 VirtPageDesc *vp; 1562 VirtPageDesc *vp;
@@ -1645,7 +1655,7 @@ void page_dump(FILE *f) @@ -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 PageDesc *p; 1660 PageDesc *p;
1651 1661
@@ -1658,10 +1668,10 @@ int page_get_flags(unsigned long address) @@ -1658,10 +1668,10 @@ int page_get_flags(unsigned long address)
1658 /* modify the flags of a page and invalidate the code if 1668 /* modify the flags of a page and invalidate the code if
1659 necessary. The flag PAGE_WRITE_ORG is positionned automatically 1669 necessary. The flag PAGE_WRITE_ORG is positionned automatically
1660 depending on PAGE_WRITE */ 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 PageDesc *p; 1673 PageDesc *p;
1664 - unsigned long addr; 1674 + target_ulong addr;
1665 1675
1666 start = start & TARGET_PAGE_MASK; 1676 start = start & TARGET_PAGE_MASK;
1667 end = TARGET_PAGE_ALIGN(end); 1677 end = TARGET_PAGE_ALIGN(end);
@@ -1684,11 +1694,11 @@ void page_set_flags(unsigned long start, unsigned long end, int flags) @@ -1684,11 +1694,11 @@ void page_set_flags(unsigned long start, unsigned long end, int flags)
1684 1694
1685 /* called from signal handler: invalidate the code and unprotect the 1695 /* called from signal handler: invalidate the code and unprotect the
1686 page. Return TRUE if the fault was succesfully handled. */ 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 unsigned int page_index, prot, pindex; 1699 unsigned int page_index, prot, pindex;
1690 PageDesc *p, *p1; 1700 PageDesc *p, *p1;
1691 - unsigned long host_start, host_end, addr; 1701 + target_ulong host_start, host_end, addr;
1692 1702
1693 host_start = address & qemu_host_page_mask; 1703 host_start = address & qemu_host_page_mask;
1694 page_index = host_start >> TARGET_PAGE_BITS; 1704 page_index = host_start >> TARGET_PAGE_BITS;
@@ -1707,7 +1717,7 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc) @@ -1707,7 +1717,7 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
1707 if (prot & PAGE_WRITE_ORG) { 1717 if (prot & PAGE_WRITE_ORG) {
1708 pindex = (address - host_start) >> TARGET_PAGE_BITS; 1718 pindex = (address - host_start) >> TARGET_PAGE_BITS;
1709 if (!(p1[pindex].flags & PAGE_WRITE)) { 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 (prot & PAGE_BITS) | PAGE_WRITE); 1721 (prot & PAGE_BITS) | PAGE_WRITE);
1712 p1[pindex].flags |= PAGE_WRITE; 1722 p1[pindex].flags |= PAGE_WRITE;
1713 /* and since the content will be modified, we must invalidate 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,11 +1733,12 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
1723 } 1733 }
1724 1734
1725 /* call this function when system calls directly modify a memory area */ 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 end = start + data_size; 1742 end = start + data_size;
1732 start &= TARGET_PAGE_MASK; 1743 start &= TARGET_PAGE_MASK;
1733 end = TARGET_PAGE_ALIGN(end); 1744 end = TARGET_PAGE_ALIGN(end);
@@ -1932,6 +1943,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, @@ -1932,6 +1943,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1932 { 1943 {
1933 int l, flags; 1944 int l, flags;
1934 target_ulong page; 1945 target_ulong page;
  1946 + void * p;
1935 1947
1936 while (len > 0) { 1948 while (len > 0) {
1937 page = addr & TARGET_PAGE_MASK; 1949 page = addr & TARGET_PAGE_MASK;
@@ -1944,11 +1956,15 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, @@ -1944,11 +1956,15 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1944 if (is_write) { 1956 if (is_write) {
1945 if (!(flags & PAGE_WRITE)) 1957 if (!(flags & PAGE_WRITE))
1946 return; 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 } else { 1962 } else {
1949 if (!(flags & PAGE_READ)) 1963 if (!(flags & PAGE_READ))
1950 return; 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 len -= l; 1969 len -= l;
1954 buf += l; 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,20 +77,20 @@ static inline uint32_t set_swi_errno(TaskState *ts, uint32_t code)
77 return code; 77 return code;
78 } 78 }
79 79
80 -#define ARG(x) tswap32(args[x]) 80 +#define ARG(n) tget32(args + n * 4)
81 uint32_t do_arm_semihosting(CPUState *env) 81 uint32_t do_arm_semihosting(CPUState *env)
82 { 82 {
83 - uint32_t *args; 83 + target_ulong args;
84 char * s; 84 char * s;
85 int nr; 85 int nr;
86 uint32_t ret; 86 uint32_t ret;
87 TaskState *ts = env->opaque; 87 TaskState *ts = env->opaque;
88 88
89 nr = env->regs[0]; 89 nr = env->regs[0];
90 - args = (uint32_t *)env->regs[1]; 90 + args = env->regs[1];
91 switch (nr) { 91 switch (nr) {
92 case SYS_OPEN: 92 case SYS_OPEN:
93 - s = (char *)ARG(0); 93 + s = (char *)g2h(ARG(0));
94 if (ARG(1) >= 12) 94 if (ARG(1) >= 12)
95 return (uint32_t)-1; 95 return (uint32_t)-1;
96 if (strcmp(s, ":tt") == 0) { 96 if (strcmp(s, ":tt") == 0) {
@@ -103,18 +103,23 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -103,18 +103,23 @@ uint32_t do_arm_semihosting(CPUState *env)
103 case SYS_CLOSE: 103 case SYS_CLOSE:
104 return set_swi_errno(ts, close(ARG(0))); 104 return set_swi_errno(ts, close(ARG(0)));
105 case SYS_WRITEC: 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 case SYS_WRITE0: 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 case SYS_WRITE: 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 if (ret == (uint32_t)-1) 118 if (ret == (uint32_t)-1)
114 return -1; 119 return -1;
115 return ARG(2) - ret; 120 return ARG(2) - ret;
116 case SYS_READ: 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 if (ret == (uint32_t)-1) 123 if (ret == (uint32_t)-1)
119 return -1; 124 return -1;
120 return ARG(2) - ret; 125 return ARG(2) - ret;
@@ -140,20 +145,21 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -140,20 +145,21 @@ uint32_t do_arm_semihosting(CPUState *env)
140 /* XXX: Not implemented. */ 145 /* XXX: Not implemented. */
141 return -1; 146 return -1;
142 case SYS_REMOVE: 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 case SYS_RENAME: 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 case SYS_CLOCK: 152 case SYS_CLOCK:
147 return clock() / (CLOCKS_PER_SEC / 100); 153 return clock() / (CLOCKS_PER_SEC / 100);
148 case SYS_TIME: 154 case SYS_TIME:
149 return set_swi_errno(ts, time(NULL)); 155 return set_swi_errno(ts, time(NULL));
150 case SYS_SYSTEM: 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 case SYS_ERRNO: 158 case SYS_ERRNO:
153 return ts->swi_errno; 159 return ts->swi_errno;
154 case SYS_GET_CMDLINE: 160 case SYS_GET_CMDLINE:
155 /* XXX: Not implemented. */ 161 /* XXX: Not implemented. */
156 - s = (char *)ARG(0); 162 + s = (char *)g2h(ARG(0));
157 *s = 0; 163 *s = 0;
158 return -1; 164 return -1;
159 case SYS_HEAPINFO: 165 case SYS_HEAPINFO:
@@ -166,11 +172,11 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -166,11 +172,11 @@ uint32_t do_arm_semihosting(CPUState *env)
166 if (!ts->heap_limit) { 172 if (!ts->heap_limit) {
167 long ret; 173 long ret;
168 174
169 - ts->heap_base = do_brk(NULL); 175 + ts->heap_base = do_brk(0);
170 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE; 176 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
171 /* Try a big heap, and reduce the size if that fails. */ 177 /* Try a big heap, and reduce the size if that fails. */
172 for (;;) { 178 for (;;) {
173 - ret = do_brk((char *)limit); 179 + ret = do_brk(limit);
174 if (ret != -1) 180 if (ret != -1)
175 break; 181 break;
176 limit = (ts->heap_base >> 1) + (limit >> 1); 182 limit = (ts->heap_base >> 1) + (limit >> 1);
@@ -178,7 +184,8 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -178,7 +184,8 @@ uint32_t do_arm_semihosting(CPUState *env)
178 ts->heap_limit = limit; 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 ptr[0] = tswap32(ts->heap_base); 189 ptr[0] = tswap32(ts->heap_base);
183 ptr[1] = tswap32(ts->heap_limit); 190 ptr[1] = tswap32(ts->heap_limit);
184 ptr[2] = tswap32(ts->stack_base); 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,17 +97,17 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
97 97
98 static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) 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 memset(regs, 0, sizeof(*regs)); 101 memset(regs, 0, sizeof(*regs));
102 regs->ARM_cpsr = 0x10; 102 regs->ARM_cpsr = 0x10;
103 if (infop->entry & 1) 103 if (infop->entry & 1)
104 regs->ARM_cpsr |= CPSR_T; 104 regs->ARM_cpsr |= CPSR_T;
105 regs->ARM_pc = infop->entry & 0xfffffffe; 105 regs->ARM_pc = infop->entry & 0xfffffffe;
106 regs->ARM_sp = infop->start_stack; 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 /* XXX: it seems that r0 is zeroed after ! */ 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 #define USE_ELF_CORE_DUMP 113 #define USE_ELF_CORE_DUMP
@@ -202,7 +202,7 @@ do { \ @@ -202,7 +202,7 @@ do { \
202 _r->gpr[3] = bprm->argc; \ 202 _r->gpr[3] = bprm->argc; \
203 _r->gpr[4] = (unsigned long)++pos; \ 203 _r->gpr[4] = (unsigned long)++pos; \
204 for (; tmp != 0; pos++) \ 204 for (; tmp != 0; pos++) \
205 - tmp = *pos; \ 205 + tmp = ldl(pos); \
206 _r->gpr[5] = (unsigned long)pos; \ 206 _r->gpr[5] = (unsigned long)pos; \
207 } while (0) 207 } while (0)
208 208
@@ -297,7 +297,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i @@ -297,7 +297,7 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
297 */ 297 */
298 struct linux_binprm { 298 struct linux_binprm {
299 char buf[128]; 299 char buf[128];
300 - unsigned long page[MAX_ARG_PAGES]; 300 + void *page[MAX_ARG_PAGES];
301 unsigned long p; 301 unsigned long p;
302 int sh_bang; 302 int sh_bang;
303 int fd; 303 int fd;
@@ -427,37 +427,13 @@ static void bswap_sym(Elf32_Sym *sym) @@ -427,37 +427,13 @@ static void bswap_sym(Elf32_Sym *sym)
427 } 427 }
428 #endif 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 * 'copy_string()' copies argument/envelope strings from user 431 * 'copy_string()' copies argument/envelope strings from user
456 * memory to free pages in kernel mem. These are in a format ready 432 * memory to free pages in kernel mem. These are in a format ready
457 * to be put directly into the top of new user memory. 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 unsigned long p) 437 unsigned long p)
462 { 438 {
463 char *tmp, *tmp1, *pag = NULL; 439 char *tmp, *tmp1, *pag = NULL;
@@ -482,10 +458,10 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page, @@ -482,10 +458,10 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
482 --p; --tmp; --len; 458 --p; --tmp; --len;
483 if (--offset < 0) { 459 if (--offset < 0) {
484 offset = p % TARGET_PAGE_SIZE; 460 offset = p % TARGET_PAGE_SIZE;
485 - pag = (char *) page[p/TARGET_PAGE_SIZE]; 461 + pag = (char *)page[p/TARGET_PAGE_SIZE];
486 if (!pag) { 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 if (!pag) 465 if (!pag)
490 return 0; 466 return 0;
491 } 467 }
@@ -591,10 +567,20 @@ static int prepare_binprm(struct linux_binprm *bprm) @@ -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 int i; 584 int i;
599 585
600 /* Create enough stack to hold everything. If we don't use 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,10 +613,10 @@ unsigned long setup_arg_pages(unsigned long p, struct linux_binprm * bprm,
627 if (bprm->page[i]) { 613 if (bprm->page[i]) {
628 info->rss++; 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 return p; 621 return p;
636 } 622 }
@@ -657,7 +643,6 @@ static void set_brk(unsigned long start, unsigned long end) @@ -657,7 +643,6 @@ static void set_brk(unsigned long start, unsigned long end)
657 static void padzero(unsigned long elf_bss) 643 static void padzero(unsigned long elf_bss)
658 { 644 {
659 unsigned long nbyte; 645 unsigned long nbyte;
660 - char * fpnt;  
661 646
662 /* XXX: this is really a hack : if the real host page size is 647 /* XXX: this is really a hack : if the real host page size is
663 smaller than the target page size, some pages after the end 648 smaller than the target page size, some pages after the end
@@ -679,55 +664,57 @@ static void padzero(unsigned long elf_bss) @@ -679,55 +664,57 @@ static void padzero(unsigned long elf_bss)
679 nbyte = elf_bss & (qemu_host_page_size-1); 664 nbyte = elf_bss & (qemu_host_page_size-1);
680 if (nbyte) { 665 if (nbyte) {
681 nbyte = qemu_host_page_size - nbyte; 666 nbyte = qemu_host_page_size - nbyte;
682 - fpnt = (char *) elf_bss;  
683 do { 667 do {
684 - *fpnt++ = 0; 668 + tput8(elf_bss, 0);
  669 + elf_bss++;
685 } while (--nbyte); 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 const char *k_platform; 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 k_platform = ELF_PLATFORM; 691 k_platform = ELF_PLATFORM;
708 if (k_platform) { 692 if (k_platform) {
709 size_t len = strlen(k_platform) + 1; 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 if (k_platform) 703 if (k_platform)
717 - csp -= 2; 704 + size += 2;
718 #ifdef DLINFO_ARCH_ITEMS 705 #ifdef DLINFO_ARCH_ITEMS
719 - csp -= DLINFO_ARCH_ITEMS*2; 706 + size += DLINFO_ARCH_ITEMS * 2;
720 #endif 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 NEW_AUX_ENT (AT_NULL, 0); 718 NEW_AUX_ENT (AT_NULL, 0);
732 719
733 /* There must be exactly DLINFO_ITEMS entries here. */ 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,7 +731,7 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
744 NEW_AUX_ENT(AT_EGID, (target_ulong) getegid()); 731 NEW_AUX_ENT(AT_EGID, (target_ulong) getegid());
745 NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP); 732 NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP);
746 if (k_platform) 733 if (k_platform)
747 - NEW_AUX_ENT(AT_PLATFORM, (target_ulong) u_platform); 734 + NEW_AUX_ENT(AT_PLATFORM, u_platform);
748 #ifdef ARCH_DLINFO 735 #ifdef ARCH_DLINFO
749 /* 736 /*
750 * ARCH_DLINFO must come last so platform specific code can enforce 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,39 +741,32 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc,
754 #endif 741 #endif
755 #undef NEW_AUX_ENT 742 #undef NEW_AUX_ENT
756 743
757 - sp -= envc+1; 744 + sp -= (envc + 1) * n;
758 envp = sp; 745 envp = sp;
759 - sp -= argc+1; 746 + sp -= (argc + 1) * n;
760 argv = sp; 747 argv = sp;
761 if (!ibcs) { 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 while (argc-->0) { 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 while (envc-->0) { 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 return sp; 766 return sp;
786 } 767 }
787 768
788 769
789 -  
790 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, 770 static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
791 int interpreter_fd, 771 int interpreter_fd,
792 unsigned long *interp_load_addr) 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,8 +1315,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * r
1335 #ifdef LOW_ELF_STACK 1315 #ifdef LOW_ELF_STACK
1336 info->start_stack = bprm->p = elf_stack - 4; 1316 info->start_stack = bprm->p = elf_stack - 4;
1337 #endif 1317 #endif
1338 - bprm->p = (unsigned long)  
1339 - create_elf_tables((char *)bprm->p, 1318 + bprm->p = create_elf_tables(bprm->p,
1340 bprm->argc, 1319 bprm->argc,
1341 bprm->envc, 1320 bprm->envc,
1342 &elf_ex, 1321 &elf_ex,
@@ -1432,6 +1411,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp, @@ -1432,6 +1411,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp,
1432 if(retval>=0) { 1411 if(retval>=0) {
1433 retval = load_elf_binary(&bprm,regs,infop); 1412 retval = load_elf_binary(&bprm,regs,infop);
1434 } 1413 }
  1414 +
1435 if(retval>=0) { 1415 if(retval>=0) {
1436 /* success. Initialize important registers */ 1416 /* success. Initialize important registers */
1437 init_thread(regs, infop); 1417 init_thread(regs, infop);
@@ -1440,7 +1420,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp, @@ -1440,7 +1420,7 @@ int elf_exec(const char * filename, char ** argv, char ** envp,
1440 1420
1441 /* Something went wrong, return the inode and free the argument pages*/ 1421 /* Something went wrong, return the inode and free the argument pages*/
1442 for (i=0 ; i<MAX_ARG_PAGES ; i++) { 1422 for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1443 - free_page((void *)bprm.page[i]); 1423 + free(bprm.page[i]);
1444 } 1424 }
1445 return(retval); 1425 return(retval);
1446 } 1426 }
linux-user/ioctls.h
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 IOCTL(KDMKTONE, 0, TYPE_INT) 55 IOCTL(KDMKTONE, 0, TYPE_INT)
56 IOCTL(KDGKBTYPE, IOC_R, MK_PTR(TYPE_CHAR)) 56 IOCTL(KDGKBTYPE, IOC_R, MK_PTR(TYPE_CHAR))
57 IOCTL(KDGKBENT, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_kbentry))) 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 IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) 60 IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT))
61 IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) 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,21 +152,25 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
152 int flags) 152 int flags)
153 { 153 {
154 unsigned int e1, e2; 154 unsigned int e1, e2;
  155 + uint32_t *p;
155 e1 = (addr << 16) | (limit & 0xffff); 156 e1 = (addr << 16) | (limit & 0xffff);
156 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); 157 e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
157 e2 |= flags; 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 static void set_gate(void *ptr, unsigned int type, unsigned int dpl, 164 static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
163 unsigned long addr, unsigned int sel) 165 unsigned long addr, unsigned int sel)
164 { 166 {
165 unsigned int e1, e2; 167 unsigned int e1, e2;
  168 + uint32_t *p;
166 e1 = (addr & 0xffff) | (sel << 16); 169 e1 = (addr & 0xffff) | (sel << 16);
167 e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); 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 uint64_t gdt_table[6]; 176 uint64_t gdt_table[6];
@@ -343,7 +347,7 @@ void cpu_loop(CPUARMState *env) @@ -343,7 +347,7 @@ void cpu_loop(CPUARMState *env)
343 347
344 /* we handle the FPU emulation here, as Linux */ 348 /* we handle the FPU emulation here, as Linux */
345 /* we get the opcode */ 349 /* we get the opcode */
346 - opcode = ldl_raw((uint8_t *)env->regs[15]); 350 + opcode = tget32(env->regs[15]);
347 351
348 if (EmulateAll(opcode, &ts->fpa, env) == 0) { 352 if (EmulateAll(opcode, &ts->fpa, env) == 0) {
349 info.si_signo = SIGILL; 353 info.si_signo = SIGILL;
@@ -364,20 +368,20 @@ void cpu_loop(CPUARMState *env) @@ -364,20 +368,20 @@ void cpu_loop(CPUARMState *env)
364 /* system call */ 368 /* system call */
365 if (trapnr == EXCP_BKPT) { 369 if (trapnr == EXCP_BKPT) {
366 if (env->thumb) { 370 if (env->thumb) {
367 - insn = lduw((void *)(env->regs[15])); 371 + insn = tget16(env->regs[15]);
368 n = insn & 0xff; 372 n = insn & 0xff;
369 env->regs[15] += 2; 373 env->regs[15] += 2;
370 } else { 374 } else {
371 - insn = ldl((void *)(env->regs[15])); 375 + insn = tget32(env->regs[15]);
372 n = (insn & 0xf) | ((insn >> 4) & 0xff0); 376 n = (insn & 0xf) | ((insn >> 4) & 0xff0);
373 env->regs[15] += 4; 377 env->regs[15] += 4;
374 } 378 }
375 } else { 379 } else {
376 if (env->thumb) { 380 if (env->thumb) {
377 - insn = lduw((void *)(env->regs[15] - 2)); 381 + insn = tget16(env->regs[15] - 2);
378 n = insn & 0xff; 382 n = insn & 0xff;
379 } else { 383 } else {
380 - insn = ldl((void *)(env->regs[15] - 4)); 384 + insn = tget32(env->regs[15] - 4);
381 n = insn & 0xffffff; 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,16 +479,16 @@ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
475 static inline void save_window_offset(CPUSPARCState *env, int cwp1) 479 static inline void save_window_offset(CPUSPARCState *env, int cwp1)
476 { 480 {
477 unsigned int i; 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 #if defined(DEBUG_WIN) 485 #if defined(DEBUG_WIN)
482 printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n", 486 printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n",
483 (int)sp_ptr, cwp1); 487 (int)sp_ptr, cwp1);
484 #endif 488 #endif
485 for(i = 0; i < 16; i++) { 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,22 +504,21 @@ static void save_window(CPUSPARCState *env)
500 static void restore_window(CPUSPARCState *env) 504 static void restore_window(CPUSPARCState *env)
501 { 505 {
502 unsigned int new_wim, i, cwp1; 506 unsigned int new_wim, i, cwp1;
503 - uint32_t *sp_ptr, reg; 507 + target_ulong sp_ptr;
504 508
505 new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & 509 new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
506 ((1LL << NWINDOWS) - 1); 510 ((1LL << NWINDOWS) - 1);
507 511
508 /* restore the invalid window */ 512 /* restore the invalid window */
509 cwp1 = (env->cwp + 1) & (NWINDOWS - 1); 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 #if defined(DEBUG_WIN) 515 #if defined(DEBUG_WIN)
512 printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", 516 printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
513 (int)sp_ptr, cwp1); 517 (int)sp_ptr, cwp1);
514 #endif 518 #endif
515 for(i = 0; i < 16; i++) { 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 env->wim = new_wim; 523 env->wim = new_wim;
521 } 524 }
@@ -1304,15 +1307,9 @@ void cpu_loop(CPUMIPSState *env) @@ -1304,15 +1307,9 @@ void cpu_loop(CPUMIPSState *env)
1304 if (nb_args >= 5) { 1307 if (nb_args >= 5) {
1305 sp_reg = env->gpr[29]; 1308 sp_reg = env->gpr[29];
1306 /* these arguments are taken from the stack */ 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 if (nb_args >= 6) { 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 } else { 1313 } else {
1317 arg6 = 0; 1314 arg6 = 0;
1318 } 1315 }
@@ -1347,8 +1344,7 @@ void cpu_loop(CPUMIPSState *env) @@ -1347,8 +1344,7 @@ void cpu_loop(CPUMIPSState *env)
1347 { 1344 {
1348 uint32_t insn, op; 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 op = insn >> 26; 1348 op = insn >> 26;
1353 // printf("insn=%08x op=%02x\n", insn, op); 1349 // printf("insn=%08x op=%02x\n", insn, op);
1354 /* XXX: totally dummy FP ops just to be able to launch 1350 /* XXX: totally dummy FP ops just to be able to launch
@@ -1531,7 +1527,7 @@ int main(int argc, char **argv) @@ -1531,7 +1527,7 @@ int main(int argc, char **argv)
1531 fprintf(logfile, "entry 0x%08lx\n" , info->entry); 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 syscall_init(); 1531 syscall_init();
1536 signal_init(); 1532 signal_init();
1537 1533
@@ -1566,7 +1562,7 @@ int main(int argc, char **argv) @@ -1566,7 +1562,7 @@ int main(int argc, char **argv)
1566 env->eip = regs->eip; 1562 env->eip = regs->eip;
1567 1563
1568 /* linux interrupt setup */ 1564 /* linux interrupt setup */
1569 - env->idt.base = (long)idt_table; 1565 + env->idt.base = h2g(idt_table);
1570 env->idt.limit = sizeof(idt_table) - 1; 1566 env->idt.limit = sizeof(idt_table) - 1;
1571 set_idt(0, 0); 1567 set_idt(0, 0);
1572 set_idt(1, 0); 1568 set_idt(1, 0);
@@ -1591,7 +1587,7 @@ int main(int argc, char **argv) @@ -1591,7 +1587,7 @@ int main(int argc, char **argv)
1591 set_idt(0x80, 3); 1587 set_idt(0x80, 3);
1592 1588
1593 /* linux segment setup */ 1589 /* linux segment setup */
1594 - env->gdt.base = (long)gdt_table; 1590 + env->gdt.base = h2g(gdt_table);
1595 env->gdt.limit = sizeof(gdt_table) - 1; 1591 env->gdt.limit = sizeof(gdt_table) - 1;
1596 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, 1592 write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
1597 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | 1593 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
linux-user/mmap.c
@@ -29,10 +29,10 @@ @@ -29,10 +29,10 @@
29 29
30 //#define DEBUG_MMAP 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 int prot1, ret; 36 int prot1, ret;
37 37
38 #ifdef DEBUG_MMAP 38 #ifdef DEBUG_MMAP
@@ -67,7 +67,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) @@ -67,7 +67,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
67 } 67 }
68 end = host_end; 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 if (ret != 0) 71 if (ret != 0)
72 return ret; 72 return ret;
73 host_start += qemu_host_page_size; 73 host_start += qemu_host_page_size;
@@ -77,7 +77,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) @@ -77,7 +77,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
77 for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { 77 for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
78 prot1 |= page_get_flags(addr); 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 prot1 & PAGE_BITS); 81 prot1 & PAGE_BITS);
82 if (ret != 0) 82 if (ret != 0)
83 return ret; 83 return ret;
@@ -86,7 +86,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) @@ -86,7 +86,7 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
86 86
87 /* handle the pages in the middle */ 87 /* handle the pages in the middle */
88 if (host_start < host_end) { 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 if (ret != 0) 90 if (ret != 0)
91 return ret; 91 return ret;
92 } 92 }
@@ -95,28 +95,31 @@ int target_mprotect(unsigned long start, unsigned long len, int prot) @@ -95,28 +95,31 @@ int target_mprotect(unsigned long start, unsigned long len, int prot)
95 } 95 }
96 96
97 /* map an incomplete host page */ 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 int prot1, prot_new; 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 /* get the protection of the target pages outside the mapping */ 109 /* get the protection of the target pages outside the mapping */
108 prot1 = 0; 110 prot1 = 0;
109 - for(addr = host_start; addr < host_end; addr++) { 111 + for(addr = real_start; addr < real_end; addr++) {
110 if (addr < start || addr >= end) 112 if (addr < start || addr >= end)
111 prot1 |= page_get_flags(addr); 113 prot1 |= page_get_flags(addr);
112 } 114 }
113 115
114 if (prot1 == 0) { 116 if (prot1 == 0) {
115 /* no page was there, so we allocate one */ 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 flags | MAP_ANONYMOUS, -1, 0); 119 flags | MAP_ANONYMOUS, -1, 0);
118 if (ret == -1) 120 if (ret == -1)
119 return ret; 121 return ret;
  122 + prot1 = prot;
120 } 123 }
121 prot1 &= PAGE_BITS; 124 prot1 &= PAGE_BITS;
122 125
@@ -130,31 +133,35 @@ int mmap_frag(unsigned long host_start, @@ -130,31 +133,35 @@ int mmap_frag(unsigned long host_start,
130 133
131 /* adjust protection to be able to read */ 134 /* adjust protection to be able to read */
132 if (!(prot1 & PROT_WRITE)) 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 /* read the corresponding file data */ 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 /* put final protection */ 141 /* put final protection */
139 if (prot_new != (prot1 | PROT_WRITE)) 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 } else { 144 } else {
142 /* just update the protection */ 145 /* just update the protection */
143 if (prot_new != prot1) { 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 return 0; 150 return 0;
148 } 151 }
149 152
150 /* NOTE: all the constants are the HOST ones */ 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 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \ 159 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
156 defined(__ia64) 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 #endif 165 #endif
159 166
160 #ifdef DEBUG_MMAP 167 #ifdef DEBUG_MMAP
@@ -191,45 +198,49 @@ long target_mmap(unsigned long start, unsigned long len, int prot, @@ -191,45 +198,49 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
191 len = TARGET_PAGE_ALIGN(len); 198 len = TARGET_PAGE_ALIGN(len);
192 if (len == 0) 199 if (len == 0)
193 return start; 200 return start;
194 - host_start = start & qemu_host_page_mask; 201 + real_start = start & qemu_host_page_mask;
195 202
196 if (!(flags & MAP_FIXED)) { 203 if (!(flags & MAP_FIXED)) {
197 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \ 204 #if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
198 - defined(__ia64) 205 + defined(__ia64) || defined(__CYGWIN__)
199 /* tell the kenel to search at the same place as i386 */ 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 last_start += HOST_PAGE_ALIGN(len); 209 last_start += HOST_PAGE_ALIGN(len);
203 } 210 }
204 #endif 211 #endif
205 if (qemu_host_page_size != qemu_real_host_page_size) { 212 if (qemu_host_page_size != qemu_real_host_page_size) {
206 /* NOTE: this code is only for debugging with '-p' option */ 213 /* NOTE: this code is only for debugging with '-p' option */
  214 + /* ??? Can also occur when TARGET_PAGE_SIZE > host page size. */
207 /* reserve a memory area */ 215 /* reserve a memory area */
  216 + /* ??? This needs fixing for remapping. */
  217 +abort();
208 host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE; 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 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 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 end = start + HOST_PAGE_ALIGN(len); 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 /* use it as a fixed mapping */ 230 /* use it as a fixed mapping */
221 flags |= MAP_FIXED; 231 flags |= MAP_FIXED;
222 } else { 232 } else {
223 /* if not fixed, no need to do anything */ 233 /* if not fixed, no need to do anything */
224 host_offset = offset & qemu_host_page_mask; 234 host_offset = offset & qemu_host_page_mask;
225 host_len = len + offset - host_offset; 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 /* update start so that it points to the file position at 'offset' */ 240 /* update start so that it points to the file position at 'offset' */
231 if (!(flags & MAP_ANONYMOUS)) 241 if (!(flags & MAP_ANONYMOUS))
232 - start += offset - host_offset; 242 + host_start += offset - host_offset;
  243 + start = h2g(host_start);
233 goto the_end1; 244 goto the_end1;
234 } 245 }
235 } 246 }
@@ -239,7 +250,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot, @@ -239,7 +250,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
239 return -1; 250 return -1;
240 } 251 }
241 end = start + len; 252 end = start + len;
242 - host_end = HOST_PAGE_ALIGN(end); 253 + real_end = HOST_PAGE_ALIGN(end);
243 254
244 /* worst case: we cannot map the file because the offset is not 255 /* worst case: we cannot map the file because the offset is not
245 aligned, so we read it */ 256 aligned, so we read it */
@@ -257,7 +268,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot, @@ -257,7 +268,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
257 -1, 0); 268 -1, 0);
258 if (retaddr == -1) 269 if (retaddr == -1)
259 return retaddr; 270 return retaddr;
260 - pread(fd, (void *)start, len, offset); 271 + pread(fd, g2h(start), len, offset);
261 if (!(prot & PROT_WRITE)) { 272 if (!(prot & PROT_WRITE)) {
262 ret = target_mprotect(start, len, prot); 273 ret = target_mprotect(start, len, prot);
263 if (ret != 0) 274 if (ret != 0)
@@ -267,40 +278,40 @@ long target_mmap(unsigned long start, unsigned long len, int prot, @@ -267,40 +278,40 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
267 } 278 }
268 279
269 /* handle the start of the mapping */ 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 /* one single host page */ 283 /* one single host page */
273 - ret = mmap_frag(host_start, start, end, 284 + ret = mmap_frag(real_start, start, end,
274 prot, flags, fd, offset); 285 prot, flags, fd, offset);
275 if (ret == -1) 286 if (ret == -1)
276 return ret; 287 return ret;
277 goto the_end1; 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 prot, flags, fd, offset); 291 prot, flags, fd, offset);
281 if (ret == -1) 292 if (ret == -1)
282 return ret; 293 return ret;
283 - host_start += qemu_host_page_size; 294 + real_start += qemu_host_page_size;
284 } 295 }
285 /* handle the end of the mapping */ 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 prot, flags, fd, 300 prot, flags, fd,
290 - offset + host_end - qemu_host_page_size - start); 301 + offset + real_end - qemu_host_page_size - start);
291 if (ret == -1) 302 if (ret == -1)
292 return ret; 303 return ret;
293 - host_end -= qemu_host_page_size; 304 + real_end -= qemu_host_page_size;
294 } 305 }
295 306
296 /* map the middle (easier) */ 307 /* map the middle (easier) */
297 - if (host_start < host_end) { 308 + if (real_start < real_end) {
298 unsigned long offset1; 309 unsigned long offset1;
299 if (flags & MAP_ANONYMOUS) 310 if (flags & MAP_ANONYMOUS)
300 offset1 = 0; 311 offset1 = 0;
301 else 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 prot, flags, fd, offset1); 315 prot, flags, fd, offset1);
305 if (ret == -1) 316 if (ret == -1)
306 return ret; 317 return ret;
@@ -316,9 +327,9 @@ long target_mmap(unsigned long start, unsigned long len, int prot, @@ -316,9 +327,9 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
316 return start; 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 int prot, ret; 333 int prot, ret;
323 334
324 #ifdef DEBUG_MMAP 335 #ifdef DEBUG_MMAP
@@ -330,36 +341,36 @@ int target_munmap(unsigned long start, unsigned long len) @@ -330,36 +341,36 @@ int target_munmap(unsigned long start, unsigned long len)
330 if (len == 0) 341 if (len == 0)
331 return -EINVAL; 342 return -EINVAL;
332 end = start + len; 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 /* handle host page containing start */ 348 /* handle host page containing start */
338 prot = 0; 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 prot |= page_get_flags(addr); 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 prot |= page_get_flags(addr); 355 prot |= page_get_flags(addr);
345 } 356 }
346 - end = host_end; 357 + end = real_end;
347 } 358 }
348 if (prot != 0) 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 prot = 0; 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 prot |= page_get_flags(addr); 365 prot |= page_get_flags(addr);
355 } 366 }
356 if (prot != 0) 367 if (prot != 0)
357 - host_end -= qemu_host_page_size; 368 + real_end -= qemu_host_page_size;
358 } 369 }
359 370
360 /* unmap what we can */ 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 if (ret != 0) 374 if (ret != 0)
364 return ret; 375 return ret;
365 } 376 }
@@ -370,25 +381,26 @@ int target_munmap(unsigned long start, unsigned long len) @@ -370,25 +381,26 @@ int target_munmap(unsigned long start, unsigned long len)
370 381
371 /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED 382 /* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
372 blocks which have been allocated starting on a host page */ 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 int prot; 388 int prot;
378 389
379 /* XXX: use 5 args syscall */ 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 if (new_addr == -1) 392 if (new_addr == -1)
382 return new_addr; 393 return new_addr;
  394 + new_addr = h2g(new_addr);
383 prot = page_get_flags(old_addr); 395 prot = page_get_flags(old_addr);
384 page_set_flags(old_addr, old_addr + old_size, 0); 396 page_set_flags(old_addr, old_addr + old_size, 0);
385 page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); 397 page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
386 return new_addr; 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 if (start & ~TARGET_PAGE_MASK) 405 if (start & ~TARGET_PAGE_MASK)
394 return -EINVAL; 406 return -EINVAL;
@@ -400,6 +412,6 @@ int target_msync(unsigned long start, unsigned long len, int flags) @@ -400,6 +412,6 @@ int target_msync(unsigned long start, unsigned long len, int flags)
400 return 0; 412 return 0;
401 413
402 start &= qemu_host_page_mask; 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,7 +69,7 @@ typedef struct TaskState {
69 int swi_errno; 69 int swi_errno;
70 #endif 70 #endif
71 #ifdef TARGET_I386 71 #ifdef TARGET_I386
72 - struct target_vm86plus_struct *target_v86; 72 + target_ulong target_v86;
73 struct vm86_saved_state vm86_saved_regs; 73 struct vm86_saved_state vm86_saved_regs;
74 struct target_vm86plus_struct vm86plus; 74 struct target_vm86plus_struct vm86plus;
75 uint32_t v86flags; 75 uint32_t v86flags;
@@ -84,8 +84,8 @@ extern TaskState *first_task_state; @@ -84,8 +84,8 @@ extern TaskState *first_task_state;
84 int elf_exec(const char * filename, char ** argv, char ** envp, 84 int elf_exec(const char * filename, char ** argv, char ** envp,
85 struct target_pt_regs * regs, struct image_info *infop); 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 void syscall_init(void); 89 void syscall_init(void);
90 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 90 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
91 long arg4, long arg5, long arg6); 91 long arg4, long arg5, long arg6);
@@ -112,19 +112,18 @@ long do_rt_sigreturn(CPUState *env); @@ -112,19 +112,18 @@ long do_rt_sigreturn(CPUState *env);
112 void save_v86_state(CPUX86State *env); 112 void save_v86_state(CPUX86State *env);
113 void handle_vm86_trap(CPUX86State *env, int trapno); 113 void handle_vm86_trap(CPUX86State *env, int trapno);
114 void handle_vm86_fault(CPUX86State *env); 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 #endif 116 #endif
118 117
119 /* mmap.c */ 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 /* user access */ 128 /* user access */
130 129
@@ -133,21 +132,22 @@ int target_msync(unsigned long start, unsigned long len, int flags); @@ -133,21 +132,22 @@ int target_msync(unsigned long start, unsigned long len, int flags);
133 132
134 #define access_ok(type,addr,size) (1) 133 #define access_ok(type,addr,size) (1)
135 134
  135 +/* NOTE get_user and put_user use host addresses. */
136 #define __put_user(x,ptr)\ 136 #define __put_user(x,ptr)\
137 ({\ 137 ({\
138 int size = sizeof(*ptr);\ 138 int size = sizeof(*ptr);\
139 switch(size) {\ 139 switch(size) {\
140 case 1:\ 140 case 1:\
141 - stb(ptr, (typeof(*ptr))(x));\ 141 + *(uint8_t *)(ptr) = (typeof(*ptr))(x);\
142 break;\ 142 break;\
143 case 2:\ 143 case 2:\
144 - stw(ptr, (typeof(*ptr))(x));\ 144 + *(uint16_t *)(ptr) = tswap16((typeof(*ptr))(x));\
145 break;\ 145 break;\
146 case 4:\ 146 case 4:\
147 - stl(ptr, (typeof(*ptr))(x));\ 147 + *(uint32_t *)(ptr) = tswap32((typeof(*ptr))(x));\
148 break;\ 148 break;\
149 case 8:\ 149 case 8:\
150 - stq(ptr, (typeof(*ptr))(x));\ 150 + *(uint64_t *)(ptr) = tswap64((typeof(*ptr))(x));\
151 break;\ 151 break;\
152 default:\ 152 default:\
153 abort();\ 153 abort();\
@@ -160,16 +160,16 @@ int target_msync(unsigned long start, unsigned long len, int flags); @@ -160,16 +160,16 @@ int target_msync(unsigned long start, unsigned long len, int flags);
160 int size = sizeof(*ptr);\ 160 int size = sizeof(*ptr);\
161 switch(size) {\ 161 switch(size) {\
162 case 1:\ 162 case 1:\
163 - x = (typeof(*ptr))ldub((void *)ptr);\ 163 + x = (typeof(*ptr))*(uint8_t *)(ptr);\
164 break;\ 164 break;\
165 case 2:\ 165 case 2:\
166 - x = (typeof(*ptr))lduw((void *)ptr);\ 166 + x = (typeof(*ptr))tswap16(*(uint16_t *)(ptr));\
167 break;\ 167 break;\
168 case 4:\ 168 case 4:\
169 - x = (typeof(*ptr))ldl((void *)ptr);\ 169 + x = (typeof(*ptr))tswap32(*(uint32_t *)(ptr));\
170 break;\ 170 break;\
171 case 8:\ 171 case 8:\
172 - x = (typeof(*ptr))ldq((void *)ptr);\ 172 + x = (typeof(*ptr))tswap64(*(uint64_t *)(ptr));\
173 break;\ 173 break;\
174 default:\ 174 default:\
175 abort();\ 175 abort();\
@@ -177,26 +177,6 @@ int target_msync(unsigned long start, unsigned long len, int flags); @@ -177,26 +177,6 @@ int target_msync(unsigned long start, unsigned long len, int flags);
177 0;\ 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 #define put_user(x,ptr)\ 180 #define put_user(x,ptr)\
201 ({\ 181 ({\
202 int __ret;\ 182 int __ret;\
@@ -217,30 +197,77 @@ static inline unsigned long __clear_user(void *dst, unsigned long size) @@ -217,30 +197,77 @@ static inline unsigned long __clear_user(void *dst, unsigned long size)
217 __ret;\ 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 else 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 #endif /* QEMU_H */ 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,7 +135,7 @@ void host_to_target_sigset(target_sigset_t *d, const sigset_t *s)
135 135
136 host_to_target_sigset_internal(&d1, s); 136 host_to_target_sigset_internal(&d1, s);
137 for(i = 0;i < TARGET_NSIG_WORDS; i++) 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 void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s) 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,7 +168,7 @@ void target_to_host_sigset(sigset_t *d, const target_sigset_t *s)
168 int i; 168 int i;
169 169
170 for(i = 0;i < TARGET_NSIG_WORDS; i++) 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 target_to_host_sigset_internal(d, &s1); 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,7 +647,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
647 ka->sa.sa_restorer) { 647 ka->sa.sa_restorer) {
648 esp = (unsigned long) ka->sa.sa_restorer; 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 static void setup_frame(int sig, struct emulated_sigaction *ka, 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,7 +694,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
694 goto give_sigsegv; 694 goto give_sigsegv;
695 695
696 /* Set up registers for signal handler */ 696 /* Set up registers for signal handler */
697 - env->regs[R_ESP] = (unsigned long) frame; 697 + env->regs[R_ESP] = h2g(frame);
698 env->eip = (unsigned long) ka->sa._sa_handler; 698 env->eip = (unsigned long) ka->sa._sa_handler;
699 699
700 cpu_x86_load_seg(env, R_DS, __USER_DS); 700 cpu_x86_load_seg(env, R_DS, __USER_DS);
@@ -835,7 +835,7 @@ badframe: @@ -835,7 +835,7 @@ badframe:
835 835
836 long do_sigreturn(CPUX86State *env) 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 target_sigset_t target_set; 839 target_sigset_t target_set;
840 sigset_t set; 840 sigset_t set;
841 int eax, i; 841 int eax, i;
@@ -866,7 +866,7 @@ badframe: @@ -866,7 +866,7 @@ badframe:
866 866
867 long do_rt_sigreturn(CPUX86State *env) 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 sigset_t set; 870 sigset_t set;
871 // stack_t st; 871 // stack_t st;
872 int eax; 872 int eax;
@@ -1029,7 +1029,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) @@ -1029,7 +1029,7 @@ get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize)
1029 /* 1029 /*
1030 * ATPCS B01 mandates 8-byte alignment 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 static int 1035 static int
@@ -1084,7 +1084,7 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, @@ -1084,7 +1084,7 @@ setup_return(CPUState *env, struct emulated_sigaction *ka,
1084 } 1084 }
1085 1085
1086 env->regs[0] = usig; 1086 env->regs[0] = usig;
1087 - env->regs[13] = (target_ulong)frame; 1087 + env->regs[13] = h2g(frame);
1088 env->regs[14] = retcode; 1088 env->regs[14] = retcode;
1089 env->regs[15] = handler & (thumb ? ~1 : ~3); 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,7 +1130,7 @@ static void setup_rt_frame(int usig, struct emulated_sigaction *ka,
1130 err |= copy_siginfo_to_user(&frame->info, info); 1130 err |= copy_siginfo_to_user(&frame->info, info);
1131 1131
1132 /* Clear all the bits of the ucontext we don't use. */ 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 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/ 1135 err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/
1136 env, set->sig[0]); 1136 env, set->sig[0]);
@@ -1202,7 +1202,7 @@ long do_sigreturn(CPUState *env) @@ -1202,7 +1202,7 @@ long do_sigreturn(CPUState *env)
1202 if (env->regs[13] & 7) 1202 if (env->regs[13] & 7)
1203 goto badframe; 1203 goto badframe;
1204 1204
1205 - frame = (struct sigframe *)env->regs[13]; 1205 + frame = (struct sigframe *)g2h(env->regs[13]);
1206 1206
1207 #if 0 1207 #if 0
1208 if (verify_area(VERIFY_READ, frame, sizeof (*frame))) 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,7 +1378,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
1378 sp = current->sas_ss_sp + current->sas_ss_size; 1378 sp = current->sas_ss_sp + current->sas_ss_size;
1379 } 1379 }
1380 #endif 1380 #endif
1381 - return (void *)(sp - framesize); 1381 + return g2h(sp - framesize);
1382 } 1382 }
1383 1383
1384 static int 1384 static int
@@ -1461,10 +1461,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1461,10 +1461,10 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1461 goto sigsegv; 1461 goto sigsegv;
1462 1462
1463 /* 3. signal handler back-trampoline and parameters */ 1463 /* 3. signal handler back-trampoline and parameters */
1464 - env->regwptr[UREG_FP] = (target_ulong) sf; 1464 + env->regwptr[UREG_FP] = h2g(sf);
1465 env->regwptr[UREG_I0] = sig; 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 /* 4. signal handler */ 1469 /* 4. signal handler */
1470 env->pc = (unsigned long) ka->sa._sa_handler; 1470 env->pc = (unsigned long) ka->sa._sa_handler;
@@ -1473,7 +1473,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1473,7 +1473,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1473 if (ka->sa.sa_restorer) 1473 if (ka->sa.sa_restorer)
1474 env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer; 1474 env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;
1475 else { 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 /* mov __NR_sigreturn, %g1 */ 1478 /* mov __NR_sigreturn, %g1 */
1479 err |= __put_user(0x821020d8, &sf->insns[0]); 1479 err |= __put_user(0x821020d8, &sf->insns[0]);
@@ -1548,7 +1548,7 @@ long do_sigreturn(CPUState *env) @@ -1548,7 +1548,7 @@ long do_sigreturn(CPUState *env)
1548 target_ulong fpu_save; 1548 target_ulong fpu_save;
1549 int err, i; 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 #if 0 1552 #if 0
1553 fprintf(stderr, "sigreturn\n"); 1553 fprintf(stderr, "sigreturn\n");
1554 fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]); 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,44 +252,43 @@ static inline int is_error(long ret)
252 return (unsigned long)ret >= (unsigned long)(-4096); 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 long mapped_addr; 266 long mapped_addr;
268 int new_alloc_size; 267 int new_alloc_size;
269 268
270 if (!new_brk) 269 if (!new_brk)
271 - return (long)target_brk; 270 + return target_brk;
272 if (new_brk < target_original_brk) 271 if (new_brk < target_original_brk)
273 return -ENOMEM; 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 /* If the new brk is less than this, set it and we're done... */ 276 /* If the new brk is less than this, set it and we're done... */
278 if (new_brk < brk_page) { 277 if (new_brk < brk_page) {
279 target_brk = new_brk; 278 target_brk = new_brk;
280 - return (long)target_brk; 279 + return target_brk;
281 } 280 }
282 281
283 /* We need to allocate more memory after the brk... */ 282 /* We need to allocate more memory after the brk... */
284 new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); 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 PROT_READ|PROT_WRITE, 285 PROT_READ|PROT_WRITE,
287 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0)); 286 MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
288 if (is_error(mapped_addr)) { 287 if (is_error(mapped_addr)) {
289 return mapped_addr; 288 return mapped_addr;
290 } else { 289 } else {
291 target_brk = new_brk; 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,9 +353,12 @@ static inline long host_to_target_clock_t(long ticks)
354 #endif 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 const struct rusage *rusage) 357 const struct rusage *rusage)
359 { 358 {
  359 + struct target_rusage *target_rusage;
  360 +
  361 + lock_user_struct(target_rusage, target_addr, 0);
360 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec); 362 target_rusage->ru_utime.tv_sec = tswapl(rusage->ru_utime.tv_sec);
361 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec); 363 target_rusage->ru_utime.tv_usec = tswapl(rusage->ru_utime.tv_usec);
362 target_rusage->ru_stime.tv_sec = tswapl(rusage->ru_stime.tv_sec); 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,35 +377,64 @@ static inline void host_to_target_rusage(struct target_rusage *target_rusage,
375 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals); 377 target_rusage->ru_nsignals = tswapl(rusage->ru_nsignals);
376 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw); 378 target_rusage->ru_nvcsw = tswapl(rusage->ru_nvcsw);
377 target_rusage->ru_nivcsw = tswapl(rusage->ru_nivcsw); 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 tv->tv_sec = tswapl(target_tv->tv_sec); 389 tv->tv_sec = tswapl(target_tv->tv_sec);
384 tv->tv_usec = tswapl(target_tv->tv_usec); 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 const struct timeval *tv) 395 const struct timeval *tv)
389 { 396 {
  397 + struct target_timeval *target_tv;
  398 +
  399 + lock_user_struct(target_tv, target_addr, 0);
390 target_tv->tv_sec = tswapl(tv->tv_sec); 400 target_tv->tv_sec = tswapl(tv->tv_sec);
391 target_tv->tv_usec = tswapl(tv->tv_usec); 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 static long do_select(long n, 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 fd_set rfds, wfds, efds; 410 fd_set rfds, wfds, efds;
400 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; 411 fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
  412 + target_long *target_rfds, *target_wfds, *target_efds;
401 struct timeval tv, *tv_ptr; 413 struct timeval tv, *tv_ptr;
402 long ret; 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 if (target_tv) { 439 if (target_tv) {
409 target_to_host_timeval(&tv, target_tv); 440 target_to_host_timeval(&tv, target_tv);
@@ -412,7 +443,9 @@ static long do_select(long n, @@ -412,7 +443,9 @@ static long do_select(long n,
412 tv_ptr = NULL; 443 tv_ptr = NULL;
413 } 444 }
414 ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); 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 host_to_target_fds(target_rfds, rfds_ptr, n); 449 host_to_target_fds(target_rfds, rfds_ptr, n);
417 host_to_target_fds(target_wfds, wfds_ptr, n); 450 host_to_target_fds(target_wfds, wfds_ptr, n);
418 host_to_target_fds(target_efds, efds_ptr, n); 451 host_to_target_fds(target_efds, efds_ptr, n);
@@ -421,25 +454,41 @@ static long do_select(long n, @@ -421,25 +454,41 @@ static long do_select(long n,
421 host_to_target_timeval(target_tv, &tv); 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 return ret; 464 return ret;
425 } 465 }
426 466
427 static inline void target_to_host_sockaddr(struct sockaddr *addr, 467 static inline void target_to_host_sockaddr(struct sockaddr *addr,
428 - struct target_sockaddr *target_addr, 468 + target_ulong target_addr,
429 socklen_t len) 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 struct sockaddr *addr, 480 struct sockaddr *addr,
437 socklen_t len) 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 static inline void target_to_host_cmsg(struct msghdr *msgh, 492 static inline void target_to_host_cmsg(struct msghdr *msgh,
444 struct target_msghdr *target_msgh) 493 struct target_msghdr *target_msgh)
445 { 494 {
@@ -484,6 +533,7 @@ static inline void target_to_host_cmsg(struct msghdr *msgh, @@ -484,6 +533,7 @@ static inline void target_to_host_cmsg(struct msghdr *msgh,
484 msgh->msg_controllen = space; 533 msgh->msg_controllen = space;
485 } 534 }
486 535
  536 +/* ??? Should this also swap msgh->name? */
487 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, 537 static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
488 struct msghdr *msgh) 538 struct msghdr *msgh)
489 { 539 {
@@ -528,7 +578,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh, @@ -528,7 +578,7 @@ static inline void host_to_target_cmsg(struct target_msghdr *target_msgh,
528 } 578 }
529 579
530 static long do_setsockopt(int sockfd, int level, int optname, 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 int val, ret; 583 int val, ret;
534 584
@@ -538,8 +588,7 @@ static long do_setsockopt(int sockfd, int level, int optname, @@ -538,8 +588,7 @@ static long do_setsockopt(int sockfd, int level, int optname,
538 if (optlen < sizeof(uint32_t)) 588 if (optlen < sizeof(uint32_t))
539 return -EINVAL; 589 return -EINVAL;
540 590
541 - if (get_user(val, (uint32_t *)optval))  
542 - return -EFAULT; 591 + val = tget32(optval);
543 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 592 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
544 break; 593 break;
545 case SOL_IP: 594 case SOL_IP:
@@ -561,11 +610,9 @@ static long do_setsockopt(int sockfd, int level, int optname, @@ -561,11 +610,9 @@ static long do_setsockopt(int sockfd, int level, int optname,
561 case IP_MULTICAST_LOOP: 610 case IP_MULTICAST_LOOP:
562 val = 0; 611 val = 0;
563 if (optlen >= sizeof(uint32_t)) { 612 if (optlen >= sizeof(uint32_t)) {
564 - if (get_user(val, (uint32_t *)optval))  
565 - return -EFAULT; 613 + val = tget32(optval);
566 } else if (optlen >= 1) { 614 } else if (optlen >= 1) {
567 - if (get_user(val, (uint8_t *)optval))  
568 - return -EFAULT; 615 + val = tget8(optval);
569 } 616 }
570 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 617 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
571 break; 618 break;
@@ -598,8 +645,8 @@ static long do_setsockopt(int sockfd, int level, int optname, @@ -598,8 +645,8 @@ static long do_setsockopt(int sockfd, int level, int optname,
598 case SO_SNDTIMEO: 645 case SO_SNDTIMEO:
599 if (optlen < sizeof(uint32_t)) 646 if (optlen < sizeof(uint32_t))
600 return -EINVAL; 647 return -EINVAL;
601 - if (get_user(val, (uint32_t *)optval))  
602 - return -EFAULT; 648 +
  649 + val = tget32(optval);
603 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); 650 ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val)));
604 break; 651 break;
605 default: 652 default:
@@ -615,7 +662,7 @@ static long do_setsockopt(int sockfd, int level, int optname, @@ -615,7 +662,7 @@ static long do_setsockopt(int sockfd, int level, int optname,
615 } 662 }
616 663
617 static long do_getsockopt(int sockfd, int level, int optname, 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 int len, lv, val, ret; 667 int len, lv, val, ret;
621 668
@@ -636,8 +683,7 @@ static long do_getsockopt(int sockfd, int level, int optname, @@ -636,8 +683,7 @@ static long do_getsockopt(int sockfd, int level, int optname,
636 case SOL_TCP: 683 case SOL_TCP:
637 /* TCP options all take an 'int' value. */ 684 /* TCP options all take an 'int' value. */
638 int_case: 685 int_case:
639 - if (get_user(len, optlen))  
640 - return -EFAULT; 686 + len = tget32(optlen);
641 if (len < 0) 687 if (len < 0)
642 return -EINVAL; 688 return -EINVAL;
643 lv = sizeof(int); 689 lv = sizeof(int);
@@ -647,10 +693,11 @@ static long do_getsockopt(int sockfd, int level, int optname, @@ -647,10 +693,11 @@ static long do_getsockopt(int sockfd, int level, int optname,
647 val = tswap32(val); 693 val = tswap32(val);
648 if (len > lv) 694 if (len > lv)
649 len = lv; 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 break; 701 break;
655 case SOL_IP: 702 case SOL_IP:
656 switch(optname) { 703 switch(optname) {
@@ -669,8 +716,7 @@ static long do_getsockopt(int sockfd, int level, int optname, @@ -669,8 +716,7 @@ static long do_getsockopt(int sockfd, int level, int optname,
669 #endif 716 #endif
670 case IP_MULTICAST_TTL: 717 case IP_MULTICAST_TTL:
671 case IP_MULTICAST_LOOP: 718 case IP_MULTICAST_LOOP:
672 - if (get_user(len, optlen))  
673 - return -EFAULT; 719 + len = tget32(optlen);
674 if (len < 0) 720 if (len < 0)
675 return -EINVAL; 721 return -EINVAL;
676 lv = sizeof(int); 722 lv = sizeof(int);
@@ -678,20 +724,14 @@ static long do_getsockopt(int sockfd, int level, int optname, @@ -678,20 +724,14 @@ static long do_getsockopt(int sockfd, int level, int optname,
678 if (ret < 0) 724 if (ret < 0)
679 return ret; 725 return ret;
680 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) { 726 if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
681 - unsigned char ucval = val;  
682 len = 1; 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 } else { 730 } else {
688 - val = tswap32(val);  
689 if (len > sizeof(int)) 731 if (len > sizeof(int))
690 len = sizeof(int); 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 break; 736 break;
697 default: 737 default:
@@ -708,25 +748,57 @@ static long do_getsockopt(int sockfd, int level, int optname, @@ -708,25 +748,57 @@ static long do_getsockopt(int sockfd, int level, int optname,
708 return ret; 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 long ret; 784 long ret;
  785 + const int n = sizeof(target_ulong);
714 786
715 switch(num) { 787 switch(num) {
716 case SOCKOP_socket: 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 ret = get_errno(socket(domain, type, protocol)); 794 ret = get_errno(socket(domain, type, protocol));
723 } 795 }
724 break; 796 break;
725 case SOCKOP_bind: 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 void *addr = alloca(addrlen); 802 void *addr = alloca(addrlen);
731 803
732 target_to_host_sockaddr(addr, target_addr, addrlen); 804 target_to_host_sockaddr(addr, target_addr, addrlen);
@@ -735,9 +807,9 @@ static long do_socketcall(int num, int32_t *vptr) @@ -735,9 +807,9 @@ static long do_socketcall(int num, int32_t *vptr)
735 break; 807 break;
736 case SOCKOP_connect: 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 void *addr = alloca(addrlen); 813 void *addr = alloca(addrlen);
742 814
743 target_to_host_sockaddr(addr, target_addr, addrlen); 815 target_to_host_sockaddr(addr, target_addr, addrlen);
@@ -746,128 +818,142 @@ static long do_socketcall(int num, int32_t *vptr) @@ -746,128 +818,142 @@ static long do_socketcall(int num, int32_t *vptr)
746 break; 818 break;
747 case SOCKOP_listen: 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 ret = get_errno(listen(sockfd, backlog)); 824 ret = get_errno(listen(sockfd, backlog));
753 } 825 }
754 break; 826 break;
755 case SOCKOP_accept: 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 void *addr = alloca(addrlen); 833 void *addr = alloca(addrlen);
762 834
763 ret = get_errno(accept(sockfd, addr, &addrlen)); 835 ret = get_errno(accept(sockfd, addr, &addrlen));
764 if (!is_error(ret)) { 836 if (!is_error(ret)) {
765 host_to_target_sockaddr(target_addr, addr, addrlen); 837 host_to_target_sockaddr(target_addr, addr, addrlen);
766 - *target_addrlen = tswap32(addrlen); 838 + tput32(target_addrlen, addrlen);
767 } 839 }
768 } 840 }
769 break; 841 break;
770 case SOCKOP_getsockname: 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 void *addr = alloca(addrlen); 848 void *addr = alloca(addrlen);
777 849
778 ret = get_errno(getsockname(sockfd, addr, &addrlen)); 850 ret = get_errno(getsockname(sockfd, addr, &addrlen));
779 if (!is_error(ret)) { 851 if (!is_error(ret)) {
780 host_to_target_sockaddr(target_addr, addr, addrlen); 852 host_to_target_sockaddr(target_addr, addr, addrlen);
781 - *target_addrlen = tswap32(addrlen); 853 + tput32(target_addrlen, addrlen);
782 } 854 }
783 } 855 }
784 break; 856 break;
785 case SOCKOP_getpeername: 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 void *addr = alloca(addrlen); 863 void *addr = alloca(addrlen);
792 864
793 ret = get_errno(getpeername(sockfd, addr, &addrlen)); 865 ret = get_errno(getpeername(sockfd, addr, &addrlen));
794 if (!is_error(ret)) { 866 if (!is_error(ret)) {
795 host_to_target_sockaddr(target_addr, addr, addrlen); 867 host_to_target_sockaddr(target_addr, addr, addrlen);
796 - *target_addrlen = tswap32(addrlen); 868 + tput32(target_addrlen, addrlen);
797 } 869 }
798 } 870 }
799 break; 871 break;
800 case SOCKOP_socketpair: 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 int tab[2]; 878 int tab[2];
807 879
808 ret = get_errno(socketpair(domain, type, protocol, tab)); 880 ret = get_errno(socketpair(domain, type, protocol, tab));
809 if (!is_error(ret)) { 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 break; 886 break;
815 case SOCKOP_send: 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 break; 899 break;
825 case SOCKOP_recv: 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 break; 912 break;
835 case SOCKOP_sendto: 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 void *addr = alloca(addrlen); 921 void *addr = alloca(addrlen);
  922 + void *host_msg;
844 923
  924 + host_msg = lock_user(msg, len, 1);
845 target_to_host_sockaddr(addr, target_addr, addrlen); 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 break; 929 break;
849 case SOCKOP_recvfrom: 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 void *addr = alloca(addrlen); 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 if (!is_error(ret)) { 944 if (!is_error(ret)) {
862 host_to_target_sockaddr(target_addr, addr, addrlen); 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 break; 952 break;
867 case SOCKOP_shutdown: 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 ret = get_errno(shutdown(sockfd, how)); 958 ret = get_errno(shutdown(sockfd, how));
873 } 959 }
@@ -876,32 +962,39 @@ static long do_socketcall(int num, int32_t *vptr) @@ -876,32 +962,39 @@ static long do_socketcall(int num, int32_t *vptr)
876 case SOCKOP_recvmsg: 962 case SOCKOP_recvmsg:
877 { 963 {
878 int fd; 964 int fd;
  965 + target_ulong target_msg;
879 struct target_msghdr *msgp; 966 struct target_msghdr *msgp;
880 struct msghdr msg; 967 struct msghdr msg;
881 - int flags, count, i; 968 + int flags, count;
882 struct iovec *vec; 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 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); 984 msg.msg_controllen = 2 * tswapl(msgp->msg_controllen);
889 msg.msg_control = alloca(msg.msg_controllen); 985 msg.msg_control = alloca(msg.msg_controllen);
890 msg.msg_flags = tswap32(msgp->msg_flags); 986 msg.msg_flags = tswap32(msgp->msg_flags);
891 987
892 count = tswapl(msgp->msg_iovlen); 988 count = tswapl(msgp->msg_iovlen);
893 vec = alloca(count * sizeof(struct iovec)); 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 msg.msg_iovlen = count; 992 msg.msg_iovlen = count;
900 msg.msg_iov = vec; 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 target_to_host_cmsg(&msg, msgp); 998 target_to_host_cmsg(&msg, msgp);
906 ret = get_errno(sendmsg(fd, &msg, flags)); 999 ret = get_errno(sendmsg(fd, &msg, flags));
907 } else { 1000 } else {
@@ -909,26 +1002,27 @@ static long do_socketcall(int num, int32_t *vptr) @@ -909,26 +1002,27 @@ static long do_socketcall(int num, int32_t *vptr)
909 if (!is_error(ret)) 1002 if (!is_error(ret))
910 host_to_target_cmsg(msgp, &msg); 1003 host_to_target_cmsg(msgp, &msg);
911 } 1004 }
  1005 + unlock_iovec(vec, target_vec, count, !send);
912 } 1006 }
913 break; 1007 break;
914 case SOCKOP_setsockopt: 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 ret = do_setsockopt(sockfd, level, optname, optval, optlen); 1016 ret = do_setsockopt(sockfd, level, optname, optval, optlen);
923 } 1017 }
924 break; 1018 break;
925 case SOCKOP_getsockopt: 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 ret = do_getsockopt(sockfd, level, optname, optval, poptlen); 1027 ret = do_getsockopt(sockfd, level, optname, optval, poptlen);
934 } 1028 }
@@ -949,6 +1043,7 @@ static struct shm_region { @@ -949,6 +1043,7 @@ static struct shm_region {
949 uint32_t size; 1043 uint32_t size;
950 } shm_regions[N_SHM_REGIONS]; 1044 } shm_regions[N_SHM_REGIONS];
951 1045
  1046 +/* ??? This only works with linear mappings. */
952 static long do_ipc(long call, long first, long second, long third, 1047 static long do_ipc(long call, long first, long second, long third,
953 long ptr, long fifth) 1048 long ptr, long fifth)
954 { 1049 {
@@ -1065,12 +1160,15 @@ IOCTLEntry ioctl_entries[] = { @@ -1065,12 +1160,15 @@ IOCTLEntry ioctl_entries[] = {
1065 { 0, 0, }, 1160 { 0, 0, },
1066 }; 1161 };
1067 1162
  1163 +/* ??? Implement proper locking for ioctls. */
1068 static long do_ioctl(long fd, long cmd, long arg) 1164 static long do_ioctl(long fd, long cmd, long arg)
1069 { 1165 {
1070 const IOCTLEntry *ie; 1166 const IOCTLEntry *ie;
1071 const argtype *arg_type; 1167 const argtype *arg_type;
1072 long ret; 1168 long ret;
1073 uint8_t buf_temp[MAX_STRUCT_SIZE]; 1169 uint8_t buf_temp[MAX_STRUCT_SIZE];
  1170 + int target_size;
  1171 + void *argptr;
1074 1172
1075 ie = ioctl_entries; 1173 ie = ioctl_entries;
1076 for(;;) { 1174 for(;;) {
@@ -1098,23 +1196,32 @@ static long do_ioctl(long fd, long cmd, long arg) @@ -1098,23 +1196,32 @@ static long do_ioctl(long fd, long cmd, long arg)
1098 break; 1196 break;
1099 case TYPE_PTR: 1197 case TYPE_PTR:
1100 arg_type++; 1198 arg_type++;
  1199 + target_size = thunk_type_size(arg_type, 0);
1101 switch(ie->access) { 1200 switch(ie->access) {
1102 case IOC_R: 1201 case IOC_R:
1103 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1202 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1104 if (!is_error(ret)) { 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 break; 1208 break;
1108 case IOC_W: 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 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1213 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1111 break; 1214 break;
1112 default: 1215 default:
1113 case IOC_RW: 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 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); 1220 ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
1116 if (!is_error(ret)) { 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 break; 1226 break;
1120 } 1227 }
@@ -1338,35 +1445,41 @@ static bitmask_transtbl fcntl_flags_tbl[] = { @@ -1338,35 +1445,41 @@ static bitmask_transtbl fcntl_flags_tbl[] = {
1338 /* NOTE: there is really one LDT for all the threads */ 1445 /* NOTE: there is really one LDT for all the threads */
1339 uint8_t *ldt_table; 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 int size; 1450 int size;
  1451 + void *p;
1344 1452
1345 if (!ldt_table) 1453 if (!ldt_table)
1346 return 0; 1454 return 0;
1347 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE; 1455 size = TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE;
1348 if (size > bytecount) 1456 if (size > bytecount)
1349 size = bytecount; 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 return size; 1462 return size;
1352 } 1463 }
1353 1464
1354 /* XXX: add locking support */ 1465 /* XXX: add locking support */
1355 static int write_ldt(CPUX86State *env, 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 struct target_modify_ldt_ldt_s ldt_info; 1469 struct target_modify_ldt_ldt_s ldt_info;
  1470 + struct target_modify_ldt_ldt_s *target_ldt_info;
1359 int seg_32bit, contents, read_exec_only, limit_in_pages; 1471 int seg_32bit, contents, read_exec_only, limit_in_pages;
1360 int seg_not_present, useable; 1472 int seg_not_present, useable;
1361 uint32_t *lp, entry_1, entry_2; 1473 uint32_t *lp, entry_1, entry_2;
1362 1474
1363 if (bytecount != sizeof(ldt_info)) 1475 if (bytecount != sizeof(ldt_info))
1364 return -EINVAL; 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 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES) 1484 if (ldt_info.entry_number >= TARGET_LDT_ENTRIES)
1372 return -EINVAL; 1485 return -EINVAL;
@@ -1389,7 +1502,7 @@ static int write_ldt(CPUX86State *env, @@ -1389,7 +1502,7 @@ static int write_ldt(CPUX86State *env,
1389 if (!ldt_table) 1502 if (!ldt_table)
1390 return -ENOMEM; 1503 return -ENOMEM;
1391 memset(ldt_table, 0, TARGET_LDT_ENTRIES * TARGET_LDT_ENTRY_SIZE); 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 env->ldt.limit = 0xffff; 1506 env->ldt.limit = 0xffff;
1394 } 1507 }
1395 1508
@@ -1432,7 +1545,7 @@ install: @@ -1432,7 +1545,7 @@ install:
1432 } 1545 }
1433 1546
1434 /* specific and weird i386 syscalls */ 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 int ret = -ENOSYS; 1550 int ret = -ENOSYS;
1438 1551
@@ -1523,31 +1636,35 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) @@ -1523,31 +1636,35 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
1523 return ret; 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 struct flock fl; 1641 struct flock fl;
1529 - struct target_flock *target_fl = (void *)arg; 1642 + struct target_flock *target_fl;
1530 long ret; 1643 long ret;
1531 - 1644 +
1532 switch(cmd) { 1645 switch(cmd) {
1533 case TARGET_F_GETLK: 1646 case TARGET_F_GETLK:
1534 ret = fcntl(fd, cmd, &fl); 1647 ret = fcntl(fd, cmd, &fl);
1535 if (ret == 0) { 1648 if (ret == 0) {
  1649 + lock_user_struct(target_fl, arg, 0);
1536 target_fl->l_type = tswap16(fl.l_type); 1650 target_fl->l_type = tswap16(fl.l_type);
1537 target_fl->l_whence = tswap16(fl.l_whence); 1651 target_fl->l_whence = tswap16(fl.l_whence);
1538 target_fl->l_start = tswapl(fl.l_start); 1652 target_fl->l_start = tswapl(fl.l_start);
1539 target_fl->l_len = tswapl(fl.l_len); 1653 target_fl->l_len = tswapl(fl.l_len);
1540 target_fl->l_pid = tswapl(fl.l_pid); 1654 target_fl->l_pid = tswapl(fl.l_pid);
  1655 + unlock_user_struct(target_fl, arg, 1);
1541 } 1656 }
1542 break; 1657 break;
1543 1658
1544 case TARGET_F_SETLK: 1659 case TARGET_F_SETLK:
1545 case TARGET_F_SETLKW: 1660 case TARGET_F_SETLKW:
  1661 + lock_user_struct(target_fl, arg, 1);
1546 fl.l_type = tswap16(target_fl->l_type); 1662 fl.l_type = tswap16(target_fl->l_type);
1547 fl.l_whence = tswap16(target_fl->l_whence); 1663 fl.l_whence = tswap16(target_fl->l_whence);
1548 fl.l_start = tswapl(target_fl->l_start); 1664 fl.l_start = tswapl(target_fl->l_start);
1549 fl.l_len = tswapl(target_fl->l_len); 1665 fl.l_len = tswapl(target_fl->l_len);
1550 fl.l_pid = tswapl(target_fl->l_pid); 1666 fl.l_pid = tswapl(target_fl->l_pid);
  1667 + unlock_user_struct(target_fl, arg, 0);
1551 ret = fcntl(fd, cmd, &fl); 1668 ret = fcntl(fd, cmd, &fl);
1552 break; 1669 break;
1553 1670
@@ -1690,12 +1807,35 @@ static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2, @@ -1690,12 +1807,35 @@ static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
1690 } 1807 }
1691 #endif 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 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 1832 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1694 long arg4, long arg5, long arg6) 1833 long arg4, long arg5, long arg6)
1695 { 1834 {
1696 long ret; 1835 long ret;
1697 struct stat st; 1836 struct stat st;
1698 struct statfs stfs; 1837 struct statfs stfs;
  1838 + void *p;
1699 1839
1700 #ifdef DEBUG 1840 #ifdef DEBUG
1701 gemu_log("syscall %d", num); 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,89 +1851,140 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1711 ret = 0; /* avoid warning */ 1851 ret = 0; /* avoid warning */
1712 break; 1852 break;
1713 case TARGET_NR_read: 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 break; 1858 break;
1717 case TARGET_NR_write: 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 break; 1863 break;
1720 case TARGET_NR_open: 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 target_to_host_bitmask(arg2, fcntl_flags_tbl), 1867 target_to_host_bitmask(arg2, fcntl_flags_tbl),
1723 arg3)); 1868 arg3));
  1869 + unlock_user(p, arg1, 0);
1724 break; 1870 break;
1725 case TARGET_NR_close: 1871 case TARGET_NR_close:
1726 ret = get_errno(close(arg1)); 1872 ret = get_errno(close(arg1));
1727 break; 1873 break;
1728 case TARGET_NR_brk: 1874 case TARGET_NR_brk:
1729 - ret = do_brk((char *)arg1); 1875 + ret = do_brk(arg1);
1730 break; 1876 break;
1731 case TARGET_NR_fork: 1877 case TARGET_NR_fork:
1732 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); 1878 ret = get_errno(do_fork(cpu_env, SIGCHLD, 0));
1733 break; 1879 break;
1734 case TARGET_NR_waitpid: 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 break; 1887 break;
1742 case TARGET_NR_creat: 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 break; 1892 break;
1745 case TARGET_NR_link: 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 break; 1902 break;
1748 case TARGET_NR_unlink: 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 break; 1907 break;
1751 case TARGET_NR_execve: 1908 case TARGET_NR_execve:
1752 { 1909 {
1753 char **argp, **envp; 1910 char **argp, **envp;
1754 int argc, envc; 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 char **q; 1916 char **q;
1757 1917
1758 argc = 0; 1918 argc = 0;
1759 - for (p = (void *)arg2; *p; p++) 1919 + guest_argp = arg2;
  1920 + for (gp = guest_argp; tgetl(gp); gp++)
1760 argc++; 1921 argc++;
1761 envc = 0; 1922 envc = 0;
1762 - for (p = (void *)arg3; *p; p++) 1923 + guest_envp = arg3;
  1924 + for (gp = guest_envp; tgetl(gp); gp++)
1763 envc++; 1925 envc++;
1764 1926
1765 argp = alloca((argc + 1) * sizeof(void *)); 1927 argp = alloca((argc + 1) * sizeof(void *));
1766 envp = alloca((envc + 1) * sizeof(void *)); 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 *q = NULL; 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 *q = NULL; 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 break; 1963 break;
1779 case TARGET_NR_chdir: 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 break; 1968 break;
1782 #ifdef TARGET_NR_time 1969 #ifdef TARGET_NR_time
1783 case TARGET_NR_time: 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 break; 1977 break;
1791 #endif 1978 #endif
1792 case TARGET_NR_mknod: 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 break; 1983 break;
1795 case TARGET_NR_chmod: 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 break; 1988 break;
1798 #ifdef TARGET_NR_break 1989 #ifdef TARGET_NR_break
1799 case TARGET_NR_break: 1990 case TARGET_NR_break:
@@ -1813,14 +2004,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1813,14 +2004,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1813 /* need to look at the data field */ 2004 /* need to look at the data field */
1814 goto unimplemented; 2005 goto unimplemented;
1815 case TARGET_NR_umount: 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 break; 2010 break;
1818 case TARGET_NR_stime: 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 break; 2017 break;
1826 case TARGET_NR_ptrace: 2018 case TARGET_NR_ptrace:
@@ -1837,30 +2029,36 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1837,30 +2029,36 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1837 break; 2029 break;
1838 case TARGET_NR_utime: 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 } else { 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 break; 2047 break;
1852 case TARGET_NR_utimes: 2048 case TARGET_NR_utimes:
1853 { 2049 {
1854 - struct target_timeval *target_tvp = (struct target_timeval *)arg2;  
1855 struct timeval *tvp, tv[2]; 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 tvp = tv; 2055 tvp = tv;
1860 } else { 2056 } else {
1861 tvp = NULL; 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 break; 2063 break;
1866 #ifdef TARGET_NR_stty 2064 #ifdef TARGET_NR_stty
@@ -1872,7 +2070,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1872,7 +2070,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1872 goto unimplemented; 2070 goto unimplemented;
1873 #endif 2071 #endif
1874 case TARGET_NR_access: 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 break; 2076 break;
1877 case TARGET_NR_nice: 2077 case TARGET_NR_nice:
1878 ret = get_errno(nice(arg1)); 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,33 +2089,45 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1889 ret = get_errno(kill(arg1, arg2)); 2089 ret = get_errno(kill(arg1, arg2));
1890 break; 2090 break;
1891 case TARGET_NR_rename: 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 break; 2100 break;
1894 case TARGET_NR_mkdir: 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 break; 2105 break;
1897 case TARGET_NR_rmdir: 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 break; 2110 break;
1900 case TARGET_NR_dup: 2111 case TARGET_NR_dup:
1901 ret = get_errno(dup(arg1)); 2112 ret = get_errno(dup(arg1));
1902 break; 2113 break;
1903 case TARGET_NR_pipe: 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 if (!is_error(ret)) { 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 break; 2123 break;
1913 case TARGET_NR_times: 2124 case TARGET_NR_times:
1914 { 2125 {
1915 - struct target_tms *tmsp = (void *)arg1; 2126 + struct target_tms *tmsp;
1916 struct tms tms; 2127 struct tms tms;
1917 ret = get_errno(times(&tms)); 2128 ret = get_errno(times(&tms));
1918 - if (tmsp) { 2129 + if (arg1) {
  2130 + tmsp = lock_user(arg1, sizeof(struct target_tms), 0);
1919 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime)); 2131 tmsp->tms_utime = tswapl(host_to_target_clock_t(tms.tms_utime));
1920 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime)); 2132 tmsp->tms_stime = tswapl(host_to_target_clock_t(tms.tms_stime));
1921 tmsp->tms_cutime = tswapl(host_to_target_clock_t(tms.tms_cutime)); 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,7 +2147,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1935 case TARGET_NR_acct: 2147 case TARGET_NR_acct:
1936 goto unimplemented; 2148 goto unimplemented;
1937 case TARGET_NR_umount2: 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 break; 2153 break;
1940 #ifdef TARGET_NR_lock 2154 #ifdef TARGET_NR_lock
1941 case TARGET_NR_lock: 2155 case TARGET_NR_lock:
@@ -1966,7 +2180,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1966,7 +2180,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1966 ret = get_errno(umask(arg1)); 2180 ret = get_errno(umask(arg1));
1967 break; 2181 break;
1968 case TARGET_NR_chroot: 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 break; 2186 break;
1971 case TARGET_NR_ustat: 2187 case TARGET_NR_ustat:
1972 goto unimplemented; 2188 goto unimplemented;
@@ -1984,29 +2200,49 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -1984,29 +2200,49 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1984 break; 2200 break;
1985 case TARGET_NR_sigaction: 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 struct target_sigaction act, oact, *pact; 2204 struct target_sigaction act, oact, *pact;
1990 - if (old_act) { 2205 + if (arg2) {
  2206 + lock_user_struct(old_act, arg2, 1);
1991 act._sa_handler = old_act->_sa_handler; 2207 act._sa_handler = old_act->_sa_handler;
1992 target_siginitset(&act.sa_mask, old_act->sa_mask); 2208 target_siginitset(&act.sa_mask, old_act->sa_mask);
1993 act.sa_flags = old_act->sa_flags; 2209 act.sa_flags = old_act->sa_flags;
1994 act.sa_restorer = old_act->sa_restorer; 2210 act.sa_restorer = old_act->sa_restorer;
  2211 + unlock_user_struct(old_act, arg2, 0);
1995 pact = &act; 2212 pact = &act;
1996 } else { 2213 } else {
1997 pact = NULL; 2214 pact = NULL;
1998 } 2215 }
1999 ret = get_errno(do_sigaction(arg1, pact, &oact)); 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 break; 2226 break;
2008 case TARGET_NR_rt_sigaction: 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 break; 2246 break;
2011 case TARGET_NR_sgetmask: 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,9 +2269,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2033 { 2269 {
2034 int how = arg1; 2270 int how = arg1;
2035 sigset_t set, oldset, *set_ptr; 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 switch(how) { 2274 switch(how) {
2040 case TARGET_SIG_BLOCK: 2275 case TARGET_SIG_BLOCK:
2041 how = SIG_BLOCK; 2276 how = SIG_BLOCK;
@@ -2050,15 +2285,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2050,15 +2285,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2050 ret = -EINVAL; 2285 ret = -EINVAL;
2051 goto fail; 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 set_ptr = &set; 2291 set_ptr = &set;
2055 } else { 2292 } else {
2056 how = 0; 2293 how = 0;
2057 set_ptr = NULL; 2294 set_ptr = NULL;
2058 } 2295 }
2059 ret = get_errno(sigprocmask(arg1, set_ptr, &oldset)); 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 break; 2303 break;
@@ -2066,10 +2305,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2066,10 +2305,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2066 { 2305 {
2067 int how = arg1; 2306 int how = arg1;
2068 sigset_t set, oldset, *set_ptr; 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 switch(how) { 2310 switch(how) {
2074 case TARGET_SIG_BLOCK: 2311 case TARGET_SIG_BLOCK:
2075 how = SIG_BLOCK; 2312 how = SIG_BLOCK;
@@ -2084,15 +2321,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2084,15 +2321,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2084 ret = -EINVAL; 2321 ret = -EINVAL;
2085 goto fail; 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 set_ptr = &set; 2327 set_ptr = &set;
2089 } else { 2328 } else {
2090 how = 0; 2329 how = 0;
2091 set_ptr = NULL; 2330 set_ptr = NULL;
2092 } 2331 }
2093 ret = get_errno(sigprocmask(how, set_ptr, &oldset)); 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 break; 2339 break;
@@ -2101,7 +2342,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2101,7 +2342,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2101 sigset_t set; 2342 sigset_t set;
2102 ret = get_errno(sigpending(&set)); 2343 ret = get_errno(sigpending(&set));
2103 if (!is_error(ret)) { 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 break; 2350 break;
@@ -2110,51 +2353,59 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2110,51 +2353,59 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2110 sigset_t set; 2353 sigset_t set;
2111 ret = get_errno(sigpending(&set)); 2354 ret = get_errno(sigpending(&set));
2112 if (!is_error(ret)) { 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 break; 2361 break;
2117 case TARGET_NR_sigsuspend: 2362 case TARGET_NR_sigsuspend:
2118 { 2363 {
2119 sigset_t set; 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 ret = get_errno(sigsuspend(&set)); 2368 ret = get_errno(sigsuspend(&set));
2122 } 2369 }
2123 break; 2370 break;
2124 case TARGET_NR_rt_sigsuspend: 2371 case TARGET_NR_rt_sigsuspend:
2125 { 2372 {
2126 sigset_t set; 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 ret = get_errno(sigsuspend(&set)); 2377 ret = get_errno(sigsuspend(&set));
2129 } 2378 }
2130 break; 2379 break;
2131 case TARGET_NR_rt_sigtimedwait: 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 sigset_t set; 2382 sigset_t set;
2137 struct timespec uts, *puts; 2383 struct timespec uts, *puts;
2138 siginfo_t uinfo; 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 puts = &uts; 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 } else { 2392 } else {
2146 puts = NULL; 2393 puts = NULL;
2147 } 2394 }
2148 ret = get_errno(sigtimedwait(&set, &uinfo, puts)); 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 break; 2402 break;
2154 case TARGET_NR_rt_sigqueueinfo: 2403 case TARGET_NR_rt_sigqueueinfo:
2155 { 2404 {
2156 siginfo_t uinfo; 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 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo)); 2409 ret = get_errno(sys_rt_sigqueueinfo(arg1, arg2, &uinfo));
2159 } 2410 }
2160 break; 2411 break;
@@ -2167,16 +2418,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2167,16 +2418,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2167 ret = do_rt_sigreturn(cpu_env); 2418 ret = do_rt_sigreturn(cpu_env);
2168 break; 2419 break;
2169 case TARGET_NR_sethostname: 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 break; 2424 break;
2172 case TARGET_NR_setrlimit: 2425 case TARGET_NR_setrlimit:
2173 { 2426 {
2174 /* XXX: convert resource ? */ 2427 /* XXX: convert resource ? */
2175 int resource = arg1; 2428 int resource = arg1;
2176 - struct target_rlimit *target_rlim = (void *)arg2; 2429 + struct target_rlimit *target_rlim;
2177 struct rlimit rlim; 2430 struct rlimit rlim;
  2431 + lock_user_struct(target_rlim, arg2, 1);
2178 rlim.rlim_cur = tswapl(target_rlim->rlim_cur); 2432 rlim.rlim_cur = tswapl(target_rlim->rlim_cur);
2179 rlim.rlim_max = tswapl(target_rlim->rlim_max); 2433 rlim.rlim_max = tswapl(target_rlim->rlim_max);
  2434 + unlock_user_struct(target_rlim, arg2, 0);
2180 ret = get_errno(setrlimit(resource, &rlim)); 2435 ret = get_errno(setrlimit(resource, &rlim));
2181 } 2436 }
2182 break; 2437 break;
@@ -2184,72 +2439,91 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2184,72 +2439,91 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2184 { 2439 {
2185 /* XXX: convert resource ? */ 2440 /* XXX: convert resource ? */
2186 int resource = arg1; 2441 int resource = arg1;
2187 - struct target_rlimit *target_rlim = (void *)arg2; 2442 + struct target_rlimit *target_rlim;
2188 struct rlimit rlim; 2443 struct rlimit rlim;
2189 2444
2190 ret = get_errno(getrlimit(resource, &rlim)); 2445 ret = get_errno(getrlimit(resource, &rlim));
2191 if (!is_error(ret)) { 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 break; 2453 break;
2197 case TARGET_NR_getrusage: 2454 case TARGET_NR_getrusage:
2198 { 2455 {
2199 struct rusage rusage; 2456 struct rusage rusage;
2200 - struct target_rusage *target_rusage = (void *)arg2;  
2201 ret = get_errno(getrusage(arg1, &rusage)); 2457 ret = get_errno(getrusage(arg1, &rusage));
2202 if (!is_error(ret)) { 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 break; 2462 break;
2207 case TARGET_NR_gettimeofday: 2463 case TARGET_NR_gettimeofday:
2208 { 2464 {
2209 - struct target_timeval *target_tv = (void *)arg1;  
2210 struct timeval tv; 2465 struct timeval tv;
2211 ret = get_errno(gettimeofday(&tv, NULL)); 2466 ret = get_errno(gettimeofday(&tv, NULL));
2212 if (!is_error(ret)) { 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 break; 2471 break;
2217 case TARGET_NR_settimeofday: 2472 case TARGET_NR_settimeofday:
2218 { 2473 {
2219 - struct target_timeval *target_tv = (void *)arg1;  
2220 struct timeval tv; 2474 struct timeval tv;
2221 - target_to_host_timeval(&tv, target_tv); 2475 + target_to_host_timeval(&tv, arg1);
2222 ret = get_errno(settimeofday(&tv, NULL)); 2476 ret = get_errno(settimeofday(&tv, NULL));
2223 } 2477 }
2224 break; 2478 break;
2225 #ifdef TARGET_NR_select 2479 #ifdef TARGET_NR_select
2226 case TARGET_NR_select: 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 break; 2495 break;
2238 #endif 2496 #endif
2239 case TARGET_NR_symlink: 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 break; 2506 break;
2242 #ifdef TARGET_NR_oldlstat 2507 #ifdef TARGET_NR_oldlstat
2243 case TARGET_NR_oldlstat: 2508 case TARGET_NR_oldlstat:
2244 goto unimplemented; 2509 goto unimplemented;
2245 #endif 2510 #endif
2246 case TARGET_NR_readlink: 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 break; 2520 break;
2249 case TARGET_NR_uselib: 2521 case TARGET_NR_uselib:
2250 goto unimplemented; 2522 goto unimplemented;
2251 case TARGET_NR_swapon: 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 break; 2527 break;
2254 case TARGET_NR_reboot: 2528 case TARGET_NR_reboot:
2255 goto unimplemented; 2529 goto unimplemented;
@@ -2258,14 +2532,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2258,14 +2532,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2258 case TARGET_NR_mmap: 2532 case TARGET_NR_mmap:
2259 #if defined(TARGET_I386) || defined(TARGET_ARM) 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 ret = get_errno(target_mmap(v1, v2, v3, 2545 ret = get_errno(target_mmap(v1, v2, v3,
2270 target_to_host_bitmask(v4, mmap_flags_tbl), 2546 target_to_host_bitmask(v4, mmap_flags_tbl),
2271 v5, v6)); 2547 v5, v6));
@@ -2299,14 +2575,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2299,14 +2575,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2299 case TARGET_NR_mremap: 2575 case TARGET_NR_mremap:
2300 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5)); 2576 ret = get_errno(target_mremap(arg1, arg2, arg3, arg4, arg5));
2301 break; 2577 break;
  2578 + /* ??? msync/mlock/munlock are broken for softmmu. */
2302 case TARGET_NR_msync: 2579 case TARGET_NR_msync:
2303 - ret = get_errno(msync((void *)arg1, arg2, arg3)); 2580 + ret = get_errno(msync(g2h(arg1), arg2, arg3));
2304 break; 2581 break;
2305 case TARGET_NR_mlock: 2582 case TARGET_NR_mlock:
2306 - ret = get_errno(mlock((void *)arg1, arg2)); 2583 + ret = get_errno(mlock(g2h(arg1), arg2));
2307 break; 2584 break;
2308 case TARGET_NR_munlock: 2585 case TARGET_NR_munlock:
2309 - ret = get_errno(munlock((void *)arg1, arg2)); 2586 + ret = get_errno(munlock(g2h(arg1), arg2));
2310 break; 2587 break;
2311 case TARGET_NR_mlockall: 2588 case TARGET_NR_mlockall:
2312 ret = get_errno(mlockall(arg1)); 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,7 +2592,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2315 ret = get_errno(munlockall()); 2592 ret = get_errno(munlockall());
2316 break; 2593 break;
2317 case TARGET_NR_truncate: 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 break; 2598 break;
2320 case TARGET_NR_ftruncate: 2599 case TARGET_NR_ftruncate:
2321 ret = get_errno(ftruncate(arg1, arg2)); 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,11 +2613,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2334 goto unimplemented; 2613 goto unimplemented;
2335 #endif 2614 #endif
2336 case TARGET_NR_statfs: 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 convert_statfs: 2619 convert_statfs:
2339 if (!is_error(ret)) { 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 put_user(stfs.f_type, &target_stfs->f_type); 2625 put_user(stfs.f_type, &target_stfs->f_type);
2343 put_user(stfs.f_bsize, &target_stfs->f_bsize); 2626 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2344 put_user(stfs.f_blocks, &target_stfs->f_blocks); 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,6 +2631,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2348 put_user(stfs.f_ffree, &target_stfs->f_ffree); 2631 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2349 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid); 2632 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2350 put_user(stfs.f_namelen, &target_stfs->f_namelen); 2633 put_user(stfs.f_namelen, &target_stfs->f_namelen);
  2634 + unlock_user_struct(target_stfs, arg2, 1);
2351 } 2635 }
2352 break; 2636 break;
2353 case TARGET_NR_fstatfs: 2637 case TARGET_NR_fstatfs:
@@ -2355,11 +2639,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2355,11 +2639,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2355 goto convert_statfs; 2639 goto convert_statfs;
2356 #ifdef TARGET_NR_statfs64 2640 #ifdef TARGET_NR_statfs64
2357 case TARGET_NR_statfs64: 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 convert_statfs64: 2645 convert_statfs64:
2360 if (!is_error(ret)) { 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 put_user(stfs.f_type, &target_stfs->f_type); 2651 put_user(stfs.f_type, &target_stfs->f_type);
2364 put_user(stfs.f_bsize, &target_stfs->f_bsize); 2652 put_user(stfs.f_bsize, &target_stfs->f_bsize);
2365 put_user(stfs.f_blocks, &target_stfs->f_blocks); 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,6 +2657,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2369 put_user(stfs.f_ffree, &target_stfs->f_ffree); 2657 put_user(stfs.f_ffree, &target_stfs->f_ffree);
2370 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid); 2658 put_user(stfs.f_fsid.__val[0], &target_stfs->f_fsid);
2371 put_user(stfs.f_namelen, &target_stfs->f_namelen); 2659 put_user(stfs.f_namelen, &target_stfs->f_namelen);
  2660 + unlock_user_struct(target_stfs, arg3, 0);
2372 } 2661 }
2373 break; 2662 break;
2374 case TARGET_NR_fstatfs64: 2663 case TARGET_NR_fstatfs64:
@@ -2380,60 +2669,63 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2380,60 +2669,63 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2380 goto unimplemented; 2669 goto unimplemented;
2381 #endif 2670 #endif
2382 case TARGET_NR_socketcall: 2671 case TARGET_NR_socketcall:
2383 - ret = do_socketcall(arg1, (int32_t *)arg2); 2672 + ret = do_socketcall(arg1, arg2);
2384 break; 2673 break;
2385 case TARGET_NR_syslog: 2674 case TARGET_NR_syslog:
2386 goto unimplemented; 2675 goto unimplemented;
2387 case TARGET_NR_setitimer: 2676 case TARGET_NR_setitimer:
2388 { 2677 {
2389 - struct target_itimerval *target_value = (void *)arg2;  
2390 - struct target_itimerval *target_ovalue = (void *)arg3;  
2391 struct itimerval value, ovalue, *pvalue; 2678 struct itimerval value, ovalue, *pvalue;
2392 2679
2393 - if (target_value) { 2680 + if (arg2) {
2394 pvalue = &value; 2681 pvalue = &value;
2395 target_to_host_timeval(&pvalue->it_interval, 2682 target_to_host_timeval(&pvalue->it_interval,
2396 - &target_value->it_interval); 2683 + arg2);
2397 target_to_host_timeval(&pvalue->it_value, 2684 target_to_host_timeval(&pvalue->it_value,
2398 - &target_value->it_value); 2685 + arg2 + sizeof(struct target_timeval));
2399 } else { 2686 } else {
2400 pvalue = NULL; 2687 pvalue = NULL;
2401 } 2688 }
2402 ret = get_errno(setitimer(arg1, pvalue, &ovalue)); 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 &ovalue.it_interval); 2692 &ovalue.it_interval);
2406 - host_to_target_timeval(&target_ovalue->it_value, 2693 + host_to_target_timeval(arg3 + sizeof(struct target_timeval),
2407 &ovalue.it_value); 2694 &ovalue.it_value);
2408 } 2695 }
2409 } 2696 }
2410 break; 2697 break;
2411 case TARGET_NR_getitimer: 2698 case TARGET_NR_getitimer:
2412 { 2699 {
2413 - struct target_itimerval *target_value = (void *)arg2;  
2414 struct itimerval value; 2700 struct itimerval value;
2415 2701
2416 ret = get_errno(getitimer(arg1, &value)); 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 &value.it_interval); 2705 &value.it_interval);
2420 - host_to_target_timeval(&target_value->it_value, 2706 + host_to_target_timeval(arg2 + sizeof(struct target_timeval),
2421 &value.it_value); 2707 &value.it_value);
2422 } 2708 }
2423 } 2709 }
2424 break; 2710 break;
2425 case TARGET_NR_stat: 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 goto do_stat; 2715 goto do_stat;
2428 case TARGET_NR_lstat: 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 goto do_stat; 2720 goto do_stat;
2431 case TARGET_NR_fstat: 2721 case TARGET_NR_fstat:
2432 { 2722 {
2433 ret = get_errno(fstat(arg1, &st)); 2723 ret = get_errno(fstat(arg1, &st));
2434 do_stat: 2724 do_stat:
2435 if (!is_error(ret)) { 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 target_st->st_dev = tswap16(st.st_dev); 2729 target_st->st_dev = tswap16(st.st_dev);
2438 target_st->st_ino = tswapl(st.st_ino); 2730 target_st->st_ino = tswapl(st.st_ino);
2439 #if defined(TARGET_PPC) 2731 #if defined(TARGET_PPC)
@@ -2453,6 +2745,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2453,6 +2745,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2453 target_st->target_st_atime = tswapl(st.st_atime); 2745 target_st->target_st_atime = tswapl(st.st_atime);
2454 target_st->target_st_mtime = tswapl(st.st_mtime); 2746 target_st->target_st_mtime = tswapl(st.st_mtime);
2455 target_st->target_st_ctime = tswapl(st.st_ctime); 2747 target_st->target_st_ctime = tswapl(st.st_ctime);
  2748 + unlock_user_struct(target_st, arg2, 1);
2456 } 2749 }
2457 } 2750 }
2458 break; 2751 break;
@@ -2479,9 +2772,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2479,9 +2772,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2479 case TARGET_NR_wait4: 2772 case TARGET_NR_wait4:
2480 { 2773 {
2481 int status; 2774 int status;
2482 - target_long *status_ptr = (void *)arg2; 2775 + target_long status_ptr = arg2;
2483 struct rusage rusage, *rusage_ptr; 2776 struct rusage rusage, *rusage_ptr;
2484 - struct target_rusage *target_rusage = (void *)arg4; 2777 + target_ulong target_rusage = arg4;
2485 if (target_rusage) 2778 if (target_rusage)
2486 rusage_ptr = &rusage; 2779 rusage_ptr = &rusage;
2487 else 2780 else
@@ -2489,7 +2782,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2489,7 +2782,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2489 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); 2782 ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr));
2490 if (!is_error(ret)) { 2783 if (!is_error(ret)) {
2491 if (status_ptr) 2784 if (status_ptr)
2492 - *status_ptr = tswap32(status); 2785 + tputl(status_ptr, status);
2493 if (target_rusage) { 2786 if (target_rusage) {
2494 host_to_target_rusage(target_rusage, &rusage); 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,15 +2790,19 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2497 } 2790 }
2498 break; 2791 break;
2499 case TARGET_NR_swapoff: 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 break; 2796 break;
2502 case TARGET_NR_sysinfo: 2797 case TARGET_NR_sysinfo:
2503 { 2798 {
2504 - struct target_sysinfo *target_value = (void *)arg1; 2799 + struct target_sysinfo *target_value;
2505 struct sysinfo value; 2800 struct sysinfo value;
2506 ret = get_errno(sysinfo(&value)); 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 __put_user(value.uptime, &target_value->uptime); 2806 __put_user(value.uptime, &target_value->uptime);
2510 __put_user(value.loads[0], &target_value->loads[0]); 2807 __put_user(value.loads[0], &target_value->loads[0]);
2511 __put_user(value.loads[1], &target_value->loads[1]); 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,6 +2817,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2520 __put_user(value.totalhigh, &target_value->totalhigh); 2817 __put_user(value.totalhigh, &target_value->totalhigh);
2521 __put_user(value.freehigh, &target_value->freehigh); 2818 __put_user(value.freehigh, &target_value->freehigh);
2522 __put_user(value.mem_unit, &target_value->mem_unit); 2819 __put_user(value.mem_unit, &target_value->mem_unit);
  2820 + unlock_user_struct(target_value, arg1, 1);
2523 } 2821 }
2524 } 2822 }
2525 break; 2823 break;
@@ -2540,30 +2838,33 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2540,30 +2838,33 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2540 break; 2838 break;
2541 #endif 2839 #endif
2542 case TARGET_NR_setdomainname: 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 break; 2844 break;
2545 case TARGET_NR_uname: 2845 case TARGET_NR_uname:
2546 /* no need to transcode because we use the linux syscall */ 2846 /* no need to transcode because we use the linux syscall */
2547 { 2847 {
2548 struct new_utsname * buf; 2848 struct new_utsname * buf;
2549 2849
2550 - buf = (struct new_utsname *)arg1; 2850 + lock_user_struct(buf, arg1, 0);
2551 ret = get_errno(sys_uname(buf)); 2851 ret = get_errno(sys_uname(buf));
2552 if (!is_error(ret)) { 2852 if (!is_error(ret)) {
2553 /* Overrite the native machine name with whatever is being 2853 /* Overrite the native machine name with whatever is being
2554 emulated. */ 2854 emulated. */
2555 strcpy (buf->machine, UNAME_MACHINE); 2855 strcpy (buf->machine, UNAME_MACHINE);
2556 } 2856 }
  2857 + unlock_user_struct(buf, arg1, 1);
2557 } 2858 }
2558 break; 2859 break;
2559 #ifdef TARGET_I386 2860 #ifdef TARGET_I386
2560 case TARGET_NR_modify_ldt: 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 break; 2863 break;
2563 case TARGET_NR_vm86old: 2864 case TARGET_NR_vm86old:
2564 goto unimplemented; 2865 goto unimplemented;
2565 case TARGET_NR_vm86: 2866 case TARGET_NR_vm86:
2566 - ret = do_vm86(cpu_env, arg1, (void *)arg2); 2867 + ret = do_vm86(cpu_env, arg1, arg2);
2567 break; 2868 break;
2568 #endif 2869 #endif
2569 case TARGET_NR_adjtimex: 2870 case TARGET_NR_adjtimex:
@@ -2594,20 +2895,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2594,20 +2895,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2594 { 2895 {
2595 #if defined (__x86_64__) 2896 #if defined (__x86_64__)
2596 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5)); 2897 ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
2597 - *(int64_t *)arg4 = ret; 2898 + tput64(arg4, ret);
2598 #else 2899 #else
2599 int64_t res; 2900 int64_t res;
2600 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5)); 2901 ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
2601 - *(int64_t *)arg4 = tswap64(res); 2902 + tput64(arg4, res);
2602 #endif 2903 #endif
2603 } 2904 }
2604 break; 2905 break;
2605 case TARGET_NR_getdents: 2906 case TARGET_NR_getdents:
2606 #if TARGET_LONG_SIZE != 4 2907 #if TARGET_LONG_SIZE != 4
  2908 + goto unimplemented;
2607 #warning not supported 2909 #warning not supported
2608 #elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8 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 struct dirent *dirp; 2913 struct dirent *dirp;
2612 long count = arg3; 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,6 +2927,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2625 2927
2626 count1 = 0; 2928 count1 = 0;
2627 de = dirp; 2929 de = dirp;
  2930 + target_dirp = lock_user(arg2, count, 0);
2628 tde = target_dirp; 2931 tde = target_dirp;
2629 while (len > 0) { 2932 while (len > 0) {
2630 reclen = de->d_reclen; 2933 reclen = de->d_reclen;
@@ -2644,13 +2947,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2644,13 +2947,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2644 } 2947 }
2645 ret = count1; 2948 ret = count1;
2646 } 2949 }
  2950 + unlock_user(target_dirp, arg2, ret);
2647 free(dirp); 2951 free(dirp);
2648 } 2952 }
2649 #else 2953 #else
2650 { 2954 {
2651 - struct dirent *dirp = (void *)arg2; 2955 + struct dirent *dirp;
2652 long count = arg3; 2956 long count = arg3;
2653 2957
  2958 + dirp = lock_user(arg2, count, 0);
2654 ret = get_errno(sys_getdents(arg1, dirp, count)); 2959 ret = get_errno(sys_getdents(arg1, dirp, count));
2655 if (!is_error(ret)) { 2960 if (!is_error(ret)) {
2656 struct dirent *de; 2961 struct dirent *de;
@@ -2668,14 +2973,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2668,14 +2973,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2668 len -= reclen; 2973 len -= reclen;
2669 } 2974 }
2670 } 2975 }
  2976 + unlock_user(dirp, arg2, ret);
2671 } 2977 }
2672 #endif 2978 #endif
2673 break; 2979 break;
2674 #ifdef TARGET_NR_getdents64 2980 #ifdef TARGET_NR_getdents64
2675 case TARGET_NR_getdents64: 2981 case TARGET_NR_getdents64:
2676 { 2982 {
2677 - struct dirent64 *dirp = (void *)arg2; 2983 + struct dirent64 *dirp;
2678 long count = arg3; 2984 long count = arg3;
  2985 + dirp = lock_user(arg2, count, 0);
2679 ret = get_errno(sys_getdents64(arg1, dirp, count)); 2986 ret = get_errno(sys_getdents64(arg1, dirp, count));
2680 if (!is_error(ret)) { 2987 if (!is_error(ret)) {
2681 struct dirent64 *de; 2988 struct dirent64 *de;
@@ -2693,21 +3000,22 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2693,21 +3000,22 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2693 len -= reclen; 3000 len -= reclen;
2694 } 3001 }
2695 } 3002 }
  3003 + unlock_user(dirp, arg2, ret);
2696 } 3004 }
2697 break; 3005 break;
2698 #endif /* TARGET_NR_getdents64 */ 3006 #endif /* TARGET_NR_getdents64 */
2699 case TARGET_NR__newselect: 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 break; 3009 break;
2703 case TARGET_NR_poll: 3010 case TARGET_NR_poll:
2704 { 3011 {
2705 - struct target_pollfd *target_pfd = (void *)arg1; 3012 + struct target_pollfd *target_pfd;
2706 unsigned int nfds = arg2; 3013 unsigned int nfds = arg2;
2707 int timeout = arg3; 3014 int timeout = arg3;
2708 struct pollfd *pfd; 3015 struct pollfd *pfd;
2709 unsigned int i; 3016 unsigned int i;
2710 3017
  3018 + target_pfd = lock_user(arg1, sizeof(struct target_pollfd) * nfds, 1);
2711 pfd = alloca(sizeof(struct pollfd) * nfds); 3019 pfd = alloca(sizeof(struct pollfd) * nfds);
2712 for(i = 0; i < nfds; i++) { 3020 for(i = 0; i < nfds; i++) {
2713 pfd[i].fd = tswap32(target_pfd[i].fd); 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,7 +3026,10 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2718 for(i = 0; i < nfds; i++) { 3026 for(i = 0; i < nfds; i++) {
2719 target_pfd[i].revents = tswap16(pfd[i].revents); 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 break; 3034 break;
2724 case TARGET_NR_flock: 3035 case TARGET_NR_flock:
@@ -2729,31 +3040,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2729,31 +3040,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2729 case TARGET_NR_readv: 3040 case TARGET_NR_readv:
2730 { 3041 {
2731 int count = arg3; 3042 int count = arg3;
2732 - int i;  
2733 struct iovec *vec; 3043 struct iovec *vec;
2734 - struct target_iovec *target_vec = (void *)arg2;  
2735 3044
2736 vec = alloca(count * sizeof(struct iovec)); 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 ret = get_errno(readv(arg1, vec, count)); 3047 ret = get_errno(readv(arg1, vec, count));
  3048 + unlock_iovec(vec, arg2, count, 1);
2742 } 3049 }
2743 break; 3050 break;
2744 case TARGET_NR_writev: 3051 case TARGET_NR_writev:
2745 { 3052 {
2746 int count = arg3; 3053 int count = arg3;
2747 - int i;  
2748 struct iovec *vec; 3054 struct iovec *vec;
2749 - struct target_iovec *target_vec = (void *)arg2;  
2750 3055
2751 vec = alloca(count * sizeof(struct iovec)); 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 ret = get_errno(writev(arg1, vec, count)); 3058 ret = get_errno(writev(arg1, vec, count));
  3059 + unlock_iovec(vec, arg2, count, 0);
2757 } 3060 }
2758 break; 3061 break;
2759 case TARGET_NR_getsid: 3062 case TARGET_NR_getsid:
@@ -2768,27 +3071,34 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2768,27 +3071,34 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2768 return -ENOTDIR; 3071 return -ENOTDIR;
2769 case TARGET_NR_sched_setparam: 3072 case TARGET_NR_sched_setparam:
2770 { 3073 {
2771 - struct sched_param *target_schp = (void *)arg2; 3074 + struct sched_param *target_schp;
2772 struct sched_param schp; 3075 struct sched_param schp;
  3076 +
  3077 + lock_user_struct(target_schp, arg2, 1);
2773 schp.sched_priority = tswap32(target_schp->sched_priority); 3078 schp.sched_priority = tswap32(target_schp->sched_priority);
  3079 + unlock_user_struct(target_schp, arg2, 0);
2774 ret = get_errno(sched_setparam(arg1, &schp)); 3080 ret = get_errno(sched_setparam(arg1, &schp));
2775 } 3081 }
2776 break; 3082 break;
2777 case TARGET_NR_sched_getparam: 3083 case TARGET_NR_sched_getparam:
2778 { 3084 {
2779 - struct sched_param *target_schp = (void *)arg2; 3085 + struct sched_param *target_schp;
2780 struct sched_param schp; 3086 struct sched_param schp;
2781 ret = get_errno(sched_getparam(arg1, &schp)); 3087 ret = get_errno(sched_getparam(arg1, &schp));
2782 if (!is_error(ret)) { 3088 if (!is_error(ret)) {
  3089 + lock_user_struct(target_schp, arg2, 0);
2783 target_schp->sched_priority = tswap32(schp.sched_priority); 3090 target_schp->sched_priority = tswap32(schp.sched_priority);
  3091 + unlock_user_struct(target_schp, arg2, 1);
2784 } 3092 }
2785 } 3093 }
2786 break; 3094 break;
2787 case TARGET_NR_sched_setscheduler: 3095 case TARGET_NR_sched_setscheduler:
2788 { 3096 {
2789 - struct sched_param *target_schp = (void *)arg3; 3097 + struct sched_param *target_schp;
2790 struct sched_param schp; 3098 struct sched_param schp;
  3099 + lock_user_struct(target_schp, arg3, 1);
2791 schp.sched_priority = tswap32(target_schp->sched_priority); 3100 schp.sched_priority = tswap32(target_schp->sched_priority);
  3101 + unlock_user_struct(target_schp, arg3, 0);
2792 ret = get_errno(sched_setscheduler(arg1, arg2, &schp)); 3102 ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
2793 } 3103 }
2794 break; 3104 break;
@@ -2806,26 +3116,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2806,26 +3116,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2806 break; 3116 break;
2807 case TARGET_NR_sched_rr_get_interval: 3117 case TARGET_NR_sched_rr_get_interval:
2808 { 3118 {
2809 - struct target_timespec *target_ts = (void *)arg2;  
2810 struct timespec ts; 3119 struct timespec ts;
2811 ret = get_errno(sched_rr_get_interval(arg1, &ts)); 3120 ret = get_errno(sched_rr_get_interval(arg1, &ts));
2812 if (!is_error(ret)) { 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 break; 3125 break;
2818 case TARGET_NR_nanosleep: 3126 case TARGET_NR_nanosleep:
2819 { 3127 {
2820 - struct target_timespec *target_req = (void *)arg1;  
2821 - struct target_timespec *target_rem = (void *)arg2;  
2822 struct timespec req, rem; 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 ret = get_errno(nanosleep(&req, &rem)); 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 break; 3135 break;
@@ -2837,15 +3141,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2837,15 +3141,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2837 goto unimplemented; 3141 goto unimplemented;
2838 #ifdef TARGET_NR_pread 3142 #ifdef TARGET_NR_pread
2839 case TARGET_NR_pread: 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 break; 3148 break;
2843 case TARGET_NR_pwrite: 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 break; 3153 break;
2846 #endif 3154 #endif
2847 case TARGET_NR_getcwd: 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 break; 3159 break;
2850 case TARGET_NR_capget: 3160 case TARGET_NR_capget:
2851 goto unimplemented; 3161 goto unimplemented;
@@ -2874,16 +3184,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2874,16 +3184,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2874 struct rlimit rlim; 3184 struct rlimit rlim;
2875 ret = get_errno(getrlimit(arg1, &rlim)); 3185 ret = get_errno(getrlimit(arg1, &rlim));
2876 if (!is_error(ret)) { 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 target_rlim->rlim_cur = tswapl(rlim.rlim_cur); 3189 target_rlim->rlim_cur = tswapl(rlim.rlim_cur);
2879 target_rlim->rlim_max = tswapl(rlim.rlim_max); 3190 target_rlim->rlim_max = tswapl(rlim.rlim_max);
  3191 + unlock_user_struct(target_rlim, arg2, 1);
2880 } 3192 }
2881 break; 3193 break;
2882 } 3194 }
2883 #endif 3195 #endif
2884 #ifdef TARGET_NR_truncate64 3196 #ifdef TARGET_NR_truncate64
2885 case TARGET_NR_truncate64: 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 break; 3201 break;
2888 #endif 3202 #endif
2889 #ifdef TARGET_NR_ftruncate64 3203 #ifdef TARGET_NR_ftruncate64
@@ -2893,12 +3207,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2893,12 +3207,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2893 #endif 3207 #endif
2894 #ifdef TARGET_NR_stat64 3208 #ifdef TARGET_NR_stat64
2895 case TARGET_NR_stat64: 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 goto do_stat64; 3213 goto do_stat64;
2898 #endif 3214 #endif
2899 #ifdef TARGET_NR_lstat64 3215 #ifdef TARGET_NR_lstat64
2900 case TARGET_NR_lstat64: 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 goto do_stat64; 3220 goto do_stat64;
2903 #endif 3221 #endif
2904 #ifdef TARGET_NR_fstat64 3222 #ifdef TARGET_NR_fstat64
@@ -2909,8 +3227,10 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2909,8 +3227,10 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2909 if (!is_error(ret)) { 3227 if (!is_error(ret)) {
2910 #ifdef TARGET_ARM 3228 #ifdef TARGET_ARM
2911 if (((CPUARMState *)cpu_env)->eabi) { 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 memset(target_st, 0, sizeof(struct target_eabi_stat64)); 3232 memset(target_st, 0, sizeof(struct target_eabi_stat64));
  3233 + /* put_user is probably wrong. */
2914 put_user(st.st_dev, &target_st->st_dev); 3234 put_user(st.st_dev, &target_st->st_dev);
2915 put_user(st.st_ino, &target_st->st_ino); 3235 put_user(st.st_ino, &target_st->st_ino);
2916 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 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,11 +3248,14 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2928 put_user(st.st_atime, &target_st->target_st_atime); 3248 put_user(st.st_atime, &target_st->target_st_atime);
2929 put_user(st.st_mtime, &target_st->target_st_mtime); 3249 put_user(st.st_mtime, &target_st->target_st_mtime);
2930 put_user(st.st_ctime, &target_st->target_st_ctime); 3250 put_user(st.st_ctime, &target_st->target_st_ctime);
  3251 + unlock_user_struct(target_st, arg2, 0);
2931 } else 3252 } else
2932 #endif 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 memset(target_st, 0, sizeof(struct target_stat64)); 3257 memset(target_st, 0, sizeof(struct target_stat64));
  3258 + /* ??? put_user is probably wrong. */
2936 put_user(st.st_dev, &target_st->st_dev); 3259 put_user(st.st_dev, &target_st->st_dev);
2937 put_user(st.st_ino, &target_st->st_ino); 3260 put_user(st.st_ino, &target_st->st_ino);
2938 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 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,6 +3273,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2950 put_user(st.st_atime, &target_st->target_st_atime); 3273 put_user(st.st_atime, &target_st->target_st_atime);
2951 put_user(st.st_mtime, &target_st->target_st_mtime); 3274 put_user(st.st_mtime, &target_st->target_st_mtime);
2952 put_user(st.st_ctime, &target_st->target_st_ctime); 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,7 +3281,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2957 #endif 3281 #endif
2958 #ifdef USE_UID16 3282 #ifdef USE_UID16
2959 case TARGET_NR_lchown: 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 break; 3287 break;
2962 case TARGET_NR_getuid: 3288 case TARGET_NR_getuid:
2963 ret = get_errno(high2lowuid(getuid())); 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,28 +3306,32 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2980 case TARGET_NR_getgroups: 3306 case TARGET_NR_getgroups:
2981 { 3307 {
2982 int gidsetsize = arg1; 3308 int gidsetsize = arg1;
2983 - uint16_t *target_grouplist = (void *)arg2; 3309 + uint16_t *target_grouplist;
2984 gid_t *grouplist; 3310 gid_t *grouplist;
2985 int i; 3311 int i;
2986 3312
2987 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3313 grouplist = alloca(gidsetsize * sizeof(gid_t));
2988 ret = get_errno(getgroups(gidsetsize, grouplist)); 3314 ret = get_errno(getgroups(gidsetsize, grouplist));
2989 if (!is_error(ret)) { 3315 if (!is_error(ret)) {
  3316 + target_grouplist = lock_user(arg2, gidsetsize * 2, 0);
2990 for(i = 0;i < gidsetsize; i++) 3317 for(i = 0;i < gidsetsize; i++)
2991 target_grouplist[i] = tswap16(grouplist[i]); 3318 target_grouplist[i] = tswap16(grouplist[i]);
  3319 + unlock_user(target_grouplist, arg2, gidsetsize * 2);
2992 } 3320 }
2993 } 3321 }
2994 break; 3322 break;
2995 case TARGET_NR_setgroups: 3323 case TARGET_NR_setgroups:
2996 { 3324 {
2997 int gidsetsize = arg1; 3325 int gidsetsize = arg1;
2998 - uint16_t *target_grouplist = (void *)arg2; 3326 + uint16_t *target_grouplist;
2999 gid_t *grouplist; 3327 gid_t *grouplist;
3000 int i; 3328 int i;
3001 3329
3002 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3330 grouplist = alloca(gidsetsize * sizeof(gid_t));
  3331 + target_grouplist = lock_user(arg2, gidsetsize * 2, 1);
3003 for(i = 0;i < gidsetsize; i++) 3332 for(i = 0;i < gidsetsize; i++)
3004 grouplist[i] = tswap16(target_grouplist[i]); 3333 grouplist[i] = tswap16(target_grouplist[i]);
  3334 + unlock_user(target_grouplist, arg2, 0);
3005 ret = get_errno(setgroups(gidsetsize, grouplist)); 3335 ret = get_errno(setgroups(gidsetsize, grouplist));
3006 } 3336 }
3007 break; 3337 break;
@@ -3018,12 +3348,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3018,12 +3348,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3018 #ifdef TARGET_NR_getresuid 3348 #ifdef TARGET_NR_getresuid
3019 case TARGET_NR_getresuid: 3349 case TARGET_NR_getresuid:
3020 { 3350 {
3021 - int ruid, euid, suid; 3351 + uid_t ruid, euid, suid;
3022 ret = get_errno(getresuid(&ruid, &euid, &suid)); 3352 ret = get_errno(getresuid(&ruid, &euid, &suid));
3023 if (!is_error(ret)) { 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 break; 3359 break;
@@ -3038,18 +3368,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3038,18 +3368,20 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3038 #ifdef TARGET_NR_getresgid 3368 #ifdef TARGET_NR_getresgid
3039 case TARGET_NR_getresgid: 3369 case TARGET_NR_getresgid:
3040 { 3370 {
3041 - int rgid, egid, sgid; 3371 + gid_t rgid, egid, sgid;
3042 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 3372 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3043 if (!is_error(ret)) { 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 break; 3379 break;
3050 #endif 3380 #endif
3051 case TARGET_NR_chown: 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 break; 3385 break;
3054 case TARGET_NR_setuid: 3386 case TARGET_NR_setuid:
3055 ret = get_errno(setuid(low2highuid(arg1))); 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,7 +3399,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3067 3399
3068 #ifdef TARGET_NR_lchown32 3400 #ifdef TARGET_NR_lchown32
3069 case TARGET_NR_lchown32: 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 break; 3405 break;
3072 #endif 3406 #endif
3073 #ifdef TARGET_NR_getuid32 3407 #ifdef TARGET_NR_getuid32
@@ -3104,15 +3438,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3104,15 +3438,17 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3104 case TARGET_NR_getgroups32: 3438 case TARGET_NR_getgroups32:
3105 { 3439 {
3106 int gidsetsize = arg1; 3440 int gidsetsize = arg1;
3107 - uint32_t *target_grouplist = (void *)arg2; 3441 + uint32_t *target_grouplist;
3108 gid_t *grouplist; 3442 gid_t *grouplist;
3109 int i; 3443 int i;
3110 3444
3111 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3445 grouplist = alloca(gidsetsize * sizeof(gid_t));
3112 ret = get_errno(getgroups(gidsetsize, grouplist)); 3446 ret = get_errno(getgroups(gidsetsize, grouplist));
3113 if (!is_error(ret)) { 3447 if (!is_error(ret)) {
  3448 + target_grouplist = lock_user(arg2, gidsetsize * 4, 0);
3114 for(i = 0;i < gidsetsize; i++) 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 break; 3454 break;
@@ -3121,13 +3457,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3121,13 +3457,15 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3121 case TARGET_NR_setgroups32: 3457 case TARGET_NR_setgroups32:
3122 { 3458 {
3123 int gidsetsize = arg1; 3459 int gidsetsize = arg1;
3124 - uint32_t *target_grouplist = (void *)arg2; 3460 + uint32_t *target_grouplist;
3125 gid_t *grouplist; 3461 gid_t *grouplist;
3126 int i; 3462 int i;
3127 3463
3128 grouplist = alloca(gidsetsize * sizeof(gid_t)); 3464 grouplist = alloca(gidsetsize * sizeof(gid_t));
  3465 + target_grouplist = lock_user(arg2, gidsetsize * 4, 1);
3129 for(i = 0;i < gidsetsize; i++) 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 ret = get_errno(setgroups(gidsetsize, grouplist)); 3469 ret = get_errno(setgroups(gidsetsize, grouplist));
3132 } 3470 }
3133 break; 3471 break;
@@ -3145,12 +3483,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3145,12 +3483,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3145 #ifdef TARGET_NR_getresuid32 3483 #ifdef TARGET_NR_getresuid32
3146 case TARGET_NR_getresuid32: 3484 case TARGET_NR_getresuid32:
3147 { 3485 {
3148 - int ruid, euid, suid; 3486 + uid_t ruid, euid, suid;
3149 ret = get_errno(getresuid(&ruid, &euid, &suid)); 3487 ret = get_errno(getresuid(&ruid, &euid, &suid));
3150 if (!is_error(ret)) { 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 break; 3494 break;
@@ -3163,19 +3501,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3163,19 +3501,21 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3163 #ifdef TARGET_NR_getresgid32 3501 #ifdef TARGET_NR_getresgid32
3164 case TARGET_NR_getresgid32: 3502 case TARGET_NR_getresgid32:
3165 { 3503 {
3166 - int rgid, egid, sgid; 3504 + gid_t rgid, egid, sgid;
3167 ret = get_errno(getresgid(&rgid, &egid, &sgid)); 3505 ret = get_errno(getresgid(&rgid, &egid, &sgid));
3168 if (!is_error(ret)) { 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 break; 3512 break;
3175 #endif 3513 #endif
3176 #ifdef TARGET_NR_chown32 3514 #ifdef TARGET_NR_chown32
3177 case TARGET_NR_chown32: 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 break; 3519 break;
3180 #endif 3520 #endif
3181 #ifdef TARGET_NR_setuid32 3521 #ifdef TARGET_NR_setuid32
@@ -3213,9 +3553,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3213,9 +3553,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3213 case TARGET_NR_fcntl64: 3553 case TARGET_NR_fcntl64:
3214 { 3554 {
3215 struct flock64 fl; 3555 struct flock64 fl;
3216 - struct target_flock64 *target_fl = (void *)arg3; 3556 + struct target_flock64 *target_fl;
3217 #ifdef TARGET_ARM 3557 #ifdef TARGET_ARM
3218 - struct target_eabi_flock64 *target_efl = (void *)arg3; 3558 + struct target_eabi_flock64 *target_efl;
3219 #endif 3559 #endif
3220 3560
3221 switch(arg2) { 3561 switch(arg2) {
@@ -3224,19 +3564,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3224,19 +3564,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3224 if (ret == 0) { 3564 if (ret == 0) {
3225 #ifdef TARGET_ARM 3565 #ifdef TARGET_ARM
3226 if (((CPUARMState *)cpu_env)->eabi) { 3566 if (((CPUARMState *)cpu_env)->eabi) {
  3567 + lock_user_struct(target_efl, arg3, 0);
3227 target_efl->l_type = tswap16(fl.l_type); 3568 target_efl->l_type = tswap16(fl.l_type);
3228 target_efl->l_whence = tswap16(fl.l_whence); 3569 target_efl->l_whence = tswap16(fl.l_whence);
3229 target_efl->l_start = tswap64(fl.l_start); 3570 target_efl->l_start = tswap64(fl.l_start);
3230 target_efl->l_len = tswap64(fl.l_len); 3571 target_efl->l_len = tswap64(fl.l_len);
3231 target_efl->l_pid = tswapl(fl.l_pid); 3572 target_efl->l_pid = tswapl(fl.l_pid);
  3573 + unlock_user_struct(target_efl, arg3, 1);
3232 } else 3574 } else
3233 #endif 3575 #endif
3234 { 3576 {
  3577 + lock_user_struct(target_fl, arg3, 0);
3235 target_fl->l_type = tswap16(fl.l_type); 3578 target_fl->l_type = tswap16(fl.l_type);
3236 target_fl->l_whence = tswap16(fl.l_whence); 3579 target_fl->l_whence = tswap16(fl.l_whence);
3237 target_fl->l_start = tswap64(fl.l_start); 3580 target_fl->l_start = tswap64(fl.l_start);
3238 target_fl->l_len = tswap64(fl.l_len); 3581 target_fl->l_len = tswap64(fl.l_len);
3239 target_fl->l_pid = tswapl(fl.l_pid); 3582 target_fl->l_pid = tswapl(fl.l_pid);
  3583 + unlock_user_struct(target_fl, arg3, 1);
3240 } 3584 }
3241 } 3585 }
3242 break; 3586 break;
@@ -3245,19 +3589,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3245,19 +3589,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3245 case F_SETLKW64: 3589 case F_SETLKW64:
3246 #ifdef TARGET_ARM 3590 #ifdef TARGET_ARM
3247 if (((CPUARMState *)cpu_env)->eabi) { 3591 if (((CPUARMState *)cpu_env)->eabi) {
  3592 + lock_user_struct(target_efl, arg3, 1);
3248 fl.l_type = tswap16(target_efl->l_type); 3593 fl.l_type = tswap16(target_efl->l_type);
3249 fl.l_whence = tswap16(target_efl->l_whence); 3594 fl.l_whence = tswap16(target_efl->l_whence);
3250 fl.l_start = tswap64(target_efl->l_start); 3595 fl.l_start = tswap64(target_efl->l_start);
3251 fl.l_len = tswap64(target_efl->l_len); 3596 fl.l_len = tswap64(target_efl->l_len);
3252 fl.l_pid = tswapl(target_efl->l_pid); 3597 fl.l_pid = tswapl(target_efl->l_pid);
  3598 + unlock_user_struct(target_efl, arg3, 0);
3253 } else 3599 } else
3254 #endif 3600 #endif
3255 { 3601 {
  3602 + lock_user_struct(target_fl, arg3, 1);
3256 fl.l_type = tswap16(target_fl->l_type); 3603 fl.l_type = tswap16(target_fl->l_type);
3257 fl.l_whence = tswap16(target_fl->l_whence); 3604 fl.l_whence = tswap16(target_fl->l_whence);
3258 fl.l_start = tswap64(target_fl->l_start); 3605 fl.l_start = tswap64(target_fl->l_start);
3259 fl.l_len = tswap64(target_fl->l_len); 3606 fl.l_len = tswap64(target_fl->l_len);
3260 fl.l_pid = tswapl(target_fl->l_pid); 3607 fl.l_pid = tswapl(target_fl->l_pid);
  3608 + unlock_user_struct(target_fl, arg3, 0);
3261 } 3609 }
3262 ret = get_errno(fcntl(arg1, arg2, &fl)); 3610 ret = get_errno(fcntl(arg1, arg2, &fl));
3263 break; 3611 break;
linux-user/syscall_types.h
@@ -68,6 +68,9 @@ STRUCT(dirent, @@ -68,6 +68,9 @@ STRUCT(dirent,
68 STRUCT(kbentry, 68 STRUCT(kbentry,
69 TYPE_CHAR, TYPE_CHAR, TYPE_SHORT) 69 TYPE_CHAR, TYPE_CHAR, TYPE_SHORT)
70 70
  71 +STRUCT(kbsentry,
  72 + TYPE_CHAR, MK_ARRAY(TYPE_CHAR, 512))
  73 +
71 STRUCT(audio_buf_info, 74 STRUCT(audio_buf_info,
72 TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT) 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,25 +62,28 @@ static inline unsigned int vm_getl(uint8_t *segptr, unsigned int reg16)
62 void save_v86_state(CPUX86State *env) 62 void save_v86_state(CPUX86State *env)
63 { 63 {
64 TaskState *ts = env->opaque; 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 /* put the VM86 registers in the userspace register structure */ 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 set_flags(env->eflags, ts->v86flags, VIF_MASK | ts->v86mask); 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 #ifdef DEBUG_VM86 87 #ifdef DEBUG_VM86
85 fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n", 88 fprintf(logfile, "save_v86_state: eflags=%08x cs:ip=%04x:%04x\n",
86 env->eflags, env->segs[R_CS].selector, env->eip); 89 env->eflags, env->segs[R_CS].selector, env->eip);
@@ -378,10 +381,10 @@ void handle_vm86_fault(CPUX86State *env) @@ -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 TaskState *ts = env->opaque; 386 TaskState *ts = env->opaque;
  387 + struct target_vm86plus_struct * target_v86;
385 int ret; 388 int ret;
386 389
387 switch (subfunction) { 390 switch (subfunction) {
@@ -402,7 +405,6 @@ int do_vm86(CPUX86State *env, long subfunction, @@ -402,7 +405,6 @@ int do_vm86(CPUX86State *env, long subfunction,
402 goto out; 405 goto out;
403 } 406 }
404 407
405 - ts->target_v86 = target_v86;  
406 /* save current CPU regs */ 408 /* save current CPU regs */
407 ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */ 409 ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */
408 ts->vm86_saved_regs.ebx = env->regs[R_EBX]; 410 ts->vm86_saved_regs.ebx = env->regs[R_EBX];
@@ -421,6 +423,8 @@ int do_vm86(CPUX86State *env, long subfunction, @@ -421,6 +423,8 @@ int do_vm86(CPUX86State *env, long subfunction,
421 ts->vm86_saved_regs.fs = env->segs[R_FS].selector; 423 ts->vm86_saved_regs.fs = env->segs[R_FS].selector;
422 ts->vm86_saved_regs.gs = env->segs[R_GS].selector; 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 /* build vm86 CPU state */ 428 /* build vm86 CPU state */
425 ts->v86flags = tswap32(target_v86->regs.eflags); 429 ts->v86flags = tswap32(target_v86->regs.eflags);
426 env->eflags = (env->eflags & ~SAFE_MASK) | 430 env->eflags = (env->eflags & ~SAFE_MASK) |
@@ -465,6 +469,7 @@ int do_vm86(CPUX86State *env, long subfunction, @@ -465,6 +469,7 @@ int do_vm86(CPUX86State *env, long subfunction,
465 ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags); 469 ts->vm86plus.vm86plus.flags = tswapl(target_v86->vm86plus.flags);
466 memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab, 470 memcpy(&ts->vm86plus.vm86plus.vm86dbg_intxxtab,
467 target_v86->vm86plus.vm86dbg_intxxtab, 32); 471 target_v86->vm86plus.vm86dbg_intxxtab, 32);
  472 + unlock_user_struct(target_v86, vm86_addr, 0);
468 473
469 #ifdef DEBUG_VM86 474 #ifdef DEBUG_VM86
470 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n", 475 fprintf(logfile, "do_vm86: cs:ip=%04x:%04x\n",
target-arm/nwfpe/fpa11_cpdt.c
@@ -31,48 +31,52 @@ @@ -31,48 +31,52 @@
31 static inline 31 static inline
32 void loadSingle(const unsigned int Fn,const unsigned int *pMem) 32 void loadSingle(const unsigned int Fn,const unsigned int *pMem)
33 { 33 {
  34 + target_ulong addr = (target_ulong)(long)pMem;
34 FPA11 *fpa11 = GET_FPA11(); 35 FPA11 *fpa11 = GET_FPA11();
35 fpa11->fType[Fn] = typeSingle; 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 static inline 40 static inline
40 void loadDouble(const unsigned int Fn,const unsigned int *pMem) 41 void loadDouble(const unsigned int Fn,const unsigned int *pMem)
41 { 42 {
  43 + target_ulong addr = (target_ulong)(long)pMem;
42 FPA11 *fpa11 = GET_FPA11(); 44 FPA11 *fpa11 = GET_FPA11();
43 unsigned int *p; 45 unsigned int *p;
44 p = (unsigned int*)&fpa11->fpreg[Fn].fDouble; 46 p = (unsigned int*)&fpa11->fpreg[Fn].fDouble;
45 fpa11->fType[Fn] = typeDouble; 47 fpa11->fType[Fn] = typeDouble;
46 #ifdef WORDS_BIGENDIAN 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 #else 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 #endif 54 #endif
53 } 55 }
54 56
55 static inline 57 static inline
56 void loadExtended(const unsigned int Fn,const unsigned int *pMem) 58 void loadExtended(const unsigned int Fn,const unsigned int *pMem)
57 { 59 {
  60 + target_ulong addr = (target_ulong)(long)pMem;
58 FPA11 *fpa11 = GET_FPA11(); 61 FPA11 *fpa11 = GET_FPA11();
59 unsigned int *p; 62 unsigned int *p;
60 p = (unsigned int*)&fpa11->fpreg[Fn].fExtended; 63 p = (unsigned int*)&fpa11->fpreg[Fn].fExtended;
61 fpa11->fType[Fn] = typeExtended; 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 static inline 70 static inline
68 void loadMultiple(const unsigned int Fn,const unsigned int *pMem) 71 void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
69 { 72 {
  73 + target_ulong addr = (target_ulong)(long)pMem;
70 FPA11 *fpa11 = GET_FPA11(); 74 FPA11 *fpa11 = GET_FPA11();
71 register unsigned int *p; 75 register unsigned int *p;
72 unsigned long x; 76 unsigned long x;
73 77
74 p = (unsigned int*)&(fpa11->fpreg[Fn]); 78 p = (unsigned int*)&(fpa11->fpreg[Fn]);
75 - get_user(x, &pMem[0]); 79 + x = tget32(addr);
76 fpa11->fType[Fn] = (x >> 14) & 0x00000003; 80 fpa11->fType[Fn] = (x >> 14) & 0x00000003;
77 81
78 switch (fpa11->fType[Fn]) 82 switch (fpa11->fType[Fn])
@@ -80,16 +84,16 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem) @@ -80,16 +84,16 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
80 case typeSingle: 84 case typeSingle:
81 case typeDouble: 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 p[2] = 0; /* empty */ 89 p[2] = 0; /* empty */
86 } 90 }
87 break; 91 break;
88 92
89 case typeExtended: 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 p[0] = (x & 0x80003fff); 97 p[0] = (x & 0x80003fff);
94 } 98 }
95 break; 99 break;
@@ -99,6 +103,7 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem) @@ -99,6 +103,7 @@ void loadMultiple(const unsigned int Fn,const unsigned int *pMem)
99 static inline 103 static inline
100 void storeSingle(const unsigned int Fn,unsigned int *pMem) 104 void storeSingle(const unsigned int Fn,unsigned int *pMem)
101 { 105 {
  106 + target_ulong addr = (target_ulong)(long)pMem;
102 FPA11 *fpa11 = GET_FPA11(); 107 FPA11 *fpa11 = GET_FPA11();
103 float32 val; 108 float32 val;
104 register unsigned int *p = (unsigned int*)&val; 109 register unsigned int *p = (unsigned int*)&val;
@@ -116,12 +121,13 @@ void storeSingle(const unsigned int Fn,unsigned int *pMem) @@ -116,12 +121,13 @@ void storeSingle(const unsigned int Fn,unsigned int *pMem)
116 default: val = fpa11->fpreg[Fn].fSingle; 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 static inline 127 static inline
123 void storeDouble(const unsigned int Fn,unsigned int *pMem) 128 void storeDouble(const unsigned int Fn,unsigned int *pMem)
124 { 129 {
  130 + target_ulong addr = (target_ulong)(long)pMem;
125 FPA11 *fpa11 = GET_FPA11(); 131 FPA11 *fpa11 = GET_FPA11();
126 float64 val; 132 float64 val;
127 register unsigned int *p = (unsigned int*)&val; 133 register unsigned int *p = (unsigned int*)&val;
@@ -139,17 +145,18 @@ void storeDouble(const unsigned int Fn,unsigned int *pMem) @@ -139,17 +145,18 @@ void storeDouble(const unsigned int Fn,unsigned int *pMem)
139 default: val = fpa11->fpreg[Fn].fDouble; 145 default: val = fpa11->fpreg[Fn].fDouble;
140 } 146 }
141 #ifdef WORDS_BIGENDIAN 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 #else 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 #endif 153 #endif
148 } 154 }
149 155
150 static inline 156 static inline
151 void storeExtended(const unsigned int Fn,unsigned int *pMem) 157 void storeExtended(const unsigned int Fn,unsigned int *pMem)
152 { 158 {
  159 + target_ulong addr = (target_ulong)(long)pMem;
153 FPA11 *fpa11 = GET_FPA11(); 160 FPA11 *fpa11 = GET_FPA11();
154 floatx80 val; 161 floatx80 val;
155 register unsigned int *p = (unsigned int*)&val; 162 register unsigned int *p = (unsigned int*)&val;
@@ -167,14 +174,15 @@ void storeExtended(const unsigned int Fn,unsigned int *pMem) @@ -167,14 +174,15 @@ void storeExtended(const unsigned int Fn,unsigned int *pMem)
167 default: val = fpa11->fpreg[Fn].fExtended; 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 static inline 182 static inline
176 void storeMultiple(const unsigned int Fn,unsigned int *pMem) 183 void storeMultiple(const unsigned int Fn,unsigned int *pMem)
177 { 184 {
  185 + target_ulong addr = (target_ulong)(long)pMem;
178 FPA11 *fpa11 = GET_FPA11(); 186 FPA11 *fpa11 = GET_FPA11();
179 register unsigned int nType, *p; 187 register unsigned int nType, *p;
180 188
@@ -186,17 +194,17 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem) @@ -186,17 +194,17 @@ void storeMultiple(const unsigned int Fn,unsigned int *pMem)
186 case typeSingle: 194 case typeSingle:
187 case typeDouble: 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 break; 201 break;
194 202
195 case typeExtended: 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 break; 209 break;
202 } 210 }