Ejemplo n.º 1
0
 def divide_intervals(self, stages, table):
     divided_intervals = {i: intervaltree.IntervalTree() for i in stages}
     for r in table.iterrows():
         n = r["substagenum"]
         divided_intervals[n].add(intervaltree.Interval(long(r["minaddr"]), long(r["maxaddr"])))
         if self.interval_type == self.CUMULATIVE:
             for i in range(n + 1, len(stages)):
                 divided_intervals[i].add(intervaltree.Interval(long(r["minaddr"]), long(r["maxaddr"])))
     for i in divided_intervals.itervalues():
         i.merge_overlaps()
     return divided_intervals
Ejemplo n.º 2
0
 def lookup_symbol_interval(self, name, num):
     (startaddr, endaddr) = db_info.get(self.stage).mmap_var_loc(name)
     reloc_names = db_info.get(self.stage).reloc_names_in_substage(num)
     varloc = intervaltree.Interval(long(startaddr), long(endaddr))
     for (rname, rbegin,
          rsize, roffset) in db_info.get(self.stage).reloc_info_by_cardinal(reloc_names):
         relrange = intervaltree.Interval(long(rbegin), long(rbegin + rsize))
         if relrange.contains_interval(varloc):
             offset = roffset
             varloc = intervaltree.Interval(long(varloc.begin + offset),
                                            long(varloc.end + offset))
     return varloc
Ejemplo n.º 3
0
 def update_writes(self,
                   line,
                   pc,
                   lo,
                   hi,
                   stage,
                   origpc=None,
                   substage=None):
     if not pc:
         (path, lineno) = line.split(':')
         lineno = int(lineno)
     else:
         (path, lineno) = ('', 0)
     if not origpc:
         origpc = pc
     w = WriteDstResult(path,
                        lineno,
                        '', [intervaltree.Interval(long(lo), long(hi))],
                        pc,
                        origpc,
                        substage_name=substage)
     if lo > hi:
         print "%x > %x at %x" % (lo, hi, pc)
         traceback.print_stack()
     self.writerangetable.add_dsts_entry(w)
Ejemplo n.º 4
0
 def from_line(cls, line, stage):
     res = cls.regexp.match(line.strip())
     if res is None:
         raise Exception("%s is not a framac dst result")
     else:
         min_value = long(res.group(1), 0)
         max_value = long(res.group(2), 0)
         #if max_value > 0xFFFFFFFF:
         #    max_value = 0xFFFFFFFF
         lvalue = res.group(3)
         path = res.group(4)
         # somewhat of a hack to get relative path
         root = Main.get_target_cfg().software_cfg.root
         if path.startswith(root):
             path = os.path.relpath(path, root)
             path = os.path.join(Main.raw.runtime.temp_target_src_dir, path)
         elif path.startswith(
                 Main.test_suite_path):  # not sure why this happens
             path = os.path.relpath(path, Main.test_suite_path)
             path = os.path.join(Main.raw.runtime.temp_target_src_dir, path)
         elif path.startswith("/tmp/tmp"):
             path = "/".join(path.split("/")[3:])
             path = os.path.join(Main.raw.runtime.temp_target_src_dir, path)
         lineno = int(res.group(5))
         callstack = res.group(6)
         # somewhat of a hack for muxconf
         return cls(path,
                    lineno,
                    lvalue, [intervaltree.Interval(min_value, max_value)],
                    callstack=callstack,
                    stage=stage)
Ejemplo n.º 5
0
 def _add_addr_range(self, start, end):
     if isinstance(start, (int, long)) and isinstance(end, (int, long)):
         if not end >= start:
             raise Exception(
                 "start addr %x must be smaller than end address %x for %s"
                 % (start, end, self.short_name))
         self.addresses.add(intervaltree.Interval(long(start), long(end)))
     else:
         raise Exception(
             "One of start addr (%s) end addr (%s) is not an int for %s" %
             (start, end, self.short_name))
Ejemplo n.º 6
0
    def setup(self):
        if not self.attr_exists("setup_done"):
            self.populate_path_from_name("hw_info_path",
                                         or_default=True,
                                         do_setattr=True)
            self._check_path("hw_info_path")
            self._update_raw("hw_info_path", self.hw_info_path)

            self.setup_done = True
            self.host_cfgs = {}
            for h in self.hosts:
                self.host_cfgs[h] = self.object_config_lookup("HostConfig", h)

            if not self.attr_exists("addr_range"):
                self.addr_range = Main.default_raw.HardwareClass._hw.addr_range
            lo = long(self.addr_range[0])
            hi = long(self.addr_range[1])
            self.addr_range = intervaltree.IntervalTree(
                [intervaltree.Interval(lo, hi)])
            range_intervals = []
            self.addr_range_names = []
            if self.attr_exists("named_addr_ranges"):
                for (k, [lo, hi]) in self.named_addr_ranges.iteritems():
                    self.addr_range_names.append(k)
                    inter = intervaltree.Interval(long(lo), long(hi))
                    range_intervals.append(inter)
                    setattr(self, k, inter)
                    self._update_raw(k, inter)

            self.ram_ranges = intervaltree.IntervalTree(range_intervals)
            self.ram_ranges.merge_overlaps()
            self.non_ram_ranges = self.addr_range
            for r in self.ram_ranges:
                self.non_ram_ranges.chop(r.begin, r.end)
                self.non_ram_ranges.remove_overlap(r)
            if not hasattr(self, "default_host"):
                self.default_host = self.hosts[0]
Ejemplo n.º 7
0
    def calculate_framac_intervals(self, substages):

        intervals = {n: intervaltree.IntervalTree() for n in substages}
        for num in substages:
            for r in pytable_utils.get_rows(self.trace_intervals_table,
                                            'substagenum == %s' % num):
                # lookup writes performed by this function
                f = r['functionname']
                (lopc, hipc) = self.fun_info(f)
                res = db_info.get(self.stage).write_interval_info(tracename, lopc, hipc)
                intervals[num] += intervaltree.IntervalTree([intervaltree.Interval(long(r[0]),
                                                                                   long(r[1]))
                                                             for r in res])

        return intervals
Ejemplo n.º 8
0
 def _relocated(regname, fullname):
     r = allregions[regname]
     ret = s
     rend = fullname.rsplit(".", 1)[1]
     cardinalres = re.match("([\d])+_relocated", rend)
     cardinal = cardinalres.group(1)
     relocindex = re.sub("[._relocated]+", "", rend)
     if r.addresses_resolved:
         start = min(r.addresses).begin
         end = max(r.addresses).end
         (offset, mod) = db_info.get(
             self.stage).reloc_offset_and_mod_from_cardinal(
                 relocindex)
         ret = intervaltree.Interval(long((start + offset) % mod),
                                     long((end + offset) % mod))
     return ret
Ejemplo n.º 9
0
 def allowed_writes(self, substage):
     n = substage
     query = "(substagenum == %d) & (writable == True)" % (n)
     drs = self.substage_region_policy_table.where(query)
     iis = intervaltree.IntervalTree()
     for region in drs:
         if region['allowed_symbol']:
             sname = region['symbol_elf_name']
             iis.add(self.lookup_symbol_interval(sname, n))
         else:
             query = 'short_name == "%s"' % region['short_name']
             for r in self.substage_mmap_addr_table.where(query):
                 iis.add(intervaltree.Interval(long(r['startaddr']),
                                               long(r['endaddr'])))
     iis.merge_overlaps()
     iis.merge_equals()
     return iis
Ejemplo n.º 10
0
 def resolve_addresses(self, all_regions={}, values={}):
     all_resolved = True
     if self.addresses_resolved is True:
         return
     elif self._csv:
         (f, parsed) = parse_am37x_register_tables.parsecsv(self._csv)
         addrs = intervaltree.IntervalTree()
         for p in parsed:
             addr = p[parse_am37x_register_tables.TITable.ADDRESS]
             if addr:
                 addr = long(addr, 0)
             else:
                 continue
             wid = p[parse_am37x_register_tables.TITable.WIDTH]
             name = p[parse_am37x_register_tables.TITable.NAME]
             # create a unique name without spaces
             name = re.sub("[\s]", "", name) + (".%x" % addr)
             size = long(wid) / 8 if wid else 4
             i = intervaltree.Interval(long(addr), long(addr + size))
             addrs.add(i)
             raw_perms = p[parse_am37x_register_tables.TITable.TYPE].lower()
             perms = "readonly" if 'w' not in raw_perms else 'global'
             self._raw_subregions[name] = {
                 'addresses': [i.begin, i.end],
                 'include_children': False,
                 'type': perms,
             }
             self.children_names.append("%s.%s" % (self.short_name, name))
         self.addresses = addrs
         f.close()
         all_resolved = True
     elif (type(self._raw_addresses) == list):
         if type(self._raw_addresses[0]
                 ) == list:  # its a list of lists of subregions
             for a in self._raw_addresses:
                 all_resolved = all_resolved and self._resolve_addr_region(
                     a, all_regions, values)
         else:
             all_resolved = self._resolve_addr_region(
                 self._raw_addresses, all_regions, values)
     else:
         all_resolved = self._resolve_special_addr_region(
             self._raw_addresses, all_regions, values)
     self.addresses_resolved = all_resolved
 def find_thumb_ranges(stage, noop=False):
     cc = Main.cc
     elf = stage.elf
     thumb = intervaltree.IntervalTree()
     arm = intervaltree.IntervalTree()
     data = intervaltree.IntervalTree()
     if noop:
         return (thumb, arm, data)
     cmd = "%snm -S -n --special-syms %s 2>/dev/null" % (cc, elf)
     output = subprocess.check_output(cmd, shell=True).split('\n')
     prev = None
     lo = 0
     dta = re.compile('\s+[a-zA-Z]\s+\$[tad]$')
     for o in output:
         o = o.strip()
         if dta.search(o):
             hi = long(o[:8], 16)
             if (prev is not None) and (not lo == hi):
                 i = intervaltree.Interval(lo, hi)
                 if prev == 't':
                     thumb.add(i)
                 elif prev == 'a':
                     arm.add(i)
                 elif prev == 'd':
                     data.add(i)
                 else:
                     raise Exception
             lo = hi
             prev = o[-1]
         else:
             continue
     res = (thumb, arm, data)
     for r in res:
         r.merge_overlaps()
         r.merge_equals()
     return res
    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()