James E. Smith

133 papers A* 51A 13B 6C 3Misc 3Journal 40Unranked 16
YearRankTypeTitle / Venue / Authors
2021 conf
ISVLSI
Harideep Nair, John Paul Shen, James E. Smith
2021 J jnl
CoRR
Harideep Nair, John Paul Shen, James E. Smith
2021 A* conf
ISCA
Georgios Tzimpragos, Jennifer Volk, Alex Wynn, James E. Smith, Timothy Sherwood
2020 J jnl
CoRR
Harideep Nair, John Paul Shen, James E. Smith
2018 A* conf
ISCA
James E. Smith
2017 J jnl
IEEE Micro
James E. Smith
2017 book
James E. Smith
2014 A* conf
ISCA
James E. Smith
2013 A conf
ICS
James E. Smith
2010 Misc conf
PDPTA
James E. Smith, Jonathan Apodaca, Anthony A. Maciejewski, Howard Jay Siegel
2009 Misc conf
IKE
Paul Maxwell, Anthony A. Maciejewski, Howard Jay Siegel, Jerry Potter, James E. Smith
2009 J jnl
ACM Trans. Comput. Syst.
Stijn Eyerman, Lieven Eeckhout, Tejas Karkhanis, James E. Smith
2008 A* conf
MICRO
Nidhi Aggarwal, James E. Smith, Kewal K. Saluja, Norman P. Jouppi, Parthasarathy Ranganathan
2008 J jnl
IEEE Micro
Kyle J. Nesbit, Miquel Moretó, Francisco J. Cazorla, Alex Ramírez, Mateo Valero, James E. Smith
2008 A* conf
HPCA
Nidhi Aggarwal, Jason F. Cantin, Mikko H. Lipasti, James E. Smith
2008 conf
HiPEAC
Stijn Eyerman, Lieven Eeckhout, James E. Smith
2007 J jnl
IEEE Micro
Stijn Eyerman, Lieven Eeckhout, Tejas Karkhanis, James E. Smith
2007 A* conf
ISCA
Tejas Karkhanis, James E. Smith
2007 A* conf
ISCA
Nidhi Aggarwal, Parthasarathy Ranganathan, Norman P. Jouppi, James E. Smith
2007 conf
Asia-Pacific Computer Systems Architecture Conference
Marco Galluzzi, Enrique Vallejo, Adrián Cristal, Fernando Vallejo, Ramón Beivide, Per Stenström, James E. Smith, Mateo Valero
2007 J jnl
Computer
Nidhi Aggarwal, Parthasarathy Ranganathan, Norman P. Jouppi, James E. Smith
2007 B conf
PACT
Stijn Eyerman, Lieven Eeckhout, James E. Smith
2007 A* conf
ISCA
Kyle J. Nesbit, James Laudon, James E. Smith
2006 A* conf
ASPLOS
Stijn Eyerman, Lieven Eeckhout, Tejas Karkhanis, James E. Smith
2006 A* conf
HPCA
Shiliang Hu, Ilhyun Kim, Mikko H. Lipasti, James E. Smith
2006 B conf
ISPASS
Stijn Eyerman, James E. Smith, Lieven Eeckhout
2006 J jnl
IEEE Micro
Jason F. Cantin, James E. Smith, Mikko H. Lipasti, Andreas Moshovos, Babak Falsafi
2006 A* conf
MICRO
Kyle J. Nesbit, Nidhi Aggarwal, James Laudon, James E. Smith
2006 A* conf
ISCA
Shiliang Hu, James E. Smith
2006 A* conf
ASPLOS
Jason F. Cantin, Mikko H. Lipasti, James E. Smith
2006 J jnl
Computer
Joshua J. Yi, Lieven Eeckhout, David J. Lilja, Brad Calder, Lizy Kurian John, James E. Smith
2006 J jnl
Int. J. Embed. Syst.
Ashutosh S. Dhodapkar, James E. Smith
2005 B conf
VEE
James E. Smith
2005 J jnl
IEEE Micro
Kyle J. Nesbit, James E. Smith
2005 conf
ICPS
Enrique Vallejo, Marco Galluzzi, Adrián Cristal, Fernando Vallejo, Ramón Beivide, Per Stenström, James E. Smith, Mateo Valero
2005 A* conf
ISCA
Jason F. Cantin, Mikko H. Lipasti, James E. Smith
2005 A conf
OOPSLA
Ajeet Shankar, S. Subramanya Sastry, Rastislav Bodík, James E. Smith
2005 J jnl
IEEE Trans. Parallel Distributed Syst.
Jason F. Cantin, Mikko H. Lipasti, James E. Smith
2005 conf
Euro-Par
Ramon Canal, Antonio González, James E. Smith
2004 A* conf
ISCA
Tejas Karkhanis, James E. Smith
2004 conf
IEEE PACT
Kyle J. Nesbit, Ashutosh S. Dhodapkar, James E. Smith
2004 A* conf
HPCA
Kyle J. Nesbit, James E. Smith
2004 A conf
CGO
Ramon Canal, Antonio González, James E. Smith
2004 conf
Asia-Pacific Computer Systems Architecture Conference
James E. Smith
2004 B conf
ISPASS
Brad Calder, Daniel Citron, Yale N. Patt, James E. Smith
2004 A conf
IPDPS
Ashutosh S. Dhodapkar, James E. Smith
2004 A conf
CGO
Shiliang Hu, James E. Smith
2003 A* conf
MICRO
Ashutosh S. Dhodapkar, James E. Smith
2003 A conf
CGO
Ho-Seop Kim, James E. Smith
2003 A* conf
MICRO
Ho-Seop Kim, James E. Smith
2003 A conf
ICS
James E. Smith
2003 J jnl
IEEE Micro
Lieven Eeckhout, Sébastien Nussbaum, James E. Smith, Koen De Bosschere
2003 B conf
SPAA
Jason F. Cantin, Mikko H. Lipasti, James E. Smith
2002 A* conf
ISCA
Ho-Seop Kim, James E. Smith
2002 A conf
ICS
Juan L. Aragón, José González, Antonio González, James E. Smith
2002 conf
PACS
Pradip Bose, David M. Brooks, Alper Buyuktosunoglu, Peter W. Cook, K. Das, Philip G. Emma, Michael Gschwind, Hans M. Jacobson, Tejas Karkhanis, Prabhakar Kudva, Stanley Schuster, James E. Smith, Viji Srinivasan, Victor V. Zyuban, David H. Albonesi, Sandhya Dwarkadas
2002 J jnl
J. Circuits Syst. Comput.
George Cai, Ashutosh S. Dhodapkar, James E. Smith
2002 A* conf
ISCA
Ashutosh S. Dhodapkar, James E. Smith
2002 A conf
ISLPED
Tejas Karkhanis, James E. Smith, Pradip Bose
2002 conf
Annual Simulation Symposium
Sébastien Nussbaum, James E. Smith
2001 J jnl
Computer
James E. Smith
2001 conf
IEEE PACT
Sébastien Nussbaum, James E. Smith
2001 A* conf
ISCA
S. Subramanya Sastry, Rastislav Bodík, James E. Smith
2001 J jnl
IEEE Trans. Parallel Distributed Syst.
T. N. Vijaykumar, Sridhar Gopal, James E. Smith, Gurindar S. Sohi
2000 C conf
ISMM
Timothy H. Heil, James E. Smith
2000 J jnl
J. Instr. Level Parallelism
Eric Rotenberg, James E. Smith
2000 Misc conf
HiPC
James E. Smith
2000 conf
ISHPC
James E. Smith
2000 A* conf
MICRO
Timothy H. Heil, James E. Smith
2000 A* conf
ISCA
Quinn Jacobson, James E. Smith
2000 A* conf
ISCA
James E. Smith, Greg Faanes, Rabin A. Sugumar
2000 A* conf
MICRO
Ramon Canal, Antonio González, James E. Smith
1999 A* conf
HPCA
Eric Rotenberg, Quinn Jacobson, James E. Smith
1999 J jnl
IEEE Trans. Computers
Eric Rotenberg, Steve Bennett, James E. Smith
1999 A* conf
MICRO
Eric Rotenberg, James E. Smith
1999 A* conf
MICRO
Timothy H. Heil, Zak Smith, James E. Smith
1999 A* conf
HPCA
Quinn Jacobson, James E. Smith
1999 J jnl
Int. J. Parallel Program.
Yiannakis Sazeides, James E. Smith
1998 conf
25 Years ISCA: Retrospectives and Reprints
James E. Smith
1998 A* conf
PLDI
S. Subramanya Sastry, Subbarao Palacharla, James E. Smith
1998 conf
25 Years ISCA: Retrospectives and Reprints
James E. Smith, Andrew R. Pleszkun
1998 A* conf
ISCA
Yiannakis Sazeides, James E. Smith
1998 conf
25 Years ISCA: Retrospectives and Reprints
James E. Smith
1998 conf
25 Years ISCA: Retrospectives and Reprints
James E. Smith
1998 conf
25 Years ISCA: Retrospectives and Reprints
James E. Smith
1998 A* conf
HPCA
Sridhar Gopal, T. N. Vijaykumar, James E. Smith, Gurindar S. Sohi
1998 A conf
International Conference on Supercomputing
Roger Espasa, Mateo Valero, James E. Smith
1997 A* conf
ISCA
Subbarao Palacharla, Norman P. Jouppi, James E. Smith
1997 A* conf
HPCA
Quinn Jacobson, Steve Bennett, Nikhil Sharma, James E. Smith
1997 A* conf
MICRO
Roger Espasa, Mateo Valero, James E. Smith
1997 A* conf
MICRO
Quinn Jacobson, Eric Rotenberg, James E. Smith
1997 A* conf
MICRO
Yiannakis Sazeides, James E. Smith
1997 A* conf
MICRO
Eric Rotenberg, Quinn Jacobson, Yiannakis Sazeides, James E. Smith
1996 A* conf
MICRO
Erik Jacobsen, Eric Rotenberg, James E. Smith
1996 A* conf
MICRO
Yiannakis Sazeides, Stamatis Vassiliadis, James E. Smith
1996 A* conf
MICRO
Eric Rotenberg, Steve Bennett, James E. Smith
1995 A* conf
MICRO
Subbarao Palacharla, James E. Smith
1995 J jnl
Proc. IEEE
James E. Smith, Gurindar S. Sohi
1994 A conf
SC
Leonidas I. Kontothanassis, Rabin A. Sugumar, Greg Faanes, James E. Smith, Michael L. Scott
1994 J jnl
Computer
James E. Smith, Shlomo Weiss
1992 A conf
SC
Corinna G. Lee, James E. Smith
1992 J jnl
J. Parallel Distributed Comput.
Howard Jay Siegel, Seth Abraham, William L. Bain, Kenneth E. Batcher, Thomas L. Casavant, Doug DeGroot, Jack B. Dennis, David C. Douglas, Tse-Yun Feng, James R. Goodman, Alan Huang, Harry F. Jordan, J. Robert Jamp, Yale N. Patt, Alan Jay Smith, James E. Smith, Lawrence Snyder, Harold S. Stone, Russ Tuck, Benjamin W. Wah
1990 J jnl
ACM Trans. Math. Softw.
Shlomo Weiss, James E. Smith
1989 C conf
IEEE Symposium on Computer Arithmetic
D. L. Fowler, James E. Smith
1989 J jnl
Computer
James E. Smith
1989 A conf
ICS
Gurindar S. Sohi, James E. Smith, James R. Goodman
1988 J jnl
Commun. ACM
James E. Smith
1988 C conf
ICCD
James E. Smith, Gregory E. Dermer, B. D. Vanderwarn, S. D. Klinger, C. M. Rozewski, D. L. Fowler, K. R. Scidmore, James Laudon
1987 A* conf
ASPLOS
Shlomo Weiss, James E. Smith
1987 A* conf
ASPLOS
James E. Smith, Gregory E. Dermer, B. D. Vanderwarn, S. D. Klinger, C. M. Rozewski, D. L. Fowler, K. R. Scidmore, James Laudon
1986 J jnl
IEEE Trans. Computers
James E. Smith, Shlomo Weiss, Nicholas Y. Pang
1986 A* conf
ISCA
Steven R. Kunkel, James E. Smith
1986 B conf
ICPP
Steven R. Kunkel, James E. Smith
1985 A* conf
ISCA
James E. Smith, Andrew R. Pleszkun
1985 J jnl
IEEE Trans. Computers
James E. Smith, James R. Goodman
1985 J jnl
IEEE Trans. Computers
Craig S. Holt, James E. Smith
1984 J jnl
ACM Trans. Comput. Syst.
James E. Smith
1984 A* conf
ISCA
Shlomo Weiss, James E. Smith
1984 J jnl
IEEE Trans. Computers
Shlomo Weiss, James E. Smith
1984 J jnl
IEEE Trans. Computers
James E. Smith
1983 A* conf
ISCA
James E. Smith, James R. Goodman
1983 J jnl
IEEE Trans. Computers
James E. Smith, Paklin Lam
1982 A* conf
ISCA
James E. Smith
1982 A* conf
DAC
Lionel Bening, Thomas A. Lane, Curtis R. Alexander, James E. Smith
1981 A* conf
ISCA
James E. Smith
1981 J jnl
IEEE Trans. Computers
Craig S. Holt, James E. Smith
1980 J jnl
IEEE Trans. Computers
James E. Smith
1979 J jnl
IEEE Trans. Computers
James E. Smith
1979 J jnl
IEEE Trans. Computers
James E. Smith
1979 J jnl
IEEE Trans. Computers
James E. Smith
1979 J jnl
IEEE Trans. Computers
James E. Smith
1978 J jnl
IEEE Trans. Computers
James E. Smith
1978 J jnl
IEEE Trans. Computers
James E. Smith, Gernot Metze
redb/extractors/decompiler/bninja/analysis/cfg-old.py
← Index redb/extractors/decompiler/bninja/analysis/cfg-old.py python
from collections import deque
from enum import Enum

from binaryninja.enums import (
    BranchType,
    InstructionTextTokenType,
)

# Support both package and standalone imports
try:
    from ..utils.hashes import calculate_md5, calculate_sha256
except ImportError:
    # Fallback to absolute imports (for multiprocessing spawned processes)
    from redb.extractors.decompiler.bninja.utils.hashes import calculate_md5, calculate_sha256


class CFGAnalysis:
    def __init__(self, function):
        self.function = function

    def determine_block_type(self, block) -> str:
        """Determine the type of a basic block."""
        # Check if it's a thunk function (usually just a jump or call)
        if len(block.disassembly_text) <= 2 and any(
            "jmp" in line.tokens[0].text.lower() for line in block.disassembly_text
        ):
            return "THUNK"

        # Check if it contains only data (no valid instructions)
        if all(not line.tokens for line in block.disassembly_text):
            return "DATA"

        # Default to code
        return "CODE"

    def extract_cyclomatic_complexity(self):
        """
        Cyclomatic complexity (McCabe’s metric) measures the number of linearly independent paths
        through a function’s control flow graph (CFG).
        The standard formula is:

            M = E - N + 2

        where:
            - E = number of edges in the CFG
            - N = number of nodes (basic blocks)
            - 2 accounts for the entry and exit nodes of a single connected graph
        """
        if self.function is None:
            return 0

        # number of basic blocks
        num_blocks = len(self.function.basic_blocks)
        # number of edges in the graph
        num_edges = sum(
            len(basic_block.outgoing_edges)
            for basic_block in self.function.basic_blocks
        )
        return num_edges - num_blocks + 2

    def extract_function_cfg(self):
        """Extract information about a function CFG and return it as a dictionary."""

        function = self.function
        function_data = {
            "function_address": self.function.start,
            "blocks": [],
            "measures": {
                "cyclomatic_complexity": self.extract_cyclomatic_complexity(),
            },
        }

        if self.function is None:
            return function_data

        # Get the map of the depth associated to every block
        depths = self.get_map_depth()

        # Get the map of the positions associated to every block
        id_maps = self.get_block_id_map()

        # Extract block data with graph structure information
        for block in function.basic_blocks:
            # dominators per every block translated
            dominators = sorted(self.extract_dominators(block, id_maps))

            # post dominators
            post_dominators = sorted(self.extract_post_dominators(block, id_maps))

            # Build block instructions string
            block_instructions = "\n".join(str(line) for line in block.disassembly_text)

            # Determine block type
            block_type = self.determine_block_type(block)

            # Extract successors directly from basic block
            successor_blocks = [edge.target.start for edge in block.outgoing_edges]
            # We ensure a canonical order and we sort the edges
            successor_blocks.sort()

            # Extract predecessors directly from basic block
            predecessor_blocks = [edge.source.start for edge in block.incoming_edges]
            # We ensure a canonical order and we sort the edges
            predecessor_blocks.sort()

            # Determine branch type from outgoing edges
            branch_type = self.determine_branch_type(block)

            instructions_count = len(block.disassembly_text)

            # Create block record
            block_json = {
                "function_address": self.function.start,
                "block_start_address": block.start,
                "block_end_address": block.end,
                "block_size": block.end - block.start,
                "instructions_count": instructions_count,
                "block_instructions_hash": calculate_sha256(block_instructions),
                "predecessor_blocks": predecessor_blocks,
                "successor_blocks": successor_blocks,
                "depth": depths[block.start],
                "position": id_maps[block.start],
                "branch_type": branch_type,
                "block_type": block_type,
                "flags": self.extract_block_flags(block),
                "dominators": dominators,
                "post_dominators": post_dominators,
            }
            function_data["blocks"].append(block_json)

        return function_data

    def extract_dominators(self, bb, id_maps):
        """Extract the dominators normalized"""
        dom_idx = [id_maps[d.start] for d in bb.dominators]
        return dom_idx

    def extract_post_dominators(self, bb, id_maps):
        """Extract the post-dominators normalized"""
        post_dom_idx = [id_maps[d.start] for d in bb.post_dominators]
        return post_dom_idx

    def determine_branch_type(self, block):
        """
        Determine the type of branch at the end of a basic block.
        This combines edge type information with instruction analysis.
        """
        # If no outgoing edges, it might be a return or terminal block
        if not block.outgoing_edges:
            # Check if the last instruction is a return
            for line in reversed(list(block.disassembly_text)):
                if line.tokens and any(
                    token.text.lower() in ["ret", "retn"] for token in line.tokens
                ):
                    return "RETURN"
            return "UNKNOWN"

        # Collect branch types from all outgoing edges
        branch_types = []
        for edge in block.outgoing_edges:
            edge_type = edge.type
            # Map edge type to our branch type enum
            if isinstance(edge_type, str):
                if edge_type == "IndirectCall":
                    branch_types.append("CALL")
                else:
                    branch_types.append("UNKNOWN")
            else:
                # Use our mapping for integer/enum values
                type_mapping = {
                    BranchType.UnconditionalBranch: "DIRECT",
                    BranchType.FalseBranch: "CONDITIONAL",
                    BranchType.TrueBranch: "CONDITIONAL",
                    BranchType.CallDestination: "CALL",
                    BranchType.FunctionReturn: "RETURN",
                    BranchType.SystemCall: "CALL",
                    BranchType.IndirectBranch: "INDIRECT",
                    BranchType.ExceptionBranch: "UNKNOWN",
                    BranchType.UnresolvedBranch: "UNKNOWN",
                    BranchType.UserDefinedBranch: "UNKNOWN",
                }
                branch_types.append(type_mapping.get(edge_type, "UNKNOWN"))

        # Determine overall branch type (prioritize CALL > RETURN > CONDITIONAL > DIRECT)
        if "CALL" in branch_types:
            return "CALL"
        elif "RETURN" in branch_types:
            return "RETURN"
        elif "CONDITIONAL" in branch_types:
            return "CONDITIONAL"
        elif "DIRECT" in branch_types:
            return "DIRECT"
        elif len(block.outgoing_edges) == 1:
            return "FALLTHROUGH"

        # If edge analysis was inconclusive, fall back to instruction analysis
        last_instr = None
        for line in reversed(list(block.disassembly_text)):
            if line.tokens:
                last_instr = line
                break

        if last_instr:
            mnemonic = None
            for token in last_instr.tokens:
                if token.type == InstructionTextTokenType.InstructionToken:
                    mnemonic = token.text.lower()
                    break

            if mnemonic:
                if mnemonic == "call":
                    return "CALL"
                elif mnemonic == "jmp":
                    return "DIRECT"
                elif mnemonic.startswith("j") and mnemonic != "jmp":
                    return "CONDITIONAL"
                elif mnemonic in ["ret", "retn"]:
                    return "RETURN"

        return "UNKNOWN"

    def get_map_depth(self):
        """
        Run a BFS on the basic blocks of the function to assign a depth to every block
        """

        depths = {}
        entry = self.function.get_basic_block_at(self.function.start)

        ### Simple BFS
        q = deque()
        q.append(entry)
        depths[entry.start] = 0

        while q:
            b = q.popleft()
            b_depth = depths[b.start]
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in depths:
                    depths[tgt.start] = b_depth + 1
                    q.append(tgt)

        return depths

    def get_block_id_map(self):
        """
        Assign a unique, sequential ID to each basic block of the function using a BFS starting from the entry block.
        """

        id_map = {}
        entry = self.function.get_basic_block_at(self.function.start)

        q = deque()
        q.append(entry)

        current_id = 0
        id_map[entry.start] = current_id

        while q:
            b = q.popleft()
            for edge in b.outgoing_edges:
                tgt = edge.target

                if tgt is None:
                    continue

                if tgt.start not in id_map:
                    current_id += 1
                    id_map[tgt.start] = current_id
                    q.append(tgt)

        return id_map

    def extract_block_flags(self, block):
        """
        Get the flags for every basic block. Currently, we implemented these heuristics:
            - if a basic block is the entry node for a function
            - if a basic block is the exit block for a function
            - if a basic block is part of a natural loop
        """
        flags = []

        if block.start == self.function.start:
            flags.append(BlockFlags.EntryBlock.value)

        if any(edge.type == BranchType.FunctionReturn for edge in block.outgoing_edges):
            flags.append(BlockFlags.ExitBlock.value)

        # if this block is in its dominance frontier, then it's part of a natural loop
        if block in block.dominance_frontier:
            flags.append(BlockFlags.LoopBlock.value)

        return flags


class BlockFlags(Enum):
    # generally, the basic block identifying the entry point of the function
    EntryBlock = "EntryBlock"
    # any basic blocks that makes the control flow exiting from the current function
    ExitBlock = "ExitBlock"
    # any block is in a natural loop if it is in its own dominance frontier
    LoopBlock = "LoopBlock"


class BlockType(Enum):
    THUNK = "THUNK"
    DATA = "DATA"
    PADDING = "PADDING"
    CODE = "CODE"