Commit ce4defa062c5e6d940f73a1013f8770f23b0f4bf

Authored by pbrook
1 parent b88a3832

Arm Linux EABI syscall support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1756 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/main.c
@@ -360,6 +360,7 @@ void cpu_loop(CPUARMState *env) @@ -360,6 +360,7 @@ void cpu_loop(CPUARMState *env)
360 case EXCP_SWI: 360 case EXCP_SWI:
361 case EXCP_BKPT: 361 case EXCP_BKPT:
362 { 362 {
  363 + env->eabi = 1;
363 /* system call */ 364 /* system call */
364 if (trapnr == EXCP_BKPT) { 365 if (trapnr == EXCP_BKPT) {
365 if (env->thumb) { 366 if (env->thumb) {
@@ -386,13 +387,14 @@ void cpu_loop(CPUARMState *env) @@ -386,13 +387,14 @@ void cpu_loop(CPUARMState *env)
386 } else if (n == ARM_NR_semihosting 387 } else if (n == ARM_NR_semihosting
387 || n == ARM_NR_thumb_semihosting) { 388 || n == ARM_NR_thumb_semihosting) {
388 env->regs[0] = do_arm_semihosting (env); 389 env->regs[0] = do_arm_semihosting (env);
389 - } else if (n >= ARM_SYSCALL_BASE 390 + } else if (n == 0 || n >= ARM_SYSCALL_BASE
390 || (env->thumb && n == ARM_THUMB_SYSCALL)) { 391 || (env->thumb && n == ARM_THUMB_SYSCALL)) {
391 /* linux syscall */ 392 /* linux syscall */
392 - if (env->thumb) { 393 + if (env->thumb || n == 0) {
393 n = env->regs[7]; 394 n = env->regs[7];
394 } else { 395 } else {
395 n -= ARM_SYSCALL_BASE; 396 n -= ARM_SYSCALL_BASE;
  397 + env->eabi = 0;
396 } 398 }
397 env->regs[0] = do_syscall(env, 399 env->regs[0] = do_syscall(env,
398 n, 400 n,
linux-user/syscall.c
@@ -1651,6 +1651,45 @@ void syscall_init(void) @@ -1651,6 +1651,45 @@ void syscall_init(void)
1651 } 1651 }
1652 } 1652 }
1653 1653
  1654 +static inline uint64_t target_offset64(uint32_t word0, uint32_t word1)
  1655 +{
  1656 +#ifdef TARGET_WORDS_BIG_ENDIAN
  1657 + return ((uint64_t)word0 << 32) | word1;
  1658 +#else
  1659 + return ((uint64_t)word1 << 32) | word0;
  1660 +#endif
  1661 +}
  1662 +
  1663 +#ifdef TARGET_NR_truncate64
  1664 +static inline long target_truncate64(void *cpu_env, const char *arg1,
  1665 + long arg2, long arg3, long arg4)
  1666 +{
  1667 +#ifdef TARGET_ARM
  1668 + if (((CPUARMState *)cpu_env)->eabi)
  1669 + {
  1670 + arg2 = arg3;
  1671 + arg3 = arg4;
  1672 + }
  1673 +#endif
  1674 + return get_errno(truncate64(arg1, target_offset64(arg2, arg3)));
  1675 +}
  1676 +#endif
  1677 +
  1678 +#ifdef TARGET_NR_ftruncate64
  1679 +static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2,
  1680 + long arg3, long arg4)
  1681 +{
  1682 +#ifdef TARGET_ARM
  1683 + if (((CPUARMState *)cpu_env)->eabi)
  1684 + {
  1685 + arg2 = arg3;
  1686 + arg3 = arg4;
  1687 + }
  1688 +#endif
  1689 + return get_errno(ftruncate64(arg1, target_offset64(arg2, arg3)));
  1690 +}
  1691 +#endif
  1692 +
1654 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, 1693 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1655 long arg4, long arg5, long arg6) 1694 long arg4, long arg5, long arg6)
1656 { 1695 {
@@ -2844,12 +2883,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2844,12 +2883,12 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2844 #endif 2883 #endif
2845 #ifdef TARGET_NR_truncate64 2884 #ifdef TARGET_NR_truncate64
2846 case TARGET_NR_truncate64: 2885 case TARGET_NR_truncate64:
2847 - ret = get_errno(truncate64((const char *)arg1, arg2)); 2886 + ret = target_truncate64(cpu_env, (const char *)arg1, arg2, arg3, arg4);
2848 break; 2887 break;
2849 #endif 2888 #endif
2850 #ifdef TARGET_NR_ftruncate64 2889 #ifdef TARGET_NR_ftruncate64
2851 case TARGET_NR_ftruncate64: 2890 case TARGET_NR_ftruncate64:
2852 - ret = get_errno(ftruncate64(arg1, arg2)); 2891 + ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
2853 break; 2892 break;
2854 #endif 2893 #endif
2855 #ifdef TARGET_NR_stat64 2894 #ifdef TARGET_NR_stat64
@@ -2868,25 +2907,50 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2868,25 +2907,50 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2868 ret = get_errno(fstat(arg1, &st)); 2907 ret = get_errno(fstat(arg1, &st));
2869 do_stat64: 2908 do_stat64:
2870 if (!is_error(ret)) { 2909 if (!is_error(ret)) {
2871 - struct target_stat64 *target_st = (void *)arg2;  
2872 - memset(target_st, 0, sizeof(struct target_stat64));  
2873 - put_user(st.st_dev, &target_st->st_dev);  
2874 - put_user(st.st_ino, &target_st->st_ino); 2910 +#ifdef TARGET_ARM
  2911 + if (((CPUARMState *)cpu_env)->eabi) {
  2912 + struct target_eabi_stat64 *target_st = (void *)arg2;
  2913 + memset(target_st, 0, sizeof(struct target_eabi_stat64));
  2914 + put_user(st.st_dev, &target_st->st_dev);
  2915 + put_user(st.st_ino, &target_st->st_ino);
  2916 +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
  2917 + put_user(st.st_ino, &target_st->__st_ino);
  2918 +#endif
  2919 + put_user(st.st_mode, &target_st->st_mode);
  2920 + put_user(st.st_nlink, &target_st->st_nlink);
  2921 + put_user(st.st_uid, &target_st->st_uid);
  2922 + put_user(st.st_gid, &target_st->st_gid);
  2923 + put_user(st.st_rdev, &target_st->st_rdev);
  2924 + /* XXX: better use of kernel struct */
  2925 + put_user(st.st_size, &target_st->st_size);
  2926 + put_user(st.st_blksize, &target_st->st_blksize);
  2927 + put_user(st.st_blocks, &target_st->st_blocks);
  2928 + put_user(st.st_atime, &target_st->target_st_atime);
  2929 + put_user(st.st_mtime, &target_st->target_st_mtime);
  2930 + put_user(st.st_ctime, &target_st->target_st_ctime);
  2931 + } else
  2932 +#endif
  2933 + {
  2934 + struct target_stat64 *target_st = (void *)arg2;
  2935 + memset(target_st, 0, sizeof(struct target_stat64));
  2936 + put_user(st.st_dev, &target_st->st_dev);
  2937 + put_user(st.st_ino, &target_st->st_ino);
2875 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO 2938 #ifdef TARGET_STAT64_HAS_BROKEN_ST_INO
2876 - put_user(st.st_ino, &target_st->__st_ino);  
2877 -#endif  
2878 - put_user(st.st_mode, &target_st->st_mode);  
2879 - put_user(st.st_nlink, &target_st->st_nlink);  
2880 - put_user(st.st_uid, &target_st->st_uid);  
2881 - put_user(st.st_gid, &target_st->st_gid);  
2882 - put_user(st.st_rdev, &target_st->st_rdev);  
2883 - /* XXX: better use of kernel struct */  
2884 - put_user(st.st_size, &target_st->st_size);  
2885 - put_user(st.st_blksize, &target_st->st_blksize);  
2886 - put_user(st.st_blocks, &target_st->st_blocks);  
2887 - put_user(st.st_atime, &target_st->target_st_atime);  
2888 - put_user(st.st_mtime, &target_st->target_st_mtime);  
2889 - put_user(st.st_ctime, &target_st->target_st_ctime); 2939 + put_user(st.st_ino, &target_st->__st_ino);
  2940 +#endif
  2941 + put_user(st.st_mode, &target_st->st_mode);
  2942 + put_user(st.st_nlink, &target_st->st_nlink);
  2943 + put_user(st.st_uid, &target_st->st_uid);
  2944 + put_user(st.st_gid, &target_st->st_gid);
  2945 + put_user(st.st_rdev, &target_st->st_rdev);
  2946 + /* XXX: better use of kernel struct */
  2947 + put_user(st.st_size, &target_st->st_size);
  2948 + put_user(st.st_blksize, &target_st->st_blksize);
  2949 + put_user(st.st_blocks, &target_st->st_blocks);
  2950 + put_user(st.st_atime, &target_st->target_st_atime);
  2951 + put_user(st.st_mtime, &target_st->target_st_mtime);
  2952 + put_user(st.st_ctime, &target_st->target_st_ctime);
  2953 + }
2890 } 2954 }
2891 } 2955 }
2892 break; 2956 break;
@@ -3150,26 +3214,51 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -3150,26 +3214,51 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3150 { 3214 {
3151 struct flock64 fl; 3215 struct flock64 fl;
3152 struct target_flock64 *target_fl = (void *)arg3; 3216 struct target_flock64 *target_fl = (void *)arg3;
  3217 +#ifdef TARGET_ARM
  3218 + struct target_eabi_flock64 *target_efl = (void *)arg3;
  3219 +#endif
3153 3220
3154 switch(arg2) { 3221 switch(arg2) {
3155 case F_GETLK64: 3222 case F_GETLK64:
3156 ret = get_errno(fcntl(arg1, arg2, &fl)); 3223 ret = get_errno(fcntl(arg1, arg2, &fl));
3157 if (ret == 0) { 3224 if (ret == 0) {
3158 - target_fl->l_type = tswap16(fl.l_type);  
3159 - target_fl->l_whence = tswap16(fl.l_whence);  
3160 - target_fl->l_start = tswap64(fl.l_start);  
3161 - target_fl->l_len = tswap64(fl.l_len);  
3162 - target_fl->l_pid = tswapl(fl.l_pid); 3225 +#ifdef TARGET_ARM
  3226 + if (((CPUARMState *)cpu_env)->eabi) {
  3227 + target_efl->l_type = tswap16(fl.l_type);
  3228 + target_efl->l_whence = tswap16(fl.l_whence);
  3229 + target_efl->l_start = tswap64(fl.l_start);
  3230 + target_efl->l_len = tswap64(fl.l_len);
  3231 + target_efl->l_pid = tswapl(fl.l_pid);
  3232 + } else
  3233 +#endif
  3234 + {
  3235 + target_fl->l_type = tswap16(fl.l_type);
  3236 + target_fl->l_whence = tswap16(fl.l_whence);
  3237 + target_fl->l_start = tswap64(fl.l_start);
  3238 + target_fl->l_len = tswap64(fl.l_len);
  3239 + target_fl->l_pid = tswapl(fl.l_pid);
  3240 + }
3163 } 3241 }
3164 break; 3242 break;
3165 3243
3166 case F_SETLK64: 3244 case F_SETLK64:
3167 case F_SETLKW64: 3245 case F_SETLKW64:
3168 - fl.l_type = tswap16(target_fl->l_type);  
3169 - fl.l_whence = tswap16(target_fl->l_whence);  
3170 - fl.l_start = tswap64(target_fl->l_start);  
3171 - fl.l_len = tswap64(target_fl->l_len);  
3172 - fl.l_pid = tswapl(target_fl->l_pid); 3246 +#ifdef TARGET_ARM
  3247 + if (((CPUARMState *)cpu_env)->eabi) {
  3248 + fl.l_type = tswap16(target_efl->l_type);
  3249 + fl.l_whence = tswap16(target_efl->l_whence);
  3250 + fl.l_start = tswap64(target_efl->l_start);
  3251 + fl.l_len = tswap64(target_efl->l_len);
  3252 + fl.l_pid = tswapl(target_efl->l_pid);
  3253 + } else
  3254 +#endif
  3255 + {
  3256 + fl.l_type = tswap16(target_fl->l_type);
  3257 + fl.l_whence = tswap16(target_fl->l_whence);
  3258 + fl.l_start = tswap64(target_fl->l_start);
  3259 + fl.l_len = tswap64(target_fl->l_len);
  3260 + fl.l_pid = tswapl(target_fl->l_pid);
  3261 + }
3173 ret = get_errno(fcntl(arg1, arg2, &fl)); 3262 ret = get_errno(fcntl(arg1, arg2, &fl));
3174 break; 3263 break;
3175 default: 3264 default:
linux-user/syscall_defs.h
@@ -924,6 +924,38 @@ struct target_stat64 { @@ -924,6 +924,38 @@ struct target_stat64 {
924 unsigned long long st_ino; 924 unsigned long long st_ino;
925 } __attribute__((packed)); 925 } __attribute__((packed));
926 926
  927 +#ifdef TARGET_ARM
  928 +struct target_eabi_stat64 {
  929 + unsigned long long st_dev;
  930 + unsigned int __pad1;
  931 + unsigned long __st_ino;
  932 + unsigned int st_mode;
  933 + unsigned int st_nlink;
  934 +
  935 + unsigned long st_uid;
  936 + unsigned long st_gid;
  937 +
  938 + unsigned long long st_rdev;
  939 + unsigned int __pad2[2];
  940 +
  941 + long long st_size;
  942 + unsigned long st_blksize;
  943 + unsigned int __pad3;
  944 + unsigned long long st_blocks;
  945 +
  946 + unsigned long target_st_atime;
  947 + unsigned long target_st_atime_nsec;
  948 +
  949 + unsigned long target_st_mtime;
  950 + unsigned long target_st_mtime_nsec;
  951 +
  952 + unsigned long target_st_ctime;
  953 + unsigned long target_st_ctime_nsec;
  954 +
  955 + unsigned long long st_ino;
  956 +} __attribute__ ((packed));
  957 +#endif
  958 +
927 #elif defined(TARGET_SPARC) 959 #elif defined(TARGET_SPARC)
928 960
929 struct target_stat { 961 struct target_stat {
@@ -1298,8 +1330,18 @@ struct target_flock64 { @@ -1298,8 +1330,18 @@ struct target_flock64 {
1298 unsigned long long l_start; 1330 unsigned long long l_start;
1299 unsigned long long l_len; 1331 unsigned long long l_len;
1300 int l_pid; 1332 int l_pid;
1301 -}; 1333 +}__attribute__((packed));
1302 1334
  1335 +#ifdef TARGET_ARM
  1336 +struct target_eabi_flock64 {
  1337 + short l_type;
  1338 + short l_whence;
  1339 + int __pad;
  1340 + unsigned long long l_start;
  1341 + unsigned long long l_len;
  1342 + int l_pid;
  1343 +}__attribute__((packed));
  1344 +#endif
1303 1345
1304 /* soundcard defines */ 1346 /* soundcard defines */
1305 /* XXX: convert them all to arch indepedent entries */ 1347 /* XXX: convert them all to arch indepedent entries */
target-arm/cpu.h
@@ -110,6 +110,11 @@ typedef struct CPUARMState { @@ -110,6 +110,11 @@ typedef struct CPUARMState {
110 float_status fp_status; 110 float_status fp_status;
111 } vfp; 111 } vfp;
112 112
  113 +#if defined(CONFIG_USER_ONLY)
  114 + /* For usermode syscall translation. */
  115 + int eabi;
  116 +#endif
  117 +
113 CPU_COMMON 118 CPU_COMMON
114 119
115 } CPUARMState; 120 } CPUARMState;