Subversion Repositories HelenOS

Rev

Rev 2812 | Rev 3011 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2812 Rev 2813
Line 40... Line 40...
40
#include <debug.h>
40
#include <debug.h>
41
#include <ipc/ipc.h>
41
#include <ipc/ipc.h>
42
#include <ipc/sysipc.h>
42
#include <ipc/sysipc.h>
43
#include <ipc/irq.h>
43
#include <ipc/irq.h>
44
#include <ipc/ipcrsc.h>
44
#include <ipc/ipcrsc.h>
-
 
45
#include <udebug/udebug_ipc.h>
45
#include <arch/interrupt.h>
46
#include <arch/interrupt.h>
46
#include <print.h>
47
#include <print.h>
47
#include <syscall/copy.h>
48
#include <syscall/copy.h>
48
#include <security/cap.h>
49
#include <security/cap.h>
49
#include <mm/as.h>
50
#include <mm/as.h>
Line 288... Line 289...
288
        answer->buffer = NULL;
289
        answer->buffer = NULL;
289
    }
290
    }
290
    return 0;
291
    return 0;
291
}
292
}
292
 
293
 
293
static task_t *get_lock_callee_task(phone_t *phone)
-
 
294
{
-
 
295
    answerbox_t *answerbox;
-
 
296
    task_t *ta;
-
 
297
 
-
 
298
    // FIXME: locking!!!
-
 
299
 
-
 
300
    answerbox = phone->callee;
-
 
301
    ta = answerbox->task;
-
 
302
 
-
 
303
    spinlock_lock(&ta->lock);
-
 
304
 
-
 
305
    return ta;
-
 
306
}
-
 
307
 
-
 
308
static thread_t *get_task_thread_by_id(task_t *ta, thread_id_t tid)
-
 
309
{
-
 
310
    thread_t *t;
-
 
311
    link_t *cur;
-
 
312
 
-
 
313
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
-
 
314
        t = list_get_instance(cur, thread_t, th_link);     
-
 
315
        if (tid == t->tid) return t;
-
 
316
    }
-
 
317
 
-
 
318
    return NULL;
-
 
319
}
-
 
320
 
-
 
321
#include <console/klog.h>
-
 
322
 
-
 
323
static int debug_begin(call_t *call, phone_t *phone)
-
 
324
{
-
 
325
    task_t *ta;
-
 
326
 
-
 
327
    klog_printf("debug_begin()");
-
 
328
 
-
 
329
    ta = get_lock_callee_task(phone);
-
 
330
    klog_printf("debugging task %llu", ta->taskid);
-
 
331
 
-
 
332
    if (ta->being_debugged != false) {
-
 
333
        spinlock_unlock(&ta->lock);
-
 
334
        klog_printf("debug_begin(): busy error");
-
 
335
        return EBUSY;
-
 
336
    }
-
 
337
 
-
 
338
    ta->being_debugged = true;
-
 
339
    ta->stop_request = true;
-
 
340
    ta->debug_begin_call = call;
-
 
341
 
-
 
342
    if (ta->not_stoppable_count == 0) {
-
 
343
        ta->debug_begin_call = NULL;
-
 
344
        ta->stop_request = false;
-
 
345
        spinlock_unlock(&ta->lock);
-
 
346
        klog_printf("debug_begin(): immediate backsend");
-
 
347
        return 1; /* actually we need backsend with 0 retval */
-
 
348
    }
-
 
349
 
-
 
350
    spinlock_unlock(&ta->lock);
-
 
351
 
-
 
352
    klog_printf("debug_begin() done (wait for stoppability)");
-
 
353
    return 0;
-
 
354
}
-
 
355
 
-
 
356
static int debug_go(call_t *call, phone_t *phone)
-
 
357
{
-
 
358
    thread_t *t;
-
 
359
    task_t *ta;
-
 
360
 
-
 
361
    klog_printf("debug_go()");
-
 
362
    ta = get_lock_callee_task(phone);
-
 
363
 
-
 
364
    ta->debug_go_call = call;
-
 
365
    t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data));
-
 
366
    if (t == NULL) {
-
 
367
        spinlock_unlock(&ta->lock);
-
 
368
        return ENOENT;
-
 
369
    }
-
 
370
 
-
 
371
    klog_printf("debug_go(): waitq_wakeup");
-
 
372
    waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
-
 
373
 
-
 
374
    spinlock_unlock(&ta->lock);
-
 
375
 
-
 
376
    return 0; /* no backsend */
-
 
377
}
-
 
378
 
-
 
379
static int debug_args_read(call_t *call, phone_t *phone)
-
 
380
{
-
 
381
    thread_t *t;
-
 
382
    task_t *ta;
-
 
383
    void *uspace_buffer;
-
 
384
    unative_t to_copy;
-
 
385
    int rc;
-
 
386
 
-
 
387
    klog_printf("debug_args_read()");
-
 
388
    // FIXME: verify task/thread state
-
 
389
 
-
 
390
    ta = get_lock_callee_task(phone);
-
 
391
    klog_printf("task %llu", ta->taskid);
-
 
392
    t = get_task_thread_by_id(ta, IPC_GET_ARG2(call->data));
-
 
393
    if (t == NULL) {
-
 
394
        spinlock_unlock(&ta->lock);
-
 
395
        return ENOENT;
-
 
396
    }
-
 
397
 
-
 
398
    uspace_buffer = (void *)IPC_GET_ARG3(call->data);
-
 
399
    to_copy = IPC_GET_ARG4(call->data);
-
 
400
    if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
-
 
401
 
-
 
402
    rc = copy_to_uspace(uspace_buffer, t->syscall_args, to_copy);
-
 
403
    if (rc != 0) {
-
 
404
        spinlock_unlock(&ta->lock);
-
 
405
        klog_printf("debug_args_read() - copy failed");
-
 
406
        return rc;
-
 
407
    }
-
 
408
 
-
 
409
    spinlock_unlock(&ta->lock);
-
 
410
 
-
 
411
    IPC_SET_ARG1(call->data, to_copy);
-
 
412
 
-
 
413
    klog_printf("debug_args_read() done");
-
 
414
    return 1; /* actually need becksend with retval 0 */
-
 
415
}
-
 
416
 
-
 
417
static int debug_thread_read(call_t *call, phone_t *phone)
-
 
418
{
-
 
419
    thread_t *t;
-
 
420
    link_t *cur;
-
 
421
    task_t *ta;
-
 
422
    unative_t *uspace_buffer;
-
 
423
    unative_t to_copy;
-
 
424
    int rc;
-
 
425
    unsigned copied, total;
-
 
426
    unsigned buf_size;
-
 
427
    unative_t tid;
-
 
428
 
-
 
429
    klog_printf("debug_thread_read()");
-
 
430
    // FIXME: verify task/thread state
-
 
431
 
-
 
432
    ta = get_lock_callee_task(phone);
-
 
433
    klog_printf("task %llu", ta->taskid);
-
 
434
   
-
 
435
    uspace_buffer = (void *)IPC_GET_ARG2(call->data);
-
 
436
    buf_size = IPC_GET_ARG3(call->data);
-
 
437
 
-
 
438
    copied = total = 0;
-
 
439
    for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
-
 
440
        t = list_get_instance(cur, thread_t, th_link);
-
 
441
 
-
 
442
        /* Not interested in kernel threads */
-
 
443
        if ((t->flags & THREAD_FLAG_USPACE) == 0)
-
 
444
            continue;
-
 
445
 
-
 
446
        //FIXME: id cropped!!
-
 
447
        tid = (unative_t) t->tid;
-
 
448
 
-
 
449
        to_copy = sizeof(unative_t);
-
 
450
        if (copied + to_copy >= buf_size)
-
 
451
            to_copy = buf_size - copied;
-
 
452
 
-
 
453
        if (to_copy > 0) {
-
 
454
            rc = copy_to_uspace(uspace_buffer, &tid, to_copy);
-
 
455
            if (rc != 0) {
-
 
456
                spinlock_unlock(&ta->lock);
-
 
457
                klog_printf("debug_thread_read() - copy failed");
-
 
458
                return rc;
-
 
459
            }
-
 
460
        }
-
 
461
 
-
 
462
        ++uspace_buffer;
-
 
463
        total += sizeof(unative_t);
-
 
464
        copied += to_copy;
-
 
465
    }
-
 
466
 
-
 
467
    spinlock_unlock(&ta->lock);
-
 
468
 
-
 
469
    IPC_SET_ARG1(call->data, copied);
-
 
470
    IPC_SET_ARG2(call->data, total);
-
 
471
 
-
 
472
    klog_printf("debug_thread_read() done");
-
 
473
    return 1; /* actually need becksend with retval 0 */
-
 
474
}
-
 
475
 
-
 
476
#include <udebug.h>
-
 
477
 
-
 
478
static int debug_request_preprocess(call_t *call, phone_t *phone)
-
 
479
{
-
 
480
    int rc;
-
 
481
 
-
 
482
    switch (IPC_GET_ARG1(call->data)) {
-
 
483
    case UDEBUG_M_BEGIN:
-
 
484
        rc = debug_begin(call, phone);
-
 
485
        return rc;
-
 
486
    case UDEBUG_M_GO:
-
 
487
        rc = debug_go(call, phone);
-
 
488
        return rc;
-
 
489
    case UDEBUG_M_ARGS_READ:
-
 
490
        rc = debug_args_read(call, phone);
-
 
491
        return rc;
-
 
492
    case UDEBUG_M_THREAD_READ:
-
 
493
        rc = debug_thread_read(call, phone);
-
 
494
        return rc;
-
 
495
    default:
-
 
496
        break;
-
 
497
    }
-
 
498
 
-
 
499
    return 0;
-
 
500
}
-
 
501
 
-
 
502
/** Called before the request is sent.
294
/** Called before the request is sent.
503
 *
295
 *
504
 * @param call      Call structure with the request.
296
 * @param call      Call structure with the request.
505
 * @param phone     Phone that the call will be sent through.
297
 * @param phone     Phone that the call will be sent through.
506
 *
298
 *
Line 548... Line 340...
548
            return rc;
340
            return rc;
549
        }
341
        }
550
        break;
342
        break;
551
    case IPC_M_DEBUG_ALL:
343
    case IPC_M_DEBUG_ALL:
552
        /* actually need possibility of backsend with 0 result code */
344
        /* actually need possibility of backsend with 0 result code */
553
        rc = debug_request_preprocess(call, phone);
345
        rc = udebug_request_preprocess(call, phone);
554
        return rc;
346
        return rc;
555
    default:
347
    default:
556
        break;
348
        break;
557
    }
349
    }
558
    return 0;
350
    return 0;
Line 797... Line 589...
797
        sizeof(call->data.args));
589
        sizeof(call->data.args));
798
    if (rc != 0) {
590
    if (rc != 0) {
799
        ipc_call_free(call);
591
        ipc_call_free(call);
800
        return (unative_t) rc;
592
        return (unative_t) rc;
801
    }
593
    }
802
    if (TASK->being_debugged)
-
 
803
        klog_printf("call_async_slow: phone=%u, uspace_ptr=%u, arg0=%u",
-
 
804
            phoneid, (unsigned)data, call->data.args[0]);
-
 
805
    if (!(res = request_preprocess(call, phone)))
594
    if (!(res = request_preprocess(call, phone)))
806
        ipc_call(phone, call);
595
        ipc_call(phone, call);
807
    else
596
    else
808
        ipc_backsend_err(phone, call, res);
597
        ipc_backsend_err(phone, call, res);
809
 
598