コード例 #1
0
    def connect(self):
        """ attaches to blackmagic jtag debugger in swd mode """
        # ignore redundant stuff
        tmp = self.readpkt(timeout=1)
        while(tmp):
            tmp = self.readpkt(timeout=1)
        # enable extended mode
        self.fetchOK('!')

        # setup registers TODO
        # registers should be parsed from the output of, see target.xml
        #print self.fetch('qXfer:features:read:target.xml:0,3fb')
        #print self.fetch('Xfer:features:read:target.xml:3cf,3fb')
        #print self.fetch('qXfer:memory-map:read::0,3fb')
        #print self.fetch('qXfer:memory-map:read::364,3fb')

        self.port.setup(self)

        addr=struct.unpack(">I", self.getreg(4, 0x0800000c))[0] - 1
        self.br[format(addr, '08x')]={'sym': "FaultHandler",
                             'cb': self.checkfault}
        tmp = self.fetch('Z1,%s,2' % format(addr, 'x'))
        if tmp== 'OK':
            print "set break: @%s (0x%s)" % ('FaultHandler', format(addr, 'x')), tmp
            return

        # vector_catch enable hard int bus stat chk nocp mm reset
        self.send('qRcmd,766563746f725f636174636820656e61626c65206861726420696e742062757320737461742063686b206e6f6370206d6d207265736574')
        pkt=self.readpkt()
        while pkt!='OK':
            if pkt[0]!='O':
                raise ValueError('not O: %s' % pkt)
            if self.verbose:
                print unhex(pkt[1:-1])
            pkt=self.readpkt()
コード例 #2
0
ファイル: rsp.py プロジェクト: stef/pyrsp
    def set_br_a(self, addr, cb, quiet=False, sym=None):
        """ Sets a breakpoint at address, and install callback cb for it.

            `addr` is a hexadecimal string as defined by RSP protocol.
            Also, because of this RSP implementation `addr` format should be
            the same as defined by `reg_fmt`.

            Tips:
            - Use `reg_fmt` attribute to get `addr` string from an integer.
            - Normally, an unparsed register value has the same format and can
              be used as is.
        """
        if addr in self.br:
            print("warn: overwriting breakpoint at %s" % (sym or "0x" + addr))
            br = self.br[addr]
            br.update(sym=sym, cb=cb)
        else:
            self.br[addr] = br = {'sym': sym, 'addr': addr, 'cb': cb}
            if self.z_breaks:
                tmp = self.fetch(b'Z0,%s,2' % addr)
                if tmp == b"":
                    # Z/z packages are not supported, use code patching
                    self.z_breaks = False
                    br['old'] = unhex(self.fetch(b'm%s,2' % addr))
                    tmp = self.fetch(b'X%s,2:\xbe\xbe' % addr)
            else:
                br['old'] = unhex(self.fetch(b'm%s,2' % addr))
                tmp = self.fetch(b'X%s,2:\xbe\xbe' % addr)

            if self.verbose and not quiet:
                print("set break: @%s (0x%s) %s" %
                      (sym or "[unknown]", s(addr), s(tmp)))
コード例 #3
0
ファイル: rsp.py プロジェクト: stef/pyrsp
    def set_br_a(self, addr, cb, quiet=False, sym=None):
        """ Sets a breakpoint at address, and install callback cb for it.

            `addr` is a hexadecimal string as defined by RSP protocol.
            Also, because of this RSP implementation `addr` format should be
            the same as defined by `reg_fmt`.

            Tips:
            - Use `reg_fmt` attribute to get `addr` string from an integer.
            - Normally, an unparsed register value has the same format and can
              be used as is.
        """
        if addr in self.br:
            print("warn: overwriting breakpoint at %s" % (sym or "0x" + addr))
            br = self.br[addr]
            br.update(sym = sym, cb = cb)
        else:
            self.br[addr]= br = {'sym': sym, 'addr': addr, 'cb': cb}
            if self.z_breaks:
                tmp = self.fetch(b'Z0,%s,2' % addr)
                if tmp == b"":
                    # Z/z packages are not supported, use code patching
                    self.z_breaks = False
                    br['old'] = unhex(self.fetch(b'm%s,2' % addr))
                    tmp = self.fetch(b'X%s,2:\xbe\xbe' % addr)
            else:
                br['old'] = unhex(self.fetch(b'm%s,2' % addr))
                tmp = self.fetch(b'X%s,2:\xbe\xbe' % addr)

            if self.verbose and not quiet:
                print("set break: @%s (0x%s) %s" % (sym or "[unknown]", s(addr), s(tmp)))
コード例 #4
0
 def setup(self, rsp):
     rsp.send('qRcmd,737764705f7363616e')
     pkt = rsp.readpkt()
     while pkt != 'OK':
         if pkt[0] != 'O':
             raise ValueError('not O: %s' % pkt)
         if rsp.verbose:
             print unhex(pkt[1:-1])
         pkt = rsp.readpkt()
     rsp.fetchOK('vAttach;1', 'T05')
コード例 #5
0
 def setup(self, rsp):
     rsp.send('qRcmd,737764705f7363616e')
     pkt=rsp.readpkt()
     while pkt!='OK':
         if pkt[0]!='O':
             raise ValueError('not O: %s' % pkt)
         if rsp.verbose:
             print unhex(pkt[1:-1])
         pkt=rsp.readpkt()
     rsp.fetchOK('vAttach;1','T05')
コード例 #6
0
ファイル: rsp.py プロジェクト: stef/pyrsp
 def dump(self, size, addr = None):
     """ dumps data from addr if given otherwise at beginning of
         .text segment aka self.elf.workarea"""
     if addr==None:
         addr=self.elf.workarea
     rd = b''
     end = addr + size
     bsize = int(self.feats[b'PacketSize'], 16) // 2
     while addr < end:
         bsize = bsize if addr + bsize < end else end - addr
         #print('m%x,%x' % (addr, bsize))
         pkt = self.fetch(b'm%x,%x' % (addr, bsize))
         if len(pkt) & 1 and pkt[:1] == b'E':
             # There is an assumption that stub only uses 'e' for data
             # hexadecimal representation and 'E' is only used for errors.
             # However, no confirmation has been found in the protocol
             # definition. But, according to the protocol error message
             # data length is always odd (i.e. Exx).
             raise RuntimeError("Reading %u bytes at 0x%x failed: %s " % (
                 bsize, addr, s(pkt)
             ))
         rd += unhex(rsp_decode(pkt))
         addr += bsize
         #print("%s %s pkt %s" % (addr, bsize, pkt))
     return rd
コード例 #7
0
ファイル: rsp.py プロジェクト: wilvk/pyrsp
    def connect(self):
        """ attaches to blackmagic jtag debugger in swd mode """
        # ignore redundant stuff
        tmp = self.readpkt(timeout=1)
        while (tmp):
            tmp = self.readpkt(timeout=1)
        # enable extended mode
        self.fetchOK('!')

        # setup registers TODO
        # registers should be parsed from the output of, see target.xml
        #print self.fetch('qXfer:features:read:target.xml:0,3fb')
        #print self.fetch('Xfer:features:read:target.xml:3cf,3fb')
        #print self.fetch('qXfer:memory-map:read::0,3fb')
        #print self.fetch('qXfer:memory-map:read::364,3fb')

        self.port.setup(self)

        addr = struct.unpack(">I", self.getreg(4, 0x0800000c))[0] - 1
        self.br[format(addr, '08x')] = {
            'sym': "FaultHandler",
            'cb': self.checkfault
        }
        tmp = self.fetch('Z1,%s,2' % format(addr, 'x'))
        if tmp == 'OK':
            if self.verbose:
                print "set break: @%s (0x%s)" % ('FaultHandler',
                                                 format(addr, 'x')), tmp
            return

        # vector_catch enable hard int bus stat chk nocp mm reset
        self.send(
            'qRcmd,766563746f725f636174636820656e61626c65206861726420696e742062757320737461742063686b206e6f6370206d6d207265736574'
        )
        pkt = self.readpkt()
        while pkt != 'OK':
            if pkt[0] != 'O':
                raise ValueError('not O: %s' % pkt)
            if self.verbose:
                print unhex(pkt[1:-1])
            pkt = self.readpkt()
コード例 #8
0
ファイル: rsp.py プロジェクト: chaosAD/pyrsp
    def connect(self, id='1'):
        """ attaches to blackmagic jtag debugger in swd mode """
        # enable extended mode
        self.fetchOK('!')

        # setup registers TODO
        # registers should be parsed from the output of, see target.xml
        #self.fetch('qXfer:features:read:target.xml:0,3fb')
        #self.fetch('Xfer:features:read:target.xml:3cf,3fb')
        #self.fetch('qXfer:memory-map:read::0,3fb')
        #self.fetch('qXfer:memory-map:read::364,3fb')

        self.send('qRcmd,737764705f7363616e')
        pkt=self.readpkt()
        while pkt!='OK':
            if pkt[0]!='O':
                raise ValueError('not O: %s' % pkt)
            pkt=self.readpkt()
            if self.verbose:
                print unhex(pkt[1:-1])
        self.fetchOK('vAttach;%s' % id,'T05')
コード例 #9
0
    def connect(self, id='1'):
        """ attaches to blackmagic jtag debugger in swd mode """
        # enable extended mode
        self.fetchOK('!')

        # setup registers TODO
        # registers should be parsed from the output of, see target.xml
        #self.fetch('qXfer:features:read:target.xml:0,3fb')
        #self.fetch('Xfer:features:read:target.xml:3cf,3fb')
        #self.fetch('qXfer:memory-map:read::0,3fb')
        #self.fetch('qXfer:memory-map:read::364,3fb')

        self.send('qRcmd,737764705f7363616e')
        pkt = self.readpkt()
        while pkt != 'OK':
            if pkt[0] != 'O':
                raise ValueError('not O: %s' % pkt)
            pkt = self.readpkt()
            if self.verbose:
                print unhex(pkt[1:-1])
        self.fetchOK('vAttach;%s' % id, 'T05')
コード例 #10
0
ファイル: rsp.py プロジェクト: chaosAD/pyrsp
 def get_thread_info(self):
     tid = None
     tmp = self.fetch('qC')
     if tmp.startswith("QC"):
         tid=tmp[2:].strip()
     extra = unhex(self.fetch('qThreadExtraInfo,%s' % tid))
     tids = []
     tmp = self.fetch('qfThreadInfo')
     while tmp != 'l':
         if not tmp.startswith('m'):
             raise ValueError('invalid qThreadInfo response')
         tids.extend(tmp[1:].split(','))
         tmp = self.fetch('qsThreadInfo')
     return (tid, extra, tids)
コード例 #11
0
 def get_thread_info(self):
     tid = None
     tmp = self.fetch('qC')
     if tmp.startswith("QC"):
         tid = tmp[2:].strip()
     extra = unhex(self.fetch('qThreadExtraInfo,%s' % tid))
     tids = []
     tmp = self.fetch('qfThreadInfo')
     while tmp != 'l':
         if not tmp.startswith('m'):
             raise ValueError('invalid qThreadInfo response')
         tids.extend(tmp[1:].split(','))
         tmp = self.fetch('qsThreadInfo')
     return (tid, extra, tids)
コード例 #12
0
 def dump(self, size, addr=None):
     """ dumps data from addr if given otherwise at beginning of
         .text segment aka self.elf.workarea"""
     if addr == None:
         addr = self.elf.workarea
     rd = []
     i = 0
     bsize = int(self.feats['PacketSize'], 16)
     while (i < size):
         bsize = bsize if i + bsize < size else size - i
         self.send('m%x,%x' % (addr + i, bsize))
         pkt = self.readpkt()
         #print pkt
         rd.append(unhex(pkt))
         i += bsize
     return ''.join(rd)
コード例 #13
0
ファイル: rsp.py プロジェクト: chaosAD/pyrsp
 def dump(self, size, addr = None):
     """ dumps data from addr if given otherwise at beginning of
         .text segment aka self.elf.workarea"""
     if addr==None:
         addr=self.elf.workarea
     rd = []
     i=0
     bsize = int(self.feats['PacketSize'])
     while(i<size):
         bsize = bsize if i+bsize<size else size - i
         self.send('m%x,%x' % (addr+i, bsize))
         pkt=self.readpkt()
         #print pkt
         rd.append(unhex(pkt))
         i+=bsize
     return ''.join(rd)
コード例 #14
0
ファイル: rsp.py プロジェクト: chaosAD/pyrsp
    def dump_cb(self):
        """ rsp_dump callback, hit if rsp_dump is called. Outputs to
            stdout the source line, and a hexdump of the memory
            pointed by $r0 with a size of $r1 bytes. Then it resumes
            running.
        """
        src_line = self.get_src_line(int(self.regs['lr'],16) - 3)
        if src_line:
            print "%s:%s %s" % (src_line['file'], src_line['lineno'], src_line['line'])

        res_size = int(self.regs['r1'],16)
        if res_size < 1024: # for sanity
            ptr = int(self.regs['r0'],16)
            res = unhex(self.fetch('m%x,%x' % (ptr, res_size)))
            print hexdump(res, ptr)

        self.step_over_br()
コード例 #15
0
    def dump_cb(self):
        """ rsp_dump callback, hit if rsp_dump is called. Outputs to
            stdout the source line, and a hexdump of the memory
            pointed by $r0 with a size of $r1 bytes. Then it resumes
            running.
        """
        src_line = self.get_src_line(int(self.regs['lr'], 16) - 3)
        if src_line:
            print "%s:%s %s" % (src_line['file'], src_line['lineno'],
                                src_line['line'])

        res_size = int(self.regs['r1'], 16)
        if res_size <= 1024:  # for sanity
            ptr = int(self.regs['r0'], 16)
            res = unhex(self.fetch('m%x,%x' % (ptr, res_size)))
            print hexdump(res, ptr)

        self.step_over_br()
コード例 #16
0
 def set_br(self, sym, cb, quiet=False):
     """ sets a breakpoint at symbol sym, and install callback cb
         for it
     """
     addr = self.elf.symbols.get(sym)
     if not addr:
         print "unknown symbol: %s, ignoring request to set br" % sym
         return
     addr = "%08x" % (addr & ~1)
     if addr in self.br:
         print "warn: overwriting breakpoint at %s" % sym
         self.br[addr] = {'sym': sym, 'cb': cb, 'old': self.br[addr]['old']}
     else:
         self.br[addr] = {
             'sym': sym,
             'cb': cb,
             'old': unhex(self.fetch('m%s,2' % addr))
         }
     #self.fetch('Z0,%s,2' % addr)
     tmp = self.fetch('X%s,2:\xbe\xbe' % addr)
     if self.verbose and not quiet:
         print "set break: @%s (0x%s)" % (sym, addr), tmp
コード例 #17
0
ファイル: rsp.py プロジェクト: chaosAD/pyrsp
 def set_br(self, sym, cb, quiet=False):
     """ sets a breakpoint at symbol sym, and install callback cb
         for it
     """
     addr = self.elf.symbols.get(sym)
     if not addr:
         print "unknown symbol: %s, ignoring request to set br" % sym
         return
     addr = "%08x" % (addr & ~1)
     if addr in self.br:
         print "warn: overwriting breakpoint at %s" % sym
         self.br[addr]={'sym': sym,
                        'cb': cb,
                        'old': self.br[addr]['old']}
     else:
         self.br[addr]={'sym': sym,
                        'cb': cb,
                        'old': unhex(self.fetch('m%s,2' % addr))}
     #self.fetch('Z0,%s,2' % addr)
     tmp = self.fetch('X%s,2:\xbe\xbe' % addr)
     if self.verbose and not quiet:
         print "set break: @%s (0x%s)" % (sym, addr), tmp
コード例 #18
0
ファイル: rsp.py プロジェクト: stef/pyrsp
 def dump(self, size, addr=None):
     """ dumps data from addr if given otherwise at beginning of
         .text segment aka self.elf.workarea"""
     if addr == None:
         addr = self.elf.workarea
     rd = b''
     end = addr + size
     bsize = self.get_packet_size() // 2
     while addr < end:
         bsize = bsize if addr + bsize < end else end - addr
         #print('m%x,%x' % (addr, bsize))
         pkt = self.fetch(b'm%x,%x' % (addr, bsize))
         if len(pkt) & 1 and pkt[:1] == b'E':
             # There is an assumption that stub only uses 'e' for data
             # hexadecimal representation and 'E' is only used for errors.
             # However, no confirmation has been found in the protocol
             # definition. But, according to the protocol error message
             # data length is always odd (i.e. Exx).
             raise RuntimeError("Reading %u bytes at 0x%x failed: %s " %
                                (bsize, addr, s(pkt)))
         rd += unhex(rsp_decode(pkt))
         addr += bsize
         #print("%s %s pkt %s" % (addr, bsize, pkt))
     return rd
コード例 #19
0
 def getreg(self, size, ptr):
     tmp = self.fetch('m%x,%x' % (ptr, size))
     return unhex(switch_endian(tmp))
コード例 #20
0
ファイル: rsp.py プロジェクト: stef/pyrsp
 def getreg(self,size,ptr):
     tmp = self.fetch(b'm%x,%x' % (ptr, size))
     return unhex(switch_endian(tmp))
コード例 #21
0
def getreg(rsp, size, ptr):
    tmp = rsp.fetch('m%x,%x' % (ptr, size))
    return unhex(switch_endian(tmp))
コード例 #22
0
        rsp.refresh_regs()
        steps -= 1


if __name__ == "__main__":
    try:
        elffile = sys.argv[1] if len(sys.argv) > 1 else None
        rsp = CortexM3('/dev/ttyACM0', elffile, verbose=False)
        rsp.refresh_regs()
        dump_mpu(rsp)
        print 'flash_optcr=', printreg(
            flash_optcr.parse(getreg(rsp, 4, FLASH_OPTCR)))
        check_fault(rsp)
        print 'VTOR=', hex(struct.unpack(">I", getreg(rsp, 4, SCB_VTOR))[0])
        rsp.lazy_dump_regs()
        print 'xpsr=', printreg(xpsr.parse(unhex(rsp.regs['xpsr'])))
        #print hex()
        disassm(rsp, int(rsp.regs['pc'], 16), 4)
        if int(rsp.regs['pc'], 16) in [0x8003422, 0x8003424, 0x8003426]:
            rsp.set_reg('r3', rsp.regs['r0'])
            print "[x] force stepping over loop"
            while int(rsp.regs['pc'], 16) < 0x8003426:
                rsp.lazy_dump_regs()
                r = rsp.fetch('s')
                if r != 'T05': print r
            disassm(rsp, int(rsp.regs['pc'], 16), 4)

        print "[x] tracing"
        trace(rsp, 20)
        rsp.port.close(rsp)