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 360 case EXCP_SWI:
361 361 case EXCP_BKPT:
362 362 {
  363 + env->eabi = 1;
363 364 /* system call */
364 365 if (trapnr == EXCP_BKPT) {
365 366 if (env->thumb) {
... ... @@ -386,13 +387,14 @@ void cpu_loop(CPUARMState *env)
386 387 } else if (n == ARM_NR_semihosting
387 388 || n == ARM_NR_thumb_semihosting) {
388 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 391 || (env->thumb && n == ARM_THUMB_SYSCALL)) {
391 392 /* linux syscall */
392   - if (env->thumb) {
  393 + if (env->thumb || n == 0) {
393 394 n = env->regs[7];
394 395 } else {
395 396 n -= ARM_SYSCALL_BASE;
  397 + env->eabi = 0;
396 398 }
397 399 env->regs[0] = do_syscall(env,
398 400 n,
... ...
linux-user/syscall.c
... ... @@ -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 1693 long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1655 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 2883 #endif
2845 2884 #ifdef TARGET_NR_truncate64
2846 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 2887 break;
2849 2888 #endif
2850 2889 #ifdef TARGET_NR_ftruncate64
2851 2890 case TARGET_NR_ftruncate64:
2852   - ret = get_errno(ftruncate64(arg1, arg2));
  2891 + ret = target_ftruncate64(cpu_env, arg1, arg2, arg3, arg4);
2853 2892 break;
2854 2893 #endif
2855 2894 #ifdef TARGET_NR_stat64
... ... @@ -2868,25 +2907,50 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2868 2907 ret = get_errno(fstat(arg1, &st));
2869 2908 do_stat64:
2870 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 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 2956 break;
... ... @@ -3150,26 +3214,51 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
3150 3214 {
3151 3215 struct flock64 fl;
3152 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 3221 switch(arg2) {
3155 3222 case F_GETLK64:
3156 3223 ret = get_errno(fcntl(arg1, arg2, &fl));
3157 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 3242 break;
3165 3243  
3166 3244 case F_SETLK64:
3167 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 3262 ret = get_errno(fcntl(arg1, arg2, &fl));
3174 3263 break;
3175 3264 default:
... ...
linux-user/syscall_defs.h
... ... @@ -924,6 +924,38 @@ struct target_stat64 {
924 924 unsigned long long st_ino;
925 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 959 #elif defined(TARGET_SPARC)
928 960  
929 961 struct target_stat {
... ... @@ -1298,8 +1330,18 @@ struct target_flock64 {
1298 1330 unsigned long long l_start;
1299 1331 unsigned long long l_len;
1300 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 1346 /* soundcard defines */
1305 1347 /* XXX: convert them all to arch indepedent entries */
... ...
target-arm/cpu.h
... ... @@ -110,6 +110,11 @@ typedef struct CPUARMState {
110 110 float_status fp_status;
111 111 } vfp;
112 112  
  113 +#if defined(CONFIG_USER_ONLY)
  114 + /* For usermode syscall translation. */
  115 + int eabi;
  116 +#endif
  117 +
113 118 CPU_COMMON
114 119  
115 120 } CPUARMState;
... ...