Package com.zylin.zpu.simulator.gdb

Source Code of com.zylin.zpu.simulator.gdb.Packet

/*
* Created on Nov 16, 2004
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package com.zylin.zpu.simulator.gdb;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.zylin.zpu.simulator.exceptions.BadPacketException;
import com.zylin.zpu.simulator.exceptions.CPUException;
import com.zylin.zpu.simulator.exceptions.EndSessionException;
import com.zylin.zpu.simulator.exceptions.GDBServerException;
import com.zylin.zpu.simulator.exceptions.MemoryAccessException;
import com.zylin.zpu.simulator.exceptions.NoAckException;
import com.zylin.zpu.simulator.exceptions.UnknownPacketException;


/** all packet related operations */
class Packet
{
  private final GDBServer server;
 
  Packet(GDBServer server)
  {
    this.server = server;
        reply=new StringBuffer();
  }
 
  void receive() throws IOException, GDBServerException, EndSessionException
  {
    int t;
    /* we spool until we see a $ */
    this.server.expect('$');
   
    StringBuffer packet=new StringBuffer();
 
    int cc=0;
    for (;;)
    {
      int t1;
      t1=this.server.read();
      t = t1;
      if (t==0x7d)
      {
        int t2;
        t2=this.server.read();
        /* the next char is escaped after a GDB specific scheme. See
         * gdb/gdb/remote.c */
        t = t2;
        t^=0x20;
      } else
      {
        if (t=='#')
        {
          break;
        }
      }
     
      cc+=t;
     
      packet.append((char)t);
    }
    cc&=0xff;
   
    String checkSum;
    checkSum=""+(char)this.server.read()+(char)this.server.read();
    int readCheckSum;
    readCheckSum=Integer.parseInt(checkSum, 16);
    if (readCheckSum!=cc)
    {
      // error
      dumpHex(packet.toString());
     
      this.server.write("-".getBytes());
      throw new BadPacketException();
    } else
    {
      // ack
      this.server.write("+".getBytes());
    }
   
    cmd=packet.toString();
    this.server.print(GDBServer.PACKET, "Got " + number + ": #$" + cmd + "#" + checkSum);
    origCmd=cmd;
  }
 
  void parseAndExecute() throws IOException, EndSessionException
  {
      boolean silent=false;
      try
    {
      if (checkPrefix("g"))
      {
        readRegisters();
      } else if (checkPrefix("?"))
      {
        querySignal();
      } else if (checkPrefix("s"))
      {
        doStep();
      } else if (checkPrefix("m"))
      {
        try
        {
          readMemory();
        } catch (CPUException e)
                {
                    silent=true; // happens all the time while hovering over variables in the GUI
                    throw e;
                }
      } else if (checkPrefix("c"))
      {
        continueExecution();
      } else if (checkPrefix("M"))
      {
        writeMemory();
      } else if (checkPrefix("z4"))
      {
        disableAccessWatchPoint();
      } else if (checkPrefix("Z4"))
      {
        enableAccessWatchPoint();
      } else if (checkPrefix("k"))
      {
        /* we must send a reply, but not wait for ack before we shut down
           the connection.
        */
          server.alive=false;
          reply("OK");
      } else
      {
        throw new UnknownPacketException();
      }
    } catch (UnknownPacketException e)
    {
      this.server.print(GDBServer.UNKNOWN, "Unknown packet: " + origCmd);
      // empty reply to unknown packets
    } catch (CPUException e)
        {
            if (!silent)
            {
                this.server.print(GDBServer.CPUEXCEPTION, "Exception handling GDB request");
                if (GDBServer.CPUEXCEPTION)
                {
                    e.printStackTrace();
                }
            }              
            reply("E01");
        } catch (GDBServerException e)
        {
            e.printStackTrace();
            reply("E01");
        catch (RuntimeException e)
    {
      e.printStackTrace();
      reply("E01");
    }
       
    sendReply();
  }

  private void checkEmpty() throws GDBServerException
  {
    if (cmd.length()>0)
    {
      throw new GDBServerException();
    }
  }
  private void dumpHex(String arrayList2)
  {
    for (int i=0; i<arrayList2.length(); i++)
    {
      System.out.println(this.server.formatHex(arrayList2.charAt(i), "00"));
    }
  }
  /**
   * @param packetString
   * @param string
   * @return
   */
  private boolean checkPrefix(String string)
  {
    if (cmd.length() < string.length())
    {
      return false;
    } else
    {
      return cmd.substring(0, string.length()).equals(string);
    }
  }
  /**
   * @throws GDBServerException
   * @throws IOException
   * @throws MemoryAccessException
   *
   */
  private void continueExecution() throws GDBServerException
  {
    extractString("c");
    try
    {
      if (!isEmpty())
      {
        int pc=extractInteger();
        this.server.simulator.setPc(pc);
      }
      checkEmpty();
      this.server.simulator.cont();
    } catch (MemoryAccessException e)
    {
      if (GDBServer.IGNOREDEXCEPTIONS)
      {
        e.printStackTrace();
      }
    }
    reply("S05");
  }
  private void doStep()
  {
    this.server.simulator.step();
    reply("S05");
  }
  protected int extractInteger() throws GDBServerException
  {
    String number;
    Pattern p=Pattern.compile("(\\-?[0-9a-fA-F]+)");
    Matcher m = p.matcher(cmd);
    if (!m.find())
    {
      throw new GDBServerException();
    }
    number=m.group();
    extractString(number);
   
    try
    {
      return (int)Long.parseLong(number, 16);
    } catch (NumberFormatException e)
    {
      throw new GDBServerException(e);
    }
  }
  /**
   * @param string
   * @throws GDBServerException
   */
  private void extractString(String string) throws GDBServerException
  {
    if (!checkPrefix(string))
    {
      throw new GDBServerException();
    }
    stripStart(string.length());
  }
  /**
   * @throws GDBServerException
   *
   */
  private void readMemory() throws CPUException, GDBServerException
  {
    extractString("m");
    int address=extractInteger();
    extractString(",");
    int length=extractInteger();
    checkEmpty();
   
    for (int i=0; i<length; i++)
    {
      reply(this.server.formatHex(this.server.simulator.readByte(address+i), "00"));
    }
  }
  /**
   *
   */
  private void readRegisters()  throws CPUException
  {
    for (int i=0; i<this.server.simulator.getREGNUM(); i++)
    {
      reply(this.server.printHex(this.server.simulator.getReg(i)));
    }
  }
  private void writeMemory() throws GDBServerException, MemoryAccessException
  {
    extractString("M");
    int address=extractInteger();
    extractString(",");
    int length=extractInteger();
    extractString(":");
   
    for (int i=0; i<length; i++)
    {
      String t;
      t=cmd.substring(i*2, i*2+2);
      int val;
      val=Integer.parseInt(t, 16);
      this.server.simulator.writeByte(address+i, val);
    }
    reply("OK");
   
  }
 
  private void enableAccessWatchPoint() throws GDBServerException, CPUException
  {
    extractString("Z4");
    extractString(",");
    int address=extractInteger();
    extractString(",");
    int length=extractInteger();
    checkEmpty();
    server.simulator.enableAccessWatchPoint(address, length);
   
    reply("OK");
  }

  private void disableAccessWatchPoint() throws GDBServerException, CPUException
  {
    extractString("z4");
    extractString(",");
    int address=extractInteger();
    extractString(",");
    int length=extractInteger();
    checkEmpty();
    server.simulator.disableAccessWatchPoint(address, length);
   
    reply("OK");
  }

 
  private void stripStart(int length)
  {
    cmd=cmd.substring(length);
  }
  private boolean isEmpty()
  {
    return cmd.length()==0;
  }
  /**
   * @param string
   */
  protected void reply(String string)
  {
    reply.append(string);
  }
  void sendReply()
  {
    // a bit easier to debug if we can see the entire string.
    StringBuffer buffer = new StringBuffer();
    buffer.append("$");
    number++;
    String replyString = reply.toString();
    buffer.append(replyString);
    byte[] data = replyString.toString().getBytes();
    int csum = 0;
    for (int i = 0; i < data.length; i++)
    {
      csum += data[i];
    }
    csum &= 0xff;
    buffer.append("#");
    String t = Integer.toHexString(csum);
    if (t.length() == 1)
    {
      t = "0" + t;
    }
    buffer.append(t);
    this.server.print(GDBServer.REPLY, "Reply " + number + " : " + buffer.toString());
    try
    {
      this.server.write(buffer.toString().getBytes());
    } catch (IOException e)
    {
      throw new RuntimeException(e);
    }
   
    if (server.alive)
    {
      /* check for ack. */
      int ack;
      try
      {
        ack = (char)this.server.read();
      } catch (IOException e)
      {
        throw new RuntimeException(e);
      }
      if (ack == '+')
      {
        return;
      }
      this.server.print(GDBServer.MINIMAL, "Retry");
     
      throw new NoAckException();
    }
    reply=new StringBuffer();
  }
 
  private void querySignal()
  {
    // SIGINT
    //  reply("S02");
    reply("S05");
  }
  protected String cmd;
  private int number;
  private StringBuffer reply;
  private String origCmd;
    int syscallErrno;
    int syscallRetval;


   
    void invokeSyscall(String string, int argNum, String types) throws IOException, NoAckException, GDBServerException, EndSessionException, CPUException
    {
        string="F"+string;
       
        int j=0;
        for (int i=0; i<argNum; i++)
        {
            string+=",";
            string+=Integer.toHexString(server.getSyscallArg(j));
            j++;
            if (types.charAt(i)=='s')
            {
                string+="/" + Integer.toHexString(server.getSyscallArg(j));
                j++;
            }
        }

        reply(string);
        sendReply();
        for (;;)
        {
            Packet packet=new Packet(server);
            packet.receive();
            if (packet.checkPrefix("F"))
            {
                /* this is the reply we are waiting for */
                packet.extractString("F");
                syscallRetval=packet.extractInteger();
                syscallErrno=0;
                if (packet.checkPrefix(","))
                {
                    /* errno is optional */
                    packet.extractString(",");
                    syscallErrno = packet.extractInteger();
                }
                break;
            } else
            {
                /* something else... */
                try
                {
                    packet.parseAndExecute();
                    packet.sendReply();
                } catch (IOException e)
                {
                    e.printStackTrace();
                } catch (EndSessionException e)
                {
                    e.printStackTrace();
                } catch (RuntimeException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}
TOP

Related Classes of com.zylin.zpu.simulator.gdb.Packet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.