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 117  
118 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 124 static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
121 125 {
122 126 #ifdef CONFIG_USER_ONLY
123 127 TaskState *ts = env->opaque;
124 128 #endif
  129 +
125 130 if (ret == (target_ulong)-1) {
126 131 #ifdef CONFIG_USER_ONLY
127 132 ts->swi_errno = err;
  133 +#else
  134 + syscall_err = err;
128 135 #endif
129 136 env->regs[0] = ret;
130 137 } else {
... ... @@ -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 168 #define ARG(n) tget32(args + (n) * 4)
148 169 #define SET_ARG(n, val) tput32(args + (n) * 4,val)
149 170 uint32_t do_arm_semihosting(CPUState *env)
... ... @@ -173,8 +194,8 @@ uint32_t do_arm_semihosting(CPUState *env)
173 194 return STDOUT_FILENO;
174 195 }
175 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 199 return env->regs[0];
179 200 } else {
180 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 273 }
253 274 case SYS_SEEK:
254 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 277 return env->regs[0];
257 278 } else {
258 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 283 }
263 284 case SYS_FLEN:
264 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 289 } else {
268 290 struct stat buf;
269 291 ret = set_swi_errno(ts, fstat(ARG(0), &buf));
... ... @@ -276,7 +298,7 @@ uint32_t do_arm_semihosting(CPUState *env)
276 298 return -1;
277 299 case SYS_REMOVE:
278 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 302 ret = env->regs[0];
281 303 } else {
282 304 s = lock_user_string(ARG(0));
... ... @@ -287,7 +309,7 @@ uint32_t do_arm_semihosting(CPUState *env)
287 309 case SYS_RENAME:
288 310 if (use_gdb_syscalls()) {
289 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 313 return env->regs[0];
292 314 } else {
293 315 char *s2;
... ... @@ -304,7 +326,7 @@ uint32_t do_arm_semihosting(CPUState *env)
304 326 return set_swi_errno(ts, time(NULL));
305 327 case SYS_SYSTEM:
306 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 330 return env->regs[0];
309 331 } else {
310 332 s = lock_user_string(ARG(0));
... ... @@ -315,7 +337,7 @@ uint32_t do_arm_semihosting(CPUState *env)
315 337 #ifdef CONFIG_USER_ONLY
316 338 return ts->swi_errno;
317 339 #else
318   - return 0;
  340 + return syscall_err;
319 341 #endif
320 342 case SYS_GET_CMDLINE:
321 343 #ifdef CONFIG_USER_ONLY
... ...