<commit_before>/**
 * Copyright (c) 2008, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of MSPSim.
 *
 * $Id$
 *
 * -----------------------------------------------------------------
 *
 * CommandBundle
 *
 * Author  : <NAME>, <NAME>
 * Created : Mon Feb 11 2008
 * Updated : $Date$
 *           $Revision$
 */
package se.sics.mspsim.cli;
import se.sics.mspsim.core.CPUMonitor;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MSP430Constants;
import se.sics.mspsim.core.Memory;
import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.MapEntry;
import se.sics.mspsim.util.Utils;

public class DebugCommands implements CommandBundle {
  private long lastCall = 0;
  private long lastWall = 0;
  private ComponentRegistry registry;
  
  public void setupCommands(ComponentRegistry registry, CommandHandler ch) {
    this.registry = registry;
    final MSP430 cpu = (MSP430) registry.getComponent(MSP430.class);
    final ELF elf = (ELF) registry.getComponent(ELF.class);
    final GenericNode node = (GenericNode) registry.getComponent("node");
    if (cpu != null) {
      ch.registerCommand("break", new BasicAsyncCommand("add a breakpoint to a given address or symbol",
          "<address or symbol>") { 
        int address = 0; 
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          if (baddr < 0) {
            context.err.println("unknown symbol: " + context.getArgument(0));
            return 1;
          }
          cpu.setBreakPoint(address = baddr,
              new CPUMonitor() {
                public void cpuAction(int type, int adr, int data) {
                  context.out.println("*** Break at $" + Utils.hex16(adr));
                }
          });
          context.out.println("Breakpoint set at $" + Utils.hex16(baddr));
          return 0;
        }
        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(address);
        }
      });

      ch.registerCommand("watch",
          new BasicAsyncCommand("add a write/read watch to a given address or symbol", "<address or symbol> [char | break]") {
        int mode = 0;
        int address = 0;
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          if (baddr == -1) {
            context.err.println("unknown symbol: " + context.getArgument(0));            
            return -1;
          }
          if (context.getArgumentCount() > 1) {
            String modeStr = context.getArgument(1);
            if ("char".equals(modeStr)) {
              mode = 1;
            } else if ("break".equals(modeStr)) {
              mode = 2;
            }
          }
          cpu.setBreakPoint(address = baddr,
              new CPUMonitor() {
            public void cpuAction(int type, int adr, int data) {
              if (mode == 0 || mode == 2) {
                int pc = cpu.readRegister(0);
                String adrStr = getSymOrAddr(context, adr);
                String pcStr = getSymOrAddrELF(elf, pc);
                String op = "op";
                if (type == MEMORY_READ) {
                  op = "Read";
                } else if (type == MEMORY_WRITE){
                  op = "Write";
                }
                context.out.println("*** " + op + " from " + pcStr +
                    ": " + adrStr + " = " + data);
                if (mode == 2) {
                  cpu.stop();
                }
              } else {
                context.out.print((char) data);
              }
            }
          });
          context.out.println("Watch set at: " + baddr);
          return 0;
        }
        
        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(address);
          context.exit(0);
        }
      });

      ch.registerCommand("watchreg",
          new BasicAsyncCommand("add a write watch to a given register", "<register> [int]") {
        int mode = 0;
        int register = 0;
        public int executeCommand(final CommandContext context) {
          register = context.getArgumentAsRegister(0);
          if (register < 0) {
            return -1;
          }
          if (context.getArgumentCount() > 1) {
            String modeStr = context.getArgument(1);
            if ("int".equals(modeStr)) {
              mode = 1;
            } else {
              context.err.println("illegal argument: " + modeStr);
              return -1;
            }
          }
          cpu.setRegisterWriteMonitor(register, new CPUMonitor() {
            public void cpuAction(int type, int adr, int data) {
              if (mode == 0) {
                int pc = cpu.readRegister(0);
                String adrStr = getRegisterName(register);
                String pcStr = getSymOrAddrELF(elf, pc);
                context.out.println("*** Write from " + pcStr +
                    ": " + adrStr + " = " + data);
              } else {
                context.out.println(data);
              }
            }
          });
          context.out.println("Watch set for register " + getRegisterName(register));
          return 0;
        }
        
        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(register);
        }
      });

      ch.registerCommand("clear", new Command() {
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          cpu.setBreakPoint(baddr, null);
          return 0;
        }

        public String getArgumentHelp(String commandName) {
          return "<address or symbol>";
        }

        public String getCommandHelp(String commandName) {
          return "clear a breakpoint or watch from a given address or symbol";
        }
      });

      
      
      ch.registerCommand("symbol", new BasicCommand("list matching symbols", "<regexp>") {
        public int executeCommand(final CommandContext context) {<commit_msg>show watch address in hex<commit_after>/**
 * Copyright (c) 2008, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of MSPSim.
 *
 * $Id$
 *
 * -----------------------------------------------------------------
 *
 * CommandBundle
 *
 * Author  : <NAME>, <NAME>
 * Created : Mon Feb 11 2008
 * Updated : $Date$
 *           $Revision$
 */
package se.sics.mspsim.cli;
import se.sics.mspsim.core.CPUMonitor;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.MSP430Constants;
import se.sics.mspsim.core.Memory;
import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.DebugInfo;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.MapEntry;
import se.sics.mspsim.util.Utils;

public class DebugCommands implements CommandBundle {
  private long lastCall = 0;
  private long lastWall = 0;
  private ComponentRegistry registry;
  
  public void setupCommands(ComponentRegistry registry, CommandHandler ch) {
    this.registry = registry;
    final MSP430 cpu = (MSP430) registry.getComponent(MSP430.class);
    final ELF elf = (ELF) registry.getComponent(ELF.class);
    final GenericNode node = (GenericNode) registry.getComponent("node");
    if (cpu != null) {
      ch.registerCommand("break", new BasicAsyncCommand("add a breakpoint to a given address or symbol",
          "<address or symbol>") { 
        int address = 0; 
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          if (baddr < 0) {
            context.err.println("unknown symbol: " + context.getArgument(0));
            return 1;
          }
          cpu.setBreakPoint(address = baddr,
              new CPUMonitor() {
                public void cpuAction(int type, int adr, int data) {
                  context.out.println("*** Break at $" + Utils.hex16(adr));
                }
          });
          context.out.println("Breakpoint set at $" + Utils.hex16(baddr));
          return 0;
        }
        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(address);
        }
      });

      ch.registerCommand("watch",
          new BasicAsyncCommand("add a write/read watch to a given address or symbol", "<address or symbol> [char | break]") {
        int mode = 0;
        int address = 0;
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          if (baddr == -1) {
            context.err.println("unknown symbol: " + context.getArgument(0));            
            return -1;
          }
          if (context.getArgumentCount() > 1) {
            String modeStr = context.getArgument(1);
            if ("char".equals(modeStr)) {
              mode = 1;
            } else if ("break".equals(modeStr)) {
              mode = 2;
            }
          }
          cpu.setBreakPoint(address = baddr,
              new CPUMonitor() {
            public void cpuAction(int type, int adr, int data) {
              if (mode == 0 || mode == 2) {
                int pc = cpu.readRegister(0);
                String adrStr = getSymOrAddr(context, adr);
                String pcStr = getSymOrAddrELF(elf, pc);
                String op = "op";
                if (type == MEMORY_READ) {
                  op = "Read";
                } else if (type == MEMORY_WRITE){
                  op = "Write";
                }
                context.out.println("*** " + op + " from " + pcStr +
                    ": " + adrStr + " = " + data);
                if (mode == 2) {
                  cpu.stop();
                }
              } else {
                context.out.print((char) data);
              }
            }
          });
          context.out.println("Watch set at $" + Utils.hex16(baddr));
          return 0;
        }

        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(address);
          context.exit(0);
        }
      });

      ch.registerCommand("watchreg",
          new BasicAsyncCommand("add a write watch to a given register", "<register> [int]") {
        int mode = 0;
        int register = 0;
        public int executeCommand(final CommandContext context) {
          register = context.getArgumentAsRegister(0);
          if (register < 0) {
            return -1;
          }
          if (context.getArgumentCount() > 1) {
            String modeStr = context.getArgument(1);
            if ("int".equals(modeStr)) {
              mode = 1;
            } else {
              context.err.println("illegal argument: " + modeStr);
              return -1;
            }
          }
          cpu.setRegisterWriteMonitor(register, new CPUMonitor() {
            public void cpuAction(int type, int adr, int data) {
              if (mode == 0) {
                int pc = cpu.readRegister(0);
                String adrStr = getRegisterName(register);
                String pcStr = getSymOrAddrELF(elf, pc);
                context.out.println("*** Write from " + pcStr +
                    ": " + adrStr + " = " + data);
              } else {
                context.out.println(data);
              }
            }
          });
          context.out.println("Watch set for register " + getRegisterName(register));
          return 0;
        }
        
        public void stopCommand(CommandContext context) {
          cpu.clearBreakPoint(register);
        }
      });

      ch.registerCommand("clear", new Command() {
        public int executeCommand(final CommandContext context) {
          int baddr = context.getArgumentAsAddress(0);
          cpu.setBreakPoint(baddr, null);
          return 0;
        }

        public String getArgumentHelp(String commandName) {
          return "<address or symbol>";
        }

        public String getCommandHelp(String commandName) {
          return "clear a breakpoint or watch from a given address or symbol";
        }
      });

      ch.registerCommand("symbol", new BasicCommand("list matching symbols", "<regexp>") {
        public int executeCommand(final CommandContext context) {
{'fraction_non_alphanumeric': 0.10567628932857606, 'fraction_numerical': 0.009211806681803438, 'mean_word_length': 2.003897116134061, 'pattern_counts': {'":': 4, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7375499', 'n_tokens_mistral': 4257, 'n_tokens_neox': 3996, 'n_words': 1266}