Skip to content

Commit

Permalink
Dict for identifying the subbassembly object
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcere committed Jan 8, 2025
1 parent f277889 commit 3f01d7f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 34 deletions.
10 changes: 10 additions & 0 deletions src/parser/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ def __init__(self, nodeType: str):
self.objectCFG: Dict[str, CFGObject] = {}
self.subObjects: Optional[CFG] = None

# Stores an index for each object
self.objectCFG2idx: Dict[str, int] = {}

def add_object(self, name: str, cfg_object: CFGObject) -> None:
self.objectCFG[name] = cfg_object
self.objectCFG2idx[name] = len(self.objectCFG2idx)

def get_object(self, name:str) -> CFGObject:
return self.objectCFG[name]
Expand All @@ -39,6 +43,12 @@ def set_subobject(self, subobject: 'CFG'):
def get_subobject(self) -> 'CFG':
return self.subObjects

def get_object_idx(self, object_name: str) -> int:
return self.objectCFG2idx[object_name]

def get_objectCFG2idx(self) -> Dict[str, int]:
return self.objectCFG2idx

def get_as_json(self):
json_cfg = {}
json_cfg["nodeType"] = self.nodeType
Expand Down
23 changes: 11 additions & 12 deletions src/parser/cfg_instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,34 +276,33 @@ def translate_memoryguard(self) :
self.translate_builtin_args = new_builtin


def translate_datasize(self, subobjects_keys: List[str]) :
def translate_datasize(self, subobjects_keys: Dict[str, int]):
self.op = "push #[$]"

builtin_val = self.builtin_args[0]

try:
pos = subobjects_keys.index(builtin_val)
pos = subobjects_keys.get(builtin_val, None)
if pos is not None:
self.translate_builtin_args = ["{0:064X}".format(pos)]
except:
else:
print("[WARNING ERROR]: Identifier not found in subobjects keys")
self.translate_builtin_args = ["{0:064X}".format(0)]

# raise Exception("[ERROR]: Identifier not found in subobjects keys")


def translate_dataoffset(self, subobjects_keys: List[str]) :
def translate_dataoffset(self, subobjects_keys: Dict[str, int]):
self.op = "push [$]"

builtin_val = self.builtin_args[0]
try:
pos = subobjects_keys.index(builtin_val)

pos = subobjects_keys.get(builtin_val, None)
if pos is not None:
self.translate_builtin_args = ["{0:064X}".format(pos)]
except:
else:
print("[WARNING ERROR]: Identifier not found in subobjects keys")
self.translate_builtin_args = ["{0:064X}".format(0)]

# raise Exception("[ERROR]: Identifier not found in subobjects keys")


def translate_datacopy(self) :
self.op = "codecopy"
Expand All @@ -317,7 +316,7 @@ def translate_loadimmutable(self) :
self.op = "pushimmutable"
self.translate_builtin_args = self.builtin_args

def translate_built_in_function(self, subobjects_keys: List[str]):
def translate_built_in_function(self, subobjects_keys: Dict[str, int]):
self.builtin_op = self.op

if self.op == "linkersymbol":
Expand All @@ -337,7 +336,7 @@ def translate_built_in_function(self, subobjects_keys: List[str]):
else:
raise Exception("[ERROR]: Built-in function is not recognized")

def translate_opcode(self, subobjects_keys: List[str]):
def translate_opcode(self, subobjects_keys: Dict[str, int]):
if self.op in ["linkersymbol","memoryguard", "datasize", "dataoffset", "datacopy", "setimmutable", "loadimmutable"]:
self.translate_built_in_function(subobjects_keys)

Expand Down
38 changes: 19 additions & 19 deletions src/parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def process_block_entry(block_json: Dict[str, Any], phi_instr: Dict[str, Any]) -


def parse_block(object_name: str, block_json: Dict[str,Any], built_in_op: bool,
objects_keys: List[str]) -> Tuple[block_id_T, CFGBlock, Dict]:
objects_keys: Dict[str, int]) -> Tuple[block_id_T, CFGBlock, Dict]:
block_id = block_json.get("id", -1)
block_instructions = block_json.get("instructions", -1)
block_exit = block_json.get("exit", -1)
Expand Down Expand Up @@ -119,7 +119,7 @@ def update_comes_from(block_list: CFGBlockList, comes_from: Dict[str, List[str]]
block_list.get_block(block_id).add_comes_from(predecessor)


def parser_block_list(object_name: str, blocks: List[Dict[str, Any]], built_in_op : bool, objects_keys : List[str]):
def parser_block_list(object_name: str, blocks: List[Dict[str, Any]], built_in_op: bool, objects_keys: Dict[str, int]):
"""
Returns the list of blocks parsed and the ids that correspond to Exit blocks
"""
Expand All @@ -144,7 +144,7 @@ def parser_block_list(object_name: str, blocks: List[Dict[str, Any]], built_in_o
return block_list, exit_blocks


def parse_function(function_name: str, function_json: Dict[str,Any], built_in_op: bool, objects_keys: List[str]):
def parse_function(function_name: str, function_json: Dict[str,Any], built_in_op: bool, objects_keys: Dict[str, int]):

args = function_json.get("arguments", -1)
ret_vals = function_json.get("returns", -1)
Expand All @@ -159,7 +159,7 @@ def parse_function(function_name: str, function_json: Dict[str,Any], built_in_op
return cfg_function


def parse_object(object_name: str, json_object: Dict[str,Any], built_in_op: bool, objects_keys: List[str]) -> CFGObject:
def parse_object(object_name: str, json_object: Dict[str,Any], built_in_op: bool, objects_keys: Dict[str, int]) -> CFGObject:
blocks_list = json_object.get("blocks", None)

if blocks_list is None:
Expand All @@ -176,24 +176,33 @@ def parser_CFG_from_JSON(json_dict: Dict, built_in_op: bool):

cfg = CFG(nodeType)

# First, we parse the subObjects in order to generate the corresponding keys dict
subObjects = json_dict.get("subObjects", -1)

if subObjects == -1:
raise Exception("[ERROR]: JSON file does not contain key subObjects")

key_dict = dict()

if subObjects != {}:
sub_object = parser_CFG_from_JSON(subObjects, built_in_op)
cfg.set_subobject(sub_object)
key_dict = sub_object.get_objectCFG2idx()

# The contract key corresponds to the key that is neither type nor subobjects
# For yul blocks, it is "object"
object_keys = [key for key in json_dict if key not in ["type", "subObjects"]]

subobjects_keys = [key for key in json_dict.get("subObjects") if key not in ["type", "subObjects"]] if json_dict.get("subObjects",{}) != {} else []

obj_json_keys = object_keys+subobjects_keys

assert len(object_keys) >= 1, "[ERROR]: JSON file does not contain a valid key for the code"

for obj in object_keys:
json_object = json_dict.get(obj,False)
json_functions = json_object.get("functions", {})

cfg_object = parse_object(obj, json_object, built_in_op, subobjects_keys)
cfg_object = parse_object(obj, json_object, built_in_op, key_dict)

for f in json_functions:
obj_function = parse_function(f, json_functions[f], built_in_op, obj_json_keys)
obj_function = parse_function(f, json_functions[f], built_in_op, key_dict)
cfg_object.add_function(obj_function)

# Important: add the object already initialized with the functions, so that we can construct
Expand All @@ -205,15 +214,6 @@ def parser_CFG_from_JSON(json_dict: Dict, built_in_op: bool):
# obj_name = obj.get("name")
# cfg.add_object_name(obj_name)

subObjects = json_dict.get("subObjects", -1)

if subObjects == -1:
raise Exception("[ERROR]: JSON file does not contain key subObjects")

if subObjects != {}:
sub_object = parser_CFG_from_JSON(subObjects, built_in_op)
cfg.set_subobject(sub_object)

return cfg


Expand Down
6 changes: 3 additions & 3 deletions src/solution_generation/reconstruct_bytecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,9 @@ def recursive_init_asm_from_cfg(cfg: CFG, asm_dicts: Dict[str, List[ASM_bytecode

# Represents the structure of the multiple possible contracts {"0": ..., "1:..."}
multiple_object_json = {}
for i, obj_name in enumerate(objects_cfg):
obj = objects_cfg[obj_name]
for obj_name, obj in objects_cfg.items():
tags = tags_dict[obj_name]
asm_idx = cfg.get_object_idx(obj_name)

asm = traverse_cfg(obj, asm_dicts, tags)
current_object_json = {".code": asm}
Expand All @@ -343,7 +343,7 @@ def recursive_init_asm_from_cfg(cfg: CFG, asm_dicts: Dict[str, List[ASM_bytecode
# It has only one subobject at this point (the deployed code)
current_object_json[".data"] = {f"0": json_asm_subobjects}

multiple_object_json[f"{i}"] = current_object_json
multiple_object_json[f"{asm_idx}"] = current_object_json

return multiple_object_json

Expand Down

0 comments on commit 3f01d7f

Please sign in to comment.