Subversion Repositories HelenOS

Rev

Rev 3005 | Rev 3108 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2008 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. static int _set_trap_flag(dthread_t *dt, bool enable)
  50. {
  51.     static istate_t istate;
  52.     int rc;
  53.  
  54.     rc = udebug_regs_read(app_phone, dt->hash, &istate);
  55.     if (rc < 0) { printf("regs read failed\n"); return; }
  56.  
  57.     if (enable) istate.eflags |= 0x0100; /* trap flag */
  58.     else if (!active_bkpt) istate.eflags &= ~0x0100; /* trap flag */
  59.  
  60.     rc = udebug_regs_write(app_phone, dt->hash, &istate);  
  61.     if (rc < 0) { printf("regs write failed\n"); return; }
  62.  
  63.     return 0;
  64. }
  65.  
  66. int arch_breakpoint_set(breakpoint_t *b)
  67. {
  68.     char brkp[1];
  69.     int rc;
  70.  
  71.     rc = udebug_mem_read(app_phone, &b->arch.back, b->addr, 1);
  72.     cons_printf("udebug_mem_read() -> %d\n", rc);
  73.     if (rc < 0) return rc;
  74.  
  75.     brkp[0] = OPCODE_INT3;
  76.     rc = udebug_mem_write(app_phone, brkp, b->addr, 1);
  77.     if (rc < 0) return rc;
  78.  
  79.     cons_printf("udebug_mem_write() -> %d\n", rc);
  80.     return 0;
  81. }
  82.  
  83. int arch_breakpoint_remove(breakpoint_t *b)
  84. {
  85.     int rc;
  86.  
  87.     if (b->active) {
  88.         active_bkpt = NULL;
  89.     } else {
  90.             rc = udebug_mem_write(app_phone, &b->arch.back, b->addr, 1);
  91.         if (rc < 0) {
  92.             cons_printf("error writing mem\n");
  93.             return rc;
  94.         }
  95.     }
  96.  
  97.     return 0;
  98. }
  99.  
  100. void arch_event_breakpoint(thash_t thread_hash)
  101. {
  102.     static istate_t istate;
  103.     breakpoint_t *b;
  104.     int rc;
  105.  
  106.     rc = udebug_regs_read(app_phone, thread_hash, &istate);
  107. //  cons_printf("udebug_regs_read -> %d\n", rc);
  108. //  cons_printf("EIP was 0x%08x\n", istate.eip);
  109.     int brk_addr = istate.eip - 1;
  110.  
  111.     b = breakpoint_find_by_addr(brk_addr);
  112.     if (!b) {
  113.         cons_printf("unrecognized breakpoint at 0x%x\n", brk_addr);
  114.         return;
  115.     }
  116.  
  117.     istate.eip = brk_addr;
  118.     istate.eflags |= 0x0100; /* trap flag */
  119.  
  120.     rc = udebug_regs_write(app_phone, thread_hash, &istate);
  121.     if (rc < 0) { cons_printf("error writing regs\n"); return; }
  122.         rc = udebug_mem_write(app_phone, &b->arch.back, brk_addr, 1);
  123.     if (rc < 0) { cons_printf("error writing mem\n"); return; }
  124. //      cons_printf("udebug_mem_write(phone, 0x%x, 0x%02x, 1) -> %d\n", brk_addr, brk_list[bi].arch.back, rc);
  125.  
  126.     b->active = true;
  127.     active_bkpt = b;
  128.  
  129.     breakpoint_hit(b);
  130. }
  131.  
  132. void arch_event_trap(dthread_t *dt)
  133. {
  134.     breakpoint_t *b;
  135.     static istate_t istate;
  136.     unsigned char brkinstr[1];
  137.     int rc;
  138.  
  139. //  cons_printf("trap event\n");
  140.     b = active_bkpt;
  141.    
  142.     if (b) {
  143.         brkinstr[0] = OPCODE_INT3;
  144.         rc = udebug_mem_write(app_phone, brkinstr, b->addr, 1);
  145. //      cons_printf("restore breakpoint -> %d\n", rc);
  146.         active_bkpt = NULL;
  147.     }
  148.  
  149.     rc = _set_trap_flag(dt, false);
  150.     dt->arch.singlestep = false;
  151.  
  152.     singlestep_hit();
  153. }
  154.  
  155. void arch_dump_regs(thash_t thash)
  156. {
  157.     static istate_t istate;
  158.     int rc;
  159.  
  160.     rc = udebug_regs_read(app_phone, thash, &istate);
  161.     if (rc < 0) { cons_printf("Error reading regs\n"); return; }
  162.  
  163.     cons_printf(
  164.         "eip:%08x eflags:%08x eax:%08x ebx:%08x ecx:%08x edx:%08x\n"
  165.         "esi:%08x edi:%08x cs:%04x ds:%04x es:%04x fs:%04x gs:%04x\n",
  166.         istate.eip, istate.eflags, istate.eax, istate.ebx,
  167.         istate.ecx, istate.edx, istate.esi, istate.edi, istate.cs,
  168.         istate.ds, istate.es, istate.fs, istate.gs);
  169. }
  170.  
  171. void arch_singlestep(dthread_t *dt)
  172. {
  173.     int rc;
  174.  
  175.     rc = _set_trap_flag(dt, true);
  176.     if (rc != 0) return;
  177.  
  178.     dthread_resume(dt);
  179. }
  180.  
  181. /** @}
  182.  */
  183.