예제 #1
0
    def add_dsts_entry(self, dstinfo):
        num = dstinfo.substage
        if num not in self.tables.iterkeys():
            self._init_table(num)
        r = self.tables[num].row
        for v in dstinfo.values:
            r['dstlo'] = v.begin
            r['dstlolo'] = utils.addr_lo(v.begin)
            r['dstlohi'] = utils.addr_hi(v.begin)
            r['dsthi'] = v.end
            r['dsthilo'] = utils.addr_lo(v.end)
            r['dsthihi'] = utils.addr_hi(v.end)
            r['dst_not_in_ram'] = self._addr_inter_is_not_ram(v)
            r['substage'] = dstinfo.substage
            line = dstinfo.key()
            r['line'] = line
            r['lvalue'] = dstinfo.lvalue
            if not dstinfo.pc:
                if hasattr(self.stage, "write_dest_hook"):
                    hook = getattr(self, getattr(self.stge, "write_dest_hook"))
                    hook(dstinfo)

            if dstinfo.pc == 0:
                print "cannot resove just one write instruction from %s" % dstinfo.__dict__
                continue
            r['writepc'] = dstinfo.pc
            r['writepclo'] = utils.addr_lo(dstinfo.pc)
            r['writepchi'] = utils.addr_hi(dstinfo.pc)
            r['origpc'] = dstinfo.origpc if dstinfo.origpc else long(
                r['writepc'])
            r['origpclo'] = utils.addr_lo(long(r['origpc']))
            r['origpchi'] = utils.addr_hi(long(r['origpc']))
            r.append()
예제 #2
0
 def _create_var_table(self, substage=-1):
     fields = ["startaddr", "size", "kind", "name"]
     vtab = self.var_table
     if vtab.nrows > 0:
         return
     cc = Main.cc
     stage = self.stage
     sname = stage.stagename
     elf = stage.elf
     cmd = "%snm -n -S %s" % (cc, elf)
     f = StringIO.StringIO(Main.shell.run_cmd(cmd))
     reader = csv.DictReader(f, fields, delimiter=" ",
                             lineterminator="\n", skipinitialspace=True)
     row = vtab.row
     for r in reader:
         if r['name'] is not None:
             row['name'] = r['name'].strip()
             row['startaddr'] = long(r['startaddr'].strip(), 16)
             row['startaddrlo'] = utils.addr_lo(long(row['startaddr']))
             row['startaddrhi'] = utils.addr_hi(long(row['startaddr']))
             row['endaddr'] = row['startaddr'] + long(r['size'].strip(), 16)
             row['endaddrlo'] = utils.addr_lo(long(row['endaddr']))
             row['endaddrhi'] = utils.addr_hi(long(row['endaddr']))
             row['rawkind'] = r['kind'].strip()
             k = row['rawkind'].lower()
             if ('t' == k) or ('w' == k):
                 row['kind'] = getattr(addr_space.var_type, 'text')
             else:
                 row['kind'] = getattr(addr_space.var_type, 'staticvar')
             row['perms'] = getattr(addr_space.var_perms, 'rw')
             row['substage'] = substage
             row.append()
     vtab.flush()
    def create_funcs_table(
            self
    ):  # using symbol information to get function location and length
        # symbol information (lenfth) does not always agree with objdump, but that's ok
        # (example: u-boot, get_tbclk)
        self.funcstable = self.h5file.create_table(self.group, 'funcs',
                                                   FuncEntry, "function info")
        cmd = "%snm -S -n --special-syms %s 2>/dev/null" % (Main.cc,
                                                            self.stage.elf)
        output = subprocess.check_output(cmd, shell=True).split('\n')
        r = self.funcstable.row
        for o in output:
            cols = o.split()
            if len(cols) == 4:
                (addr, size, typ, name) = cols
                addr = long(addr, 16)
                size = long(size, 16)
                r['fname'] = name
                r['startaddr'] = addr
                r['startaddrlo'] = utils.addr_lo(addr)
                r['startaddrhi'] = utils.addr_hi(addr)
                r['endaddr'] = addr + size
                r['endaddrlo'] = utils.addr_lo(addr + size)
                r['endaddrhi'] = utils.addr_hi(addr + size)
                r.append()
        self.funcstable.cols.startaddrlo.create_index(kind='full')
        self.funcstable.cols.endaddrlo.create_index(kind='full')
        self.funcstable.cols.startaddrhi.create_index(kind='full')
        self.funcstable.cols.endaddrhi.create_index(kind='full')

        self.funcstable.flush()
        self.h5file.flush()
예제 #4
0
    def write_interval_info(self,
                            hwname,
                            pclo=None,
                            pchi=None,
                            substage_names=[],
                            substage_entries={}):
        wt = self._get_writestable(hwname)
        if "framac" in hwname:
            return [(r['destlo'], r['desthi']) for r in
                    pytable_utils.get_rows('(%d <= writepclo) & (%d <= writepchi) & (writepclo < %d) & (writepchi <= %d)' % \
                                           (utils.addr_lo(pclo),
                                            utils.addr_hi(pclo),
                                            utils.addr_lo(pchi),
                                            utils.addr_hi(pchi)))]
        else:
            fns = substage_entries
            substages = substage_names
            num = 0
            intervals = {n: intervaltree.IntervalTree() for n in substages}

            for r in wt.read_sorted('index'):
                pc = long(r['pc'])
                if num < len(fns) - 1:
                    # check if we found the entrypoint to the next stage
                    (lopc, hipc) = substage_entries[num + 1]
                    if (lopc <= pc) and (pc < hipc):
                        num += 1
                if num in substages:
                    start = long(r['dest'])
                    end = start + pytable_utils.get_rows(
                        wt, '(pclo == %d) & (pchi == %d)' %
                        utils.addr_lo(long(r['pc'])),
                        utils.addr_hi(long(r['pc']))[0]['writesize'])
                    intervals[num].add(intervaltree.Interval(start, end))
            return intervals
예제 #5
0
    def addr2functionname(self, addr):
        # print "%x -> %x %x" % (addr, utils.addr_hi(addr), utils.addr_lo(addr))
        addr = long(addr)
        rs = pytable_utils.get_rows(self._sdb.db.funcstable, (
            "(startaddrlo <= 0x%x) & (startaddrhi <= 0x%x) & (0x%x < endaddrlo) & (0x%x <= endaddrhi)"
            % (utils.addr_lo(addr), utils.addr_hi(addr), utils.addr_lo(addr),
               utils.addr_hi(addr))))

        if rs:
            return rs[0]['fname']
        else:
            return ''
예제 #6
0
 def write_trace_intervals(self, interval, table):
     r = table.row
     for (num, iset) in interval.iteritems():
         for i in iset:
             lo = i.begin
             hi = i.end
             r['minaddr'] = lo
             r['minaddrlo'] = utils.addr_lo(lo)
             r['minaddrhi'] = utils.addr_hi(lo)
             r['maxaddr'] = hi
             r['maxaddrlo'] = utils.addr_lo(hi)
             r['maxaddrhi'] = utils.addr_hi(hi)
             r['substagenum'] = num
             r.append()
     table.flush()
 def create_longwrites_table(self):
     self.longwritestable = self.h5file.create_table(
         self.group, 'longwrites', LongWrites, "long writes to precompute")
     skips = []
     if not self.is_arm():
         return
     r2.run_aab(self.stage.elf)  # run basic block analysis
     for r in self.stage.longwrites:
         skips.append(LongWriteDescriptorGenerator(r.name, r.inplace, self))
     for s in skips:
         r = self.longwritestable.row
         sdesc = s.generate_descriptor()
         if not sdesc:
             print "We didn't find any longwrite labels for %s" % s.name
             continue
         # to prevent duplicate entries
         query = "(breakaddrlo == 0x%x) & (breakaddrhi == 0x%x)" % \
             (utils.addr_lo(sdesc.breakaddr), utils.addr_hi(sdesc.breakaddr))
         descs = pytable_utils.get_rows(self.longwritestable, query)
         if len(descs) > 0:
             print "found duplicate longwrite at breakpoint 0x%x" % sdesc.breakaddr
             continue
         if not sdesc.valid:
             "longwrite is not value, continuing"
             continue
         sdesc.populate_row(r)
         if self.verbose:
             print sdesc.get_info()
         r.append()
         self.longwritestable.flush()
     self.longwritestable.cols.breakaddrlo.create_index(kind='full')
     self.longwritestable.cols.breakaddrhi.create_index(kind='full')
     self.longwritestable.flush()
     self.writestable.flush()
     self.h5file.flush()
 def create_stageexit_table(self):
     self.stageexits = self.h5file.create_table(self.group, 'stageexits',
                                                StageExitInfo,
                                                "stage exit info")
     sls = WriteSearch.find_labels(labeltool.StageinfoLabel, "EXIT",
                                   self.stage, "")
     r = self.stageexits.row
     for l in sls:
         lineno = self._get_real_lineno(l)
         if lineno < 0:
             print "couldn't find label at %s" % l
             continue
         loc = "%s:%d" % (l.filename, lineno)
         addr = utils.get_line_addr(
             loc,
             True,
             self.stage,
             srcdir=Main.get_runtime_config("temp_target_src_dir"))
         success = True if l.name == "success" else False
         r['addr'] = addr
         r['addrlo'] = utils.addr_lo(addr)
         r['addrhi'] = utils.addr_hi(addr)
         r['line'] = loc
         r['success'] = success
         r.append()
     self.stageexits.flush()
예제 #9
0
    def disasm_and_src_from_pc(self, pc):
        r = pytable_utils.query(
            self._sdb.db.srcstable, "(addrlo == 0x%x) & (addrhi == 0x%x)" %
            (utils.addr_lo(long(pc)), utils.addr_hi(long(pc))))

        r = next(r)
        return (r["disasm"], r["src"])
예제 #10
0
 def create_substage_memmap_table(self):
     for c in self.csvs:
         with open(c) as csvfile:
             fields = ['name', 'startaddr', 'endaddr', 'perms', 'kind']
             reader = csv.DictReader(csvfile, fields)
             r = self.memmap_table.row
             for entry in reader:
                 for f in fields:
                     if "addr" in f:
                         entry[f] = long(entry[f], 0)
                         entry[f+"lo"] = utils.addr_lo(long(entry[f]))
                         entry[f+"hi"] = utils.addr_hi(long(entry[f]))
                     else:
                         entry[f] = entry[f].strip().lower()
                         if f == 'perms':
                             entry[f] = getattr(mmap_perms, entry[f])
                         elif f == 'kind':
                             entry[f] = getattr(mmap_type, entry[f])
                     r[f] = entry[f]
                 #r['substage'] = substage
                 r.append()
     self.memmap_table.cols.startaddrlo.create_index(kind='full')
     self.memmap_table.cols.startaddrhi.create_index(kind='full')
     self.memmap_table.cols.endaddrlo.create_index(kind='full')
     self.memmap_table.cols.endaddrhi.create_index(kind='full')
     self.memmap_table.flush()
예제 #11
0
 def stepper_write_info(self, pc):
     fields = self._sdb.db.writestable.colnames
     query = "(pclo == 0x%x) & (pchi == 0x%x)" % \
         (utils.addr_lo(pc),
          utils.addr_hi(pc))
     for r in pytable_utils.query(self._sdb.db.writestable, query):
         yield {f: r[f] for f in fields}
예제 #12
0
 def src_write_info(self, pc):
     fields = self._sdb.db.srcstable.colnames
     query = "(addrlo == 0x%x) & (addrhi == 0x%x)" % \
         (utils.addr_lo(pc),
          utils.addr_hi(pc))
     # query = "addr == 0x%x" % pc
     r = pytable_utils.get_unique_result(self._sdb.db.srcstable, query)
     return {f: r[f] for f in fields}
 def get_row_information(self):
     # DST, CPYSTART, CPYEND, BEGIN, READY
     info = {
         'relocpc': self.readyaddr,
         'relocpclo': utils.addr_lo(self.readyaddr),
         'relocpchi': utils.addr_hi(self.readyaddr),
         'relmod': self.relmod,
         'startaddr': self.cpystartaddr,
         'startaddrlo': utils.addr_lo(self.cpystartaddr),
         'startaddrhi': utils.addr_hi(self.cpystartaddr),
         'relbegin': self.beginaddr,
         'size': self.cpyendaddr - self.cpystartaddr,
         'reloffset': self.reloffset,
         'reldelorig': self.delorig,
         'symname': self.symname,
         'name': self.name,
     }
     return info
예제 #14
0
 def pc_write_size(self, pc):
     res = pytable_utils.query(
         self._sdb.db.writestable, "(pclo == 0x%x) & (pchi == 0x%x)" %
         (utils.addr_lo(pc), utils.addr_hi(pc)))
     try:
         r = next(res)
         return r['writesize']
     except:
         return 0
예제 #15
0
    def skip_info(self, pc):
        query = "(pclo == 0x%x) & (pchi == 0x%x)" % \
            (utils.addr_lo(pc),
             utils.addr_hi(pc))

        return [{
            "resumepc": r["resumepc"],
            "thumb": r["thumb"]
        } for r in pytable_utils.query(self._sdb.db.skipstable, query)]
 def populate_row(self, r):
     if not self.valid:
         return
     r['breakaddr'] = self.breakaddr
     r['breakaddrlo'] = utils.addr_lo(self.breakaddr)
     r['breakaddrhi'] = utils.addr_hi(self.breakaddr)
     r['contaddr'] = self.contaddr
     r['inplace'] = self.inplace
     r['writeaddr'] = self.writeaddr
     r['writeaddrlo'] = utils.addr_lo(self.writeaddr)
     r['writeaddrhi'] = utils.addr_hi(self.writeaddr)
     r['thumb'] = self.thumb
     r['writesize'] = self.writesize
     r['start'] = self.start
     r['startlo'] = utils.addr_lo(self.start)
     r['starthi'] = utils.addr_hi(self.start)
     r['end'] = self.end
     r['endlo'] = utils.addr_lo(self.end)
     r['endhi'] = utils.addr_hi(self.end)
    def _get_write_pc_or_zero(self, dstinfo):
        framac = True
        startlineaddr = self._get_line_addr(dstinfo.key(), True, framac)
        endlineaddr = self._get_line_addr(dstinfo.key(), False, framac)
        if (startlineaddr < 0) or (endlineaddr < 0):
            return 0

        query = "(0x%x <= pclo) & (0x%x <= pchi) & (pclo < 0x%x) & (pchi <= 0x%x)" % \
            (utils.addr_lo(startlineaddr),
             utils.addr_hi(startlineaddr),
             utils.addr_lo(endlineaddr),
             utils.addr_hi(endlineaddr))
        write = pytable_utils.get_rows(self.writestable, query)
        if len(write) == 1:
            return write[0]['pc']
        else:
            print "0 or more than 1 write (%d) in %s" % (len(write), query)
            #raise Exception('?')
            # either 0 or more than zero results
            return 0
예제 #18
0
 def _add_intervals_to_table(self, table, intervals, pc, line, lvalue, dst,
                             substage):
     intervals.merge_overlaps()
     intervals.merge_equals()
     intervals.merge_overlaps()
     r = table.row
     for i in intervals:
         r['writepc'] = pc
         r['writepclo'] = utils.addr_lo(long(pc))
         r['writepchi'] = utils.addr_hi(long(pc))
         r['line'] = line
         r['lvalue'] = lvalue
         r['dst_not_in_ram'] = dst
         r['substage'] = substage
         r['dstlo'] = i.begin
         r['dstlolo'] = utils.addr_lo(i.begin)
         r['dstlohi'] = utils.addr_hi(i.begin)
         r['dsthi'] = i.end
         r['dsthilo'] = utils.addr_lo(i.end)
         r['dsthihi'] = utils.addr_hi(i.end)
         r.append()
예제 #19
0
 def add_source_code_info_row(self, thumb, addr, ivalue, disasm):
     r = self._sdb.db.srcstable.row
     r['thumb'] = thumb
     r['addr'] = addr
     r['addrlo'] = utils.addr_lo(addr)
     r['addrhi'] = utils.addr_hi(addr)
     r['ivalue'] = ivalue
     r['ilength'] = len(ivalue)
     r['mne'] = (disasm.split())[0]
     r['disasm'] = disasm
     r.append()
     self._sdb.db.srcstable.flush()
예제 #20
0
    def pc_writes_info(self, pc):
        fields = [
            'pc', 'pclo', 'pchi', 'thumb', 'reg0', 'reg1', 'reg2', 'reg3',
            'reg4', 'writesize', 'halt'
        ]

        return {
            f: r[f]
            for f in fields for r in pytable_utils.query(
                self._sdb.db.writestable, "(pclo == 0x%x) & (pchi == 0x%x)" %
                (utils.addr_lo(pc), utils.addr_hi(pc)))
        }
 def update_from_trace(self, tracewrites):
     for w in tracewrites:
         pc = long(w["pc"])
         thumb = self.thumbranges.overlaps_point(pc)
         s = self.srcstable.where("(addrlo == 0x%x) & (addrhi == 0x%x)" %
                                  (utils.addr_lo(pc), utils.addr_hi(pc)))
         try:
             s = next(s)
             # is in table, do nothing
         except StopIteration:
             r2.gets(self.stage.elf, "s 0x%x" % pc)
             i = r2.get(self.stage.elf, "pdj 1")[0]
             ins = b"%s" % i["bytes"]
             dis = i["disasm"]
             mne = dis.split()[0]
             srcr = self.srcstable.row
             srcr['addr'] = pc
             srcr['addrlo'] = utils.addr_lo(pc)
             srcr['addrhi'] = utils.addr_hi(pc)
             srcr['line'] = utils.addr2line(pc, self.stage)
             srcr['src'] = utils.line2src(srcr['line'])
             srcr['ivalue'] = ins
             srcr['ilength'] = len(ins)
             srcr['thumb'] = thumb
             srcr['disasm'] = dis
             srcr['mne'] = mne
             srcr.append()
             ws = self.writestable.row
             ws['thumb'] = thumb
             ws['pc'] = pc
             ws['pclo'] = utils.addr_lo(pc)
             ws['pchi'] = utils.addr_hi(pc)
             ws['writesize'] = w['reportedsize']
             ws['halt'] = False
             ws.append
     self.srcstable.flush()
     self.srcstable.reindex()
     self.writestable.flush()
     self.writestable.reindex()
     self.h5file.flush()
예제 #22
0
    def populate_mmap_tables(self, mmap_info):
        info_table = self.substage_mmap_info_table
        addr_table = self.substage_mmap_addr_table
        if addr_table.nrows > 0 or info_table.nrows > 0:
            return
        info_row = info_table.row
        for (short_name, region) in mmap_info.regions.iteritems():
            info_row['short_name'] = short_name
            info_row['parent_name'] = region.parent.short_name if region.parent else ''
            info_row['name'] = region.name
            info_row['comments'] = region.contents
            info_row['include_children'] = region.include_children
            info_row['do_print'] = True
            if region.parent and region.parent._csv:
                info_row['do_print'] = False
            info_row['reclassifiable'] = region.reclassifiable
            info_row.append()
        info_table.flush()
        info_table.cols.short_name.reindex()
        info_table.cols.parent_name.reindex()

        addr_row = addr_table.row
        for (short_name, region) in mmap_info.regions.iteritems():
            for a in region.addresses:
                addr_row['short_name'] = short_name
                addr_row['startaddr'] = a.begin
                addr_row['startaddrlo'] = utils.addr_lo(a.begin)
                addr_row['startaddrhi'] = utils.addr_hi(a.begin)
                addr_row['endaddr'] = a.end
                addr_row['endaddrlo'] = utils.addr_lo(a.end)
                addr_row['endaddrhi'] = utils.addr_hi(a.end)
                addr_row.append()
        addr_table.flush()
        addr_table.cols.short_name.reindex()
        addr_table.cols.startaddrlo.reindex()
        addr_table.cols.startaddrhi.reindex()
        addr_table.cols.endaddrlo.reindex()
        addr_table.cols.endaddrhi.reindex()
        self.h5mmap.flush()
    def __init__(self, start, end, inplace, table):
        self.stage = table.stage
        self.table = table
        self.inplace = inplace
        self.valid = False
        self.start = start
        self.end = end
        self.thumb = self.table.thumbranges.overlaps_point(self.start)
        self.info = LongWriteInfo(self.stage.elf, self.start, self.end,
                                  self.thumb)
        self.info.calculate_info()

        ins = self.table.ia.disasm(
            b"%s" % self.info.write_ins["bytes"].decode("hex"), self.thumb,
            self.info.write_ins["offset"])
        self.write_size = self.table.ia.calculate_store_size(ins)
        self.breakaddr = self.info.start_ins_addr
        self.writeaddr = self.info.write_ins_addr
        self.contaddr = self.info.finish_ins_addr
        writes = self.table.writestable.where(
            "(0x%x == pclo) & (0x%x == pchi)" %
            (utils.addr_lo(self.writeaddr), utils.addr_hi(self.writeaddr)))
        try:
            write = next(writes)
        except Exception as e:
            print e
            print "Longwrite not found at %x (%s)" % (self.writeaddr,
                                                      self.__dict__)
            return
        self.valid = True
        self.writesize = write['writesize']
        r2.get(self.stage.elf, "s 0x%x" % self.writeaddr)
        if self.thumb:
            r2.get(self.stage.elf, "e asm.bits=16")
            r2.gets(self.stage.elf, "ahb 16")
        else:
            r2.get(self.stage.elf, "e asm.bits=32")
            r2.gets(self.stage.elf, "ahb 32")

        r2.get(self.stage.elf, "pd 1")
        i = r2.get(self.stage.elf, "pdj 1")[0]
        self.value = b"%s" % i["bytes"]
        self.disasm = i["disasm"]

        write['halt'] = False
        write.update()
        self.funname = db_info.get(self.stage).addr2functionname(
            self.writeaddr)
        self.instr = self.table.ia.disasm(self.value, self.thumb,
                                          self.writeaddr)
        self.table.writestable.flush()
예제 #24
0
    def _create_reg_table(self):
        for c in self.reg_csvs:
            (f, reader) = parse_am37x_register_tables.parsecsv(c)
            row = self.reg_table.row
            for r in reader:
                row['address'] = long(r['address'].strip(), 16) if r['address'] else 0
                row['addresslo'] = utils.addr_lo(long(row['address']))
                row['addresshi'] = utils.addr_hi(long(row['address']))
                row["offset"] = long(r["offset"].strip(), 16) if r["offset"] else 0
                row['offsetlo'] = utils.addr_lo(long(row['offset']))
                row['offsethi'] = utils.addr_hi(long(row['offset']))
                row["table"] = r["table"] if r["table"] else ""
                row["typ"] = r["typ"] if r["typ"] else ""
                row["width"] = long(r["width"]) if r["width"] else 0
                row["reset"] = r["reset"] if r["reset"] else ""
                row["name"] = r["name"] if r["name"] else ""
                if row['address'] == 0:
                    print "addr not found in %s" % r

                row.append()
            f.close()
        self.reg_table.cols.addresslo.create_index(kind='full')
        self.reg_table.cols.addresshi.create_index(kind='full')
        self.reg_table.flush()
예제 #25
0
 def add_write_entry(self,
                     time,
                     pid,
                     size,
                     dest,
                     pc,
                     lr,
                     cpsr,
                     callindex=0,
                     substagenum=None):
     #if self.pcmin > self.pcmax:
     #    print "PC not in range %x %x (%x)" % (self.pcmin, self.pcmax, pc)
     # traceback.print_stack()
     #if (pc <= self.pcmax) and (pc >= self.pcmin):
     # get relocation info from writesearch database
     #index = self.trace_count
     r = self.writestable.row
     r['pid'] = pid
     r['dest'] = dest
     r['relocatedpc'] = pc
     r['relocatedpclo'] = utils.addr_lo(pc)
     r['relocatedpchi'] = utils.addr_hi(pc)
     r['relocatedlr'] = lr
     r['relocatedlrlo'] = utils.addr_lo(lr)
     r['relocatedlrhi'] = utils.addr_hi(lr)
     r['time'] = time
     r['reportedsize'] = size
     r['callindex'] = callindex
     r['index'] = self.trace_count
     r['cpsr'] = cpsr
     r['pc'] = pc
     r['pclo'] = utils.addr_lo(pc)
     r['pchi'] = utils.addr_hi(pc)
     r['lr'] = lr
     r['lrlo'] = utils.addr_lo(lr)
     r['lrhi'] = utils.addr_hi(lr)
     if substagenum is not None:
         r['substage'] = substagenum
     for rinfo in self.rinfos:
         offset = rinfo['reloffset']
         start = (rinfo['startaddr'] + offset)
         end = start + rinfo['size'] + offset
         # if pc is in a relocated dest range  (for now we assume no overlap)
         if (start <= pc) and (pc <= end):
             r['pc'] = pc - offset
             r['pclo'] = utils.addr_lo(long(r['pc']))
             r['pchi'] = utils.addr_hi(long(r['pc']))
             r['lr'] = lr - offset
             r['lrlo'] = utils.addr_lo(long(r['lr']))
             r['lrhi'] = utils.addr_hi(long(r['lr']))
             break
     self.trace_count += 1
     r.append()
예제 #26
0
    def _find_mux_pc(self, dst):
        user = {'res': None, 'dst': long(dst)}

        def code_hook(emu, access, addr, size, value, user):
            dst = long(user['dst'])
            if long(addr) == dst:
                pc = emu.reg_read(UC_ARM_REG_PC)
                user['res'] = pc

            return True

        user['dst'] = dst
        user['dstlo'] = utils.addr_lo(dst)
        user['dsthi'] = utils.addr_hi(dst)
        h = self.emu.hook_add(UC_HOOK_MEM_WRITE, code_hook, user_data=user)
        if self._thumb:
            self.emu.emu_start(self._mux_start | 1, self._mux_end)
        else:
            self.emu.emu_start(self._mux_start, self._mux_end)
        self.emu.hook_del(h)
        if user['res'] is None:
            raise Exception("DSF %x" % dst)
        return user['res']
예제 #27
0
 def addr_in_funcs_table(self, pc):
     return pytable_utils.has_results(
         self._sdb.db.funcstable,
         "(startaddrlo <= 0x%x) & (startaddrhi <= 0x%x) & (0x%x < endaddrlo) & (0x%x <= endaddrhi)"
         % (utils.addr_lo(pc), utils.addr_hi(pc), utils.addr_lo(pc),
            utils.addr_hi(pc)))
예제 #28
0
    def histogram(self):
        group = self.get_group()

        if hasattr(group, 'writerange'):
            # make the table again, just in case
            group.writerange.remove()
        self.histotable = self.h5file.create_table(group, 'writerange',
                                                   TraceWriteRange,
                                                   "qemu memory write ranges")
        self.histotable.cols.index.create_index(kind='full')
        histotable = self.histotable
        srcdir = Main.raw.runtime.temp_target_src_dir
        relocatedpc = 0
        relocatedlr = 0
        size = 0
        byteswritten = 0
        destlo = 0
        currentrow = None
        line = ''
        index = 0
        push = False
        pc = -1
        sub = -1
        for writerow in self.writestable.read_sorted('index'):
            if (long(writerow['relocatedpc']) == relocatedpc) and \
               (long(writerow['relocatedlr']) == relocatedlr) and \
               ((destlo + byteswritten) == long(writerow['dest'])):
                # append to current row
                currentrow['byteswritten'] += size
                byteswritten = currentrow['byteswritten']
                if push:
                    currentrow['destlo'] = currentrow['desthi'] - byteswritten
                    currentrow['destlolo'] = utils.addr_lo(
                        long(currentrow['destlo']))
                    currentrow['destlohi'] = utils.addr_hi(
                        long(currentrow['destlo']))
                else:
                    currentrow['desthi'] = currentrow['destlo'] + byteswritten
                    currentrow['desthilo'] = utils.addr_lo(
                        long(currentrow['desthi']))
                    currentrow['desthihi'] = utils.addr_hi(
                        long(currentrow['desthi']))
                currentrow['numops'] += 1
            else:
                # create a new row
                if currentrow is not None:
                    if push:
                        push = False
                    currentrow.append()
                # start a new row
                currentrow = self.histotable.row
                pc = long(writerow['pc'])
                relocatedpc = long(writerow['relocatedpc'])
                relocatedpclo = utils.addr_lo(relocatedpc)
                relocatedpchi = utils.addr_hi(relocatedpc)
                relocatedlr = long(writerow['relocatedlr'])
                relocatedlrlo = utils.addr_lo(relocatedlr)
                relocatedlrhi = utils.addr_hi(relocatedlr)
                currentrow['cpsr'] = writerow['cpsr']
                currentrow['lr'] = long(writerow['lr'])
                currentrow['lrlo'] = utils.addr_lo(long(writerow['lr']))
                currentrow['lrhi'] = utils.addr_hi(long(writerow['lr']))
                lr = writerow['lr']
                sub = writerow['substage']
                currentrow['numops'] = 1
                currentrow['pc'] = pc
                currentrow['pclo'] = utils.addr_lo(pc)
                currentrow['pchi'] = utils.addr_hi(pc)
                currentrow['relocatedpc'] = relocatedpc
                currentrow['relocatedpclo'] = utils.addr_lo(relocatedpc)
                currentrow['relocatedpchi'] = utils.addr_hi(relocatedpc)
                currentrow['relocatedlr'] = relocatedlr
                currentrow['relocatedlrlo'] = utils.addr_lo(relocatedlr)
                currentrow['relocatedlrhi'] = utils.addr_hi(relocatedlr)
                currentrow['substage'] = sub
                currentrow['index'] = index
                index += 1
                size = db_info.get(self.stage).pc_write_size(pc)
                if size < 0:
                    desthi = long(writerow['dest'])
                    currentrow['desthi'] = desthi
                    currentrow['desthilo'] = utils.addr_lo(desthi)
                    currentrow['desthihi'] = utils.addr_hi(desthi)
                    currentrow['destlo'] = long(desthi - size)
                    currentrow['destlolo'] = utils.addr_lo(
                        long(currentrow['destlo']))
                    currentrow['destlohi'] = utils.addr_hi(
                        long(currentrow['destlo']))
                    size = -1 * size
                    push = True
                else:
                    push = False
                    destlo = long(writerow['dest'])
                    currentrow['destlo'] = destlo
                    currentrow['destlolo'] = utils.addr_lo(destlo)
                    currentrow['destlohi'] = utils.addr_hi(destlo)

                    currentrow['desthi'] = long(destlo + size)
                    currentrow['desthilo'] = utils.addr_lo(
                        long(currentrow['desthi']))
                    currentrow['desthihi'] = utils.addr_hi(
                        long(currentrow['desthi']))

                byteswritten = size
                currentrow['byteswritten'] = size

        if currentrow is not None:
            currentrow.append()  # append last row
        histotable.flush()
        histotable.reindex()
        substagenums = substage.SubstagesInfo.substage_numbers(self.stage)
        print histotable.nrows
        for i in substagenums:
            print "# block writes for substage %d: %d" % (
                i, len([n for n in histotable.where("substage == %d" % i)]))
        self.h5file.flush()
    def get_row_information(self):
        row = {}
        labels = WriteSearch.find_labels(labeltool.SkipLabel, "", self.stage,
                                         self.name)
        startaddr = -1
        endaddr = -1
        start = ""
        end = ""
        elf = self.stage.elf
        srcdir = Main.get_runtime_config("temp_target_src_dir")
        isfunc = False
        for l in labels:
            if not l.name == self.name:
                continue
            if l.value == "START":
                lineno = self.table._get_real_lineno(l, False)
                start = "%s:%d" % (l.filename, lineno)
            elif l.value == "END":
                lineno = self.table._get_real_lineno(l, True)
                end = "%s:%d" % (l.filename, lineno)
            elif l.value == "FUNC":
                isfunc = True
                lineno = self.table._get_real_lineno(l, False)
                start = "%s:%d" % (l.filename, lineno)
                startaddr = self.table._get_line_addr(start, True)
                f = pytable_utils.get_unique_result(self.table.funcstable, (
                    "(startaddrlo <= 0x%x) & (0x%x < endaddrlo) & (startaddrhi <= 0x%x) & (0x%x <= endaddrhi)"
                    % (utils.addr_lo(startaddr), utils.addr_lo(startaddr),
                       utils.addr_hi(startaddr), utils.addr_hi(startaddr))))

                (startaddr, endaddr) = (f['startaddr'], f['endaddr'])
                r2.get(elf, "s 0x%x" % startaddr)
                thumb = False
                if self.table.thumbranges.overlaps_point(startaddr):
                    thumb = True
                if thumb:
                    r2.get(self.stage.elf, "e asm.bits=16")
                    r2.gets(self.stage.elf, "ahb 16")
                else:
                    r2.get(self.stage.elf, "e asm.bits=32")
                    r2.gets(self.stage.elf, "ahb 32")

                disasm = r2.get(elf, "pd 2")
                disasm = r2.get(elf, "pdj 2")

                if disasm[0]["disasm"].startswith("push"):
                    firstins = disasm[1]
                else:
                    firstins = disasm[0]
                startaddr = firstins["offset"]
                #print "start %s,%x" % (startaddr, endaddr)
            elif l.value == "NEXT":
                lineno = self.table._get_real_lineno(l, False)
                start = "%s:%d" % (l.filename, lineno)
                end = "%s:%d" % (l.filename, lineno)
            if lineno == -1:
                return None
        if (startaddr < 0) and (endaddr < 0):
            # move startaddr after any push instructions
            startaddr = self.table._get_line_addr(start, True)
            endaddr = self.table._get_line_addr(end, False)
            r2.get(elf, "s 0x%x" % startaddr)
            thumb = False
            if self.table.thumbranges.overlaps_point(startaddr):
                thumb = True

            if thumb:
                r2.gets(self.stage.elf, "ahb 16")
                r2.get(self.stage.elf, "e asm.bits=16")
            else:
                r2.gets(self.stage.elf, "ahb 32")
                r2.get(self.stage.elf, "e asm.bits=32")
            disasm = r2.get(elf, "pd 2")
            disasm = r2.get(elf, "pdj 2")
            if "disasm" in disasm[0]:
                if (disasm[0][u"disasm"].startswith("push")):
                    # don't include push instruction
                    startins = disasm[1]
                else:
                    startins = disasm[0]
                startaddr = startins["offset"]

        s = long(startaddr + self.adjuststart)
        e = long(endaddr + self.adjustend)
        if e < s:
            t = s
            s = e
            e = t
        row['pc'] = s
        row['pclo'] = utils.addr_lo(s)
        row['pchi'] = utils.addr_hi(s)
        row['resumepc'] = e
        row['resumepclo'] = utils.addr_lo(e)
        row['resumepchi'] = utils.addr_hi(e)
        row['isfunction'] = isfunc
        row['thumb'] = self.table.thumbranges.overlaps_point(row['pc'])
        return row
    def create_writes_table(self, start=0, stop=0):
        self.writestable = self.h5file.create_table(
            self.group, 'writes', WriteEntry, "statically determined pc \
                                                    values for write instructions"
        )
        self.smcstable = self.h5file.create_table(
            self.group, 'smcs', SmcEntry, "statically determined pc values \
                                                  for smc instructions")
        self.srcstable = self.h5file.create_table(self.group, 'srcs', SrcEntry,
                                                  "source code info")
        # now look at instructions
        if not self.is_arm():
            return
        srcdir = Main.get_runtime_config("temp_target_src_dir")

        allranges = intervaltree.IntervalTree()
        for s in utils.get_section_headers(self.stage):
            if s['flags'].endswith('x'):
                if s['size'] == 0:
                    continue
                allranges.add(
                    intervaltree.Interval(long(s['address']),
                                          long(s['address'] + s['size'])))
        allranges.merge_overlaps()

        r = self.writestable.row
        smcr = self.smcstable.row
        allranges = self.thumbranges | self.armranges

        # loop through all instructions as according to debug symbols
        for (ra, thumb) in [(self.thumbranges, True), (self.armranges, False)]:
            for ir in ra:
                pc_next = ir.begin
                while pc_next < ir.end:
                    pc = pc_next
                    p = False
                    r2.gets(self.stage.elf, "s 0x%x" % pc)
                    if thumb:  # force r2 to use the correct instruction size. sigh.
                        r2.gets(self.stage.elf, "ahb 16")
                        r2.gets(self.stage.elf, "e asm.bits=16")
                    else:
                        r2.gets(self.stage.elf, "ahb 32")
                        r2.gets(self.stage.elf, "e asm.bits=32")
                    r2.get(self.stage.elf, "pd 1")
                    ins_info = r2.get(self.stage.elf, "pdj 1")[0]
                    if p:
                        for k, v in ins_info.iteritems():
                            print "%s: %s" % (k, v)
                        print "offset %x" % ins_info["offset"]
                    insadded = False
                    if not "disasm" in ins_info or u"invalid" == ins_info[
                            "type"] or u"invalid" == ins_info["disasm"]:
                        print "invalid instruction according to r2: pc: %x, is thumb? %s. Using capstone to disassemble" % (
                            pc, thumb)
                        if 'bytes' in ins_info:  # get results of capstone disassembly
                            inscheck = self.ia.disasm(
                                b"%s" % ins_info['bytes'].decode("hex"), thumb,
                                pc)
                            ins_info[
                                'disasm'] = inscheck.mnemonic + " " + inscheck.op_str
                        else:
                            print ins_info
                            raise Exception()
                    pc = ins_info['offset']
                    dis = ins_info['disasm']
                    val = ins_info['bytes']
                    mne = dis.split()[0]
                    ins = b"%s" % val.decode('hex')
                    pc_next += ins_info['size']
                    #... just in case radare2 doesn't properly report invalid instructions
                    try:
                        inscheck = self.ia.disasm(ins, thumb, pc)
                    except StopIteration:
                        print "Radare2 disassembled invalid instruction 0x%x (%s) as %s" % (
                            pc, val, ins_info)
                        continue
                    if mne != inscheck.mnemonic:
                        if thumb:
                            r2.gets(self.stage.elf, "e asm.bits=16")
                            r2.gets(self.stage.elf, "ahb 16")
                        else:
                            r2.gets(self.stage.elf, "ahb 32")
                            r2.gets(self.stage.elf, "e asm.bits=32")
                        print "R2 and capstone disagree at %x %s" % (pc, thumb)
                        print "CAPSTONE --->"
                        print "addr: %x" % inscheck.address
                        print "op: %s" % inscheck.op_str
                        print "mne: %s" % inscheck.mnemonic
                        print "byres: %s" % ["%x" % b for b in inscheck.bytes]
                        print "size: %s" % inscheck.size
                        print "r2 ------------------------>"
                        print r2.gets(self.stage.elf, "e asm.bits")
                        for (k, v) in ins_info.iteritems():
                            print "%s: %s" % (k, v)
                        r2.get(self.stage.elf, "s 0x%x" % pc)
                        print r2.gets(self.stage.elf, "pd 1")
                        if self.ia.is_mne_memstore(
                                mne) or self.ia.is_mne_memstore(
                                    inscheck.mnemonic):
                            raise Exception
                        print "... But I guess it doesn't matter because neither instruction modifies memory."
                    if mne and self.ia.is_mne_memstore(mne):
                        if self.dataranges.overlaps_point(pc):
                            continue
                        r['thumb'] = thumb
                        r['pc'] = pc
                        r['pclo'] = utils.addr_lo(pc)
                        r['pchi'] = utils.addr_hi(pc)
                        r['halt'] = True
                        regs = self.ia.needed_regs(inscheck)
                        if len(regs) > 4:
                            raise Exception("Sorry, too many registers")
                        for i in range(len(regs)):
                            r['reg%d' % i] = regs[i]
                        size = self.ia.calculate_store_size(inscheck)

                        r['writesize'] = size
                        insadded = True
                        r.append()
                    elif mne == 'smc':  # add to smcs table
                        smcr['pc'] = pc
                        smcr['pclo'] = utils.addr_lo(pc)
                        smcr['pchi'] = utils.addr_hi(pc)
                        mne = 'smc'
                        thumb = False
                        if self.thumbranges.overlaps_point(pc):
                            thumb = True
                        smcr['thumb'] = thumb
                        insadded = True
                        smcr.append()
                        if self.verbose:
                            print "smc at 0x%x" % pc
                    if insadded:  # also cache source code information related to instruction
                        s = self.srcstable.where(
                            "(addrlo == 0x%x) & (addrhi == 0x%x)" %
                            (utils.addr_lo(pc), utils.addr_hi(pc)))
                        try:
                            s = next(s)
                            # is in table, do nothing
                        except StopIteration:
                            srcr = self.srcstable.row
                            srcr['addr'] = pc
                            srcr['addrlo'] = utils.addr_lo(pc)
                            srcr['addrhi'] = utils.addr_hi(pc)
                            srcr['line'] = utils.addr2line(pc, self.stage)
                            srcr['src'] = utils.line2src(srcr['line'])
                            srcr['ivalue'] = ins
                            srcr['ilength'] = len(ins)
                            srcr['thumb'] = thumb
                            srcr['disasm'] = dis
                            srcr['mne'] = mne
                            srcr.append()
                            self.srcstable.flush()
                        insadded = False
        self.writestable.flush()
        self.writestable.cols.pclo.create_index(kind='full')
        self.writestable.cols.pchi.create_index(kind='full')
        self.smcstable.flush()
        self.smcstable.cols.pclo.create_index(kind='full')
        self.smcstable.cols.pchi.create_index(kind='full')
        self.srcstable.flush()
        self.srcstable.cols.addrlo.create_index(kind='full')
        self.srcstable.cols.addrhi.create_index(kind='full')
        self.srcstable.cols.line.create_index(kind='full')
        self.smcstable.flush()
        self.h5file.flush()