Subversion Repositories HelenOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Jiri Svoboda
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup debug
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <sys/types.h>
  38. #include <bool.h>
  39. #include <udebug.h>
  40.  
  41. #include <kernel/arch/context_offset.h>
  42.  
  43. #include "../../../cons.h"
  44. #include "../../../main.h"
  45. #include "../../../include/arch.h"
  46.  
  47. #define OPCODE_INT3     0xCC
  48.  
  49. void arch_dthread_initialize(dthread_t *dt)
  50. {
  51.     dt->arch.singlestep = false;
  52. }
  53.  
  54. static int _set_trap_flag(dthread_t *dt, bool enable)
  55. {
  56.     static istate_t istate;
  57.     int rc;
  58.  
  59.     rc = udebug_regs_read(app_phone, dt->hash, &istate);
  60.     if (rc < 0) { printf("regs read failed\n"); return -1; }
  61.  
  62.     if (enable) istate.rflags |= 0x0100; /* trap flag */
  63.     else if (!active_bkpt) istate.rflags &= ~0x0100; /* trap flag */
  64.  
  65.     rc = udebug_regs_write(app_phone, dt->hash, &istate);  
  66.     if (rc < 0) { printf("regs write failed\n"); return -1; }
  67.  
  68.     return 0;
  69. }
  70.  
  71. int arch_breakpoint_set(breakpoint_t *b)
  72. {
  73.     char brkp[1];
  74.     int rc;
  75.  
  76.     rc = udebug_mem_read(app_phone, &b->arch.back, b->addr, 1);
  77.     cons_printf("udebug_mem_read() -> %d\n", rc);
  78.     if (rc < 0) return rc;
  79.  
  80.     brkp[0] = OPCODE_INT3;
  81.     rc = udebug_mem_write(app_phone, brkp, b->addr, 1);
  82.     if (rc < 0) return rc;
  83.  
  84.     cons_printf("udebug_mem_write() -> %d\n", rc);
  85.     return 0;
  86. }
  87.  
  88. int arch_breakpoint_remove(breakpoint_t *b)
  89. {
  90.     int rc;
  91.  
  92.     if (b->active) {
  93.         active_bkpt = NULL;
  94.     } else {
  95.             rc = udebug_mem_write(app_phone, &b->arch.back, b->addr, 1);
  96.         if (rc < 0) {
  97.             cons_printf("error writing mem\n");
  98.             return rc;
  99.         }
  100.     }
  101.  
  102.     return 0;
  103. }
  104.  
  105. void arch_event_breakpoint(thash_t thread_hash)
  106. {
  107.     static istate_t istate;
  108.     breakpoint_t *b;
  109.     int rc;
  110.  
  111.     rc = udebug_regs_read(app_phone, thread_hash, &istate);
  112. //  cons_printf("udebug_regs_read -> %d\n", rc);
  113. //  cons_printf("RIP was 0x%08x\n", istate.rip);
  114.     int brk_addr = istate.rip - 1;
  115.  
  116.     b = breakpoint_find_by_addr(brk_addr);
  117.     if (!b) {
  118.         cons_printf("unrecognized breakpoint at 0x%x\n", brk_addr);
  119.         return;
  120.     }
  121.  
  122.     istate.rip = brk_addr;
  123.     istate.rflags |= 0x0100; /* trap flag */
  124.  
  125.     rc = udebug_regs_write(app_phone, thread_hash, &istate);
  126.     if (rc < 0) { cons_printf("error writing regs\n"); return; }
  127.         rc = udebug_mem_write(app_phone, &b->arch.back, brk_addr, 1);
  128.     if (rc < 0) { cons_printf("error writing mem\n"); return; }
  129. //      cons_printf("udebug_mem_write(phone, 0x%x, 0x%02x, 1) -> %d\n", brk_addr, brk_list[bi].arch.back, rc);
  130.  
  131.     b->active = true;
  132.     active_bkpt = b;
  133.  
  134.     breakpoint_hit(b);
  135. }
  136.  
  137. void arch_event_trap(dthread_t *dt)
  138. {
  139.     breakpoint_t *b;
  140.     static istate_t istate;
  141.     unsigned char brkinstr[1];
  142.     int rc;
  143.  
  144. //  cons_printf("trap event\n");
  145.     b = active_bkpt;
  146.    
  147.     if (b) {
  148.         brkinstr[0] = OPCODE_INT3;
  149.         rc = udebug_mem_write(app_phone, brkinstr, b->addr, 1);
  150. //      cons_printf("restore breakpoint -> %d\n", rc);
  151.         active_bkpt = NULL;
  152.     }
  153.  
  154.     rc = _set_trap_flag(dt, false);
  155.     dt->arch.singlestep = false;
  156.  
  157.     singlestep_hit();
  158. }
  159.  
  160. void arch_dump_regs(thash_t thash)
  161. {
  162.     static istate_t istate;
  163.     int rc;
  164.  
  165.     rc = udebug_regs_read(app_phone, thash, &istate);
  166.     if (rc < 0) { cons_printf("Error reading regs\n"); return; }
  167.  
  168.     cons_printf(
  169.         "rip:%016x rflags:%016x rax:%016x rcx:%016x ecx:%016x "
  170.         "rdx:%016x\nrsi:%016x rdi:%016x r8:%016x r9:%016x "
  171.         "r10:%016x r11:%016x cs:%04x\n",
  172.         istate.rip, istate.rflags, istate.rax, istate.rcx,
  173.         istate.rdx, istate.rsi, istate.rdi, istate.r8, istate.r9,
  174.         istate.r10, istate.r11, istate.cs);
  175. }
  176.  
  177. void arch_singlestep(dthread_t *dt)
  178. {
  179.     int rc;
  180.  
  181.     rc = _set_trap_flag(dt, true);
  182.     if (rc != 0) return;
  183.  
  184.     dthread_resume(dt);
  185. }
  186.  
  187. /** @}
  188.  */
  189.