Commit 33d9cc8a9691157fd99b681a5122f734522fc63a

Authored by pbrook
1 parent 6361cdb6

ARM GDB semihosting fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2965 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 31 additions and 9 deletions
arm-semi.c
@@ -117,14 +117,21 @@ static inline uint32_t set_swi_errno(CPUState *env, uint32_t code) @@ -117,14 +117,21 @@ static inline uint32_t set_swi_errno(CPUState *env, uint32_t code)
117 117
118 static target_ulong arm_semi_syscall_len; 118 static target_ulong arm_semi_syscall_len;
119 119
  120 +#if !defined(CONFIG_USER_ONLY)
  121 +static target_ulong syscall_err;
  122 +#endif
  123 +
120 static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err) 124 static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
121 { 125 {
122 #ifdef CONFIG_USER_ONLY 126 #ifdef CONFIG_USER_ONLY
123 TaskState *ts = env->opaque; 127 TaskState *ts = env->opaque;
124 #endif 128 #endif
  129 +
125 if (ret == (target_ulong)-1) { 130 if (ret == (target_ulong)-1) {
126 #ifdef CONFIG_USER_ONLY 131 #ifdef CONFIG_USER_ONLY
127 ts->swi_errno = err; 132 ts->swi_errno = err;
  133 +#else
  134 + syscall_err = err;
128 #endif 135 #endif
129 env->regs[0] = ret; 136 env->regs[0] = ret;
130 } else { 137 } else {
@@ -144,6 +151,20 @@ static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err) @@ -144,6 +151,20 @@ static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
144 } 151 }
145 } 152 }
146 153
  154 +static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
  155 +{
  156 + /* The size is always stored in big-endian order, extract
  157 + the value. We assume the size always fit in 32 bits. */
  158 + uint32_t size;
  159 + cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
  160 + env->regs[0] = be32_to_cpu(size);
  161 +#ifdef CONFIG_USER_ONLY
  162 + ((TaskState *)env->opaque)->swi_errno = err;
  163 +#else
  164 + syscall_err = err;
  165 +#endif
  166 +}
  167 +
147 #define ARG(n) tget32(args + (n) * 4) 168 #define ARG(n) tget32(args + (n) * 4)
148 #define SET_ARG(n, val) tput32(args + (n) * 4,val) 169 #define SET_ARG(n, val) tput32(args + (n) * 4,val)
149 uint32_t do_arm_semihosting(CPUState *env) 170 uint32_t do_arm_semihosting(CPUState *env)
@@ -173,8 +194,8 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -173,8 +194,8 @@ uint32_t do_arm_semihosting(CPUState *env)
173 return STDOUT_FILENO; 194 return STDOUT_FILENO;
174 } 195 }
175 if (use_gdb_syscalls()) { 196 if (use_gdb_syscalls()) {
176 - gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), (int)ARG(2),  
177 - gdb_open_modeflags[ARG(1)]); 197 + gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
  198 + (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
178 return env->regs[0]; 199 return env->regs[0];
179 } else { 200 } else {
180 ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644)); 201 ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
@@ -252,7 +273,7 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -252,7 +273,7 @@ uint32_t do_arm_semihosting(CPUState *env)
252 } 273 }
253 case SYS_SEEK: 274 case SYS_SEEK:
254 if (use_gdb_syscalls()) { 275 if (use_gdb_syscalls()) {
255 - gdb_do_syscall(arm_semi_cb, "fseek,%x,%x,0", ARG(0), ARG(1)); 276 + gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
256 return env->regs[0]; 277 return env->regs[0];
257 } else { 278 } else {
258 ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET)); 279 ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
@@ -262,8 +283,9 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -262,8 +283,9 @@ uint32_t do_arm_semihosting(CPUState *env)
262 } 283 }
263 case SYS_FLEN: 284 case SYS_FLEN:
264 if (use_gdb_syscalls()) { 285 if (use_gdb_syscalls()) {
265 - /* TODO: Use stat syscall. */  
266 - return -1; 286 + gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x",
  287 + ARG(0), env->regs[13]-64);
  288 + return env->regs[0];
267 } else { 289 } else {
268 struct stat buf; 290 struct stat buf;
269 ret = set_swi_errno(ts, fstat(ARG(0), &buf)); 291 ret = set_swi_errno(ts, fstat(ARG(0), &buf));
@@ -276,7 +298,7 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -276,7 +298,7 @@ uint32_t do_arm_semihosting(CPUState *env)
276 return -1; 298 return -1;
277 case SYS_REMOVE: 299 case SYS_REMOVE:
278 if (use_gdb_syscalls()) { 300 if (use_gdb_syscalls()) {
279 - gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)); 301 + gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
280 ret = env->regs[0]; 302 ret = env->regs[0];
281 } else { 303 } else {
282 s = lock_user_string(ARG(0)); 304 s = lock_user_string(ARG(0));
@@ -287,7 +309,7 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -287,7 +309,7 @@ uint32_t do_arm_semihosting(CPUState *env)
287 case SYS_RENAME: 309 case SYS_RENAME:
288 if (use_gdb_syscalls()) { 310 if (use_gdb_syscalls()) {
289 gdb_do_syscall(arm_semi_cb, "rename,%s,%s", 311 gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
290 - ARG(0), (int)ARG(1), ARG(2), (int)ARG(3)); 312 + ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
291 return env->regs[0]; 313 return env->regs[0];
292 } else { 314 } else {
293 char *s2; 315 char *s2;
@@ -304,7 +326,7 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -304,7 +326,7 @@ uint32_t do_arm_semihosting(CPUState *env)
304 return set_swi_errno(ts, time(NULL)); 326 return set_swi_errno(ts, time(NULL));
305 case SYS_SYSTEM: 327 case SYS_SYSTEM:
306 if (use_gdb_syscalls()) { 328 if (use_gdb_syscalls()) {
307 - gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)); 329 + gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
308 return env->regs[0]; 330 return env->regs[0];
309 } else { 331 } else {
310 s = lock_user_string(ARG(0)); 332 s = lock_user_string(ARG(0));
@@ -315,7 +337,7 @@ uint32_t do_arm_semihosting(CPUState *env) @@ -315,7 +337,7 @@ uint32_t do_arm_semihosting(CPUState *env)
315 #ifdef CONFIG_USER_ONLY 337 #ifdef CONFIG_USER_ONLY
316 return ts->swi_errno; 338 return ts->swi_errno;
317 #else 339 #else
318 - return 0; 340 + return syscall_err;
319 #endif 341 #endif
320 case SYS_GET_CMDLINE: 342 case SYS_GET_CMDLINE:
321 #ifdef CONFIG_USER_ONLY 343 #ifdef CONFIG_USER_ONLY