def analyze_shufflevector(tokens):
    statement = Shufflevector()

    # pop potential assignment
    while tokens[0] != "shufflevector":
        tokens.pop(0)

    # pop the shufflevector token
    tokens.pop(0)

    # get the first vector type
    _, tokens = get_type(tokens)

    # get the first vector value
    value, tokens = get_value(tokens)
    statement.set_first_vector_value(value)

    # get the second vector type
    _, tokens = get_type(tokens)

    # get the second vector value
    value, tokens = get_value(tokens)
    statement.set_second_vector_value(value)

    # get the third vector type
    _, tokens = get_type(tokens)

    # get the third vector value
    value, tokens = get_value(tokens)
    statement.set_third_vector_value(value)

    return statement
Beispiel #2
0
def analyze_atomicrmw(tokens):
    statement = Atomicrmw()

    # pop potential assignment
    while tokens[0] != "atomicrmw":
        tokens.pop(0)

    # pop the atomicrmw token
    tokens.pop(0)

    # pop the potential volatile token
    if tokens[0] == "volatile":
        tokens.pop(0)

    # pop the operation
    operation = tokens.pop(0)
    statement.set_operation(operation)

    # pop the address
    _, tokens = get_type(tokens)
    address, tokens = get_value(tokens)
    statement.set_address(address)

    # pop the value
    _, tokens = get_type(tokens)
    value, tokens = get_value(tokens)
    statement.set_value(value)

    # we are not interested in ordering, we can therefore pop all remaining tokens
    while tokens:
        tokens.pop(0)

    return statement
def analyze_insertelement(tokens):
    statement = InsertElement()

    # pop the potential assignment
    while tokens[0] != "insertelement":
        tokens.pop(0)

    # pop the insertelement token
    tokens.pop(0)

    # get the vector type
    vector_type, tokens = get_type(tokens)
    statement.set_vector_type(vector_type)

    # pop the value token
    vector_value = get_value(tokens)
    statement.set_vector_value(vector_value)

    # skip the scalar element type
    _, tokens = get_type(tokens)

    # get the value element
    value, tokens = get_value(tokens)
    statement.set_scalar_value(value)

    # pop the type token
    _, tokens = get_type(tokens)

    # get the index
    statement.set_index(tokens.pop(0))

    return statement
Beispiel #4
0
def analyze_cmp(tokens):
    cmp = Cmp()

    # pop the potential assignment instruction
    while tokens[0] not in ["fcmp", "icmp"]:
        tokens.pop(0)

    # pop the fcmp instruction
    cmp.set_op_type(tokens.pop(0))

    # pop potential fast-math flags
    while is_fast_math_flag(tokens[0]):
        tokens.pop(0)

    # get the condition
    cmp.set_condition(tokens.pop(0))

    # pop the type
    _, tokens = get_type(tokens)

    # get the first value
    value1, tokens = get_value(tokens)
    cmp.set_value1(value1)

    value2, tokens = get_value(tokens)
    cmp.set_value2(value2)

    return cmp
Beispiel #5
0
def analyze_extractelement(tokens):
    statement = ExtractElement()

    # pop the potential assignment
    while tokens[0] != "extractelement":
        tokens.pop(0)

    # pop the extractelement token
    tokens.pop(0)

    # get the vector type
    vector_type, tokens = get_type(tokens)
    statement.set_vector_type(vector_type)

    # pop the value token
    vector_value, tokens = get_value(tokens)
    statement.set_vector_value(vector_value)

    # pop the type token
    _, tokens = get_type(tokens)

    # get the index
    index_value, tokens = get_value(tokens)
    statement.set_index(index_value)

    return statement
Beispiel #6
0
    def test_const_vector_op(self):
        result = get_value([
            "extractelement", "<2 x i32>", "<i32", "42,", "i32", "11>,", "i32",
            "0"
        ])
        self.assertEqual(result[0],
                         "extractelement <2 x i32> <i32 42, i32 11>, i32 0")

        result = get_value([
            "insertelement", "<2 x i32>", "<i32", "42,", "i32", "11>,", "i32",
            "1,", "i32", "0"
        ])
        self.assertEqual(
            result[0],
            "insertelement <2 x i32> <i32 42, i32 11>, i32 1, i32 0")

        result = get_value([
            "shufflevector", "<2", "x", "i32>", "<i32", "42,", "i32", "11>,",
            "<1", "x", "i32>", "<i32", "5>,", "<3", "x", "i32>", "<i32", "0,",
            "i32", "2,", "i32", "1>"
        ])
        self.assertEqual(
            result[0],
            "shufflevector <2 x i32> <i32 42, i32 11>, <1 x i32> <i32 5>, "
            "<3 x i32> <i32 0, i32 2, i32 1>")
Beispiel #7
0
 def test_global_var(self):
     self.assertEqual(get_value(["@A"])[0], "@A")
     self.assertEqual(get_value(["@str.1"])[0], "@str.1")
     self.assertEqual(get_value(["@_class_Profile"])[0], "@_class_Profile")
     self.assertEqual(
         get_value(["@_class_Profile,", "i32", "4)"])[0], "@_class_Profile")
     self.assertEqual(get_value(["@str.1)"])[0], "@str.1")
def analyze_insertvalue(tokens):
    insertvalue_instruction = Insertvalue()

    # pop the assignment segment
    while tokens[0] != "insertvalue":
        tokens.pop(0)

    # pop the insertvalue instruction
    tokens.pop(0)

    # get the object type
    object_type, tokens = get_type(tokens)
    insertvalue_instruction.set_object_type(object_type)

    # get the original object
    insertvalue_instruction.set_original(tokens[0].replace(",", ""))
    tokens.pop(0)

    # get the type and value that is to be inserted
    insert_type, tokens = get_type(tokens)
    insertvalue_instruction.set_insert_type(insert_type)

    value, tokens = get_value(tokens)
    insertvalue_instruction.set_insert_value(value)
    tokens.pop(0)

    while len(tokens) != 0:
        index, tokens = get_value(tokens)
        insertvalue_instruction.add_index(index)

    return insertvalue_instruction
def analyze_store(tokens):
    store = Store()

    # pop the store instruction
    tokens.pop(0)

    # check for atomic
    if tokens[0] == "atomic":
        tokens.pop(0)

    # check for volatile
    if tokens[0] == "volatile":
        tokens.pop(0)

    # skip type
    temp, tokens = get_type(tokens)
    store_value, tokens = get_value(tokens)
    store.set_value(store_value)
    # skip type
    _, tokens = get_type(tokens)

    # get the register
    register, tokens = get_value(tokens)
    store.set_register(register)

    return store
Beispiel #10
0
def analyze_bitwise_binary(tokens):
    statement = BitwiseBinaryStatement()

    # pop the potential assignment
    while tokens[0] not in ["shl", "lshr", "ashr", "and", "or", "xor"]:
        tokens.pop(0)

    # pop the bin instruction
    statement.set_statement_type(tokens.pop(0))

    # pop potential nuw token
    if tokens[0] == "nuw":
        tokens.pop(0)

    # pop potential nsw token
    if tokens[0] == "nsw":
        tokens.pop(0)

    # pop potential exact token
    if tokens[0] == "exact":
        tokens.pop(0)

    # pop the type
    _, tokens = get_type(tokens)

    # get the first operand
    op1, tokens = get_value(tokens)
    statement.set_op1(op1)

    # get the second operand
    op2, tokens = get_value(tokens)
    statement.set_op2(op2)

    return statement
Beispiel #11
0
    def test_const_aggregate_op(self):
        result = get_value([
            "extractvalue", "{i32,", "float}", "{i32", "4,", "float", "17.0},",
            "0"
        ])
        self.assertEqual(result[0],
                         "extractvalue {i32, float} {i32 4, float 17.0}, 0")

        result = get_value([
            "extractvalue", "({i32,", "float}", "{i32", "4,", "float",
            "17.0},", "0),", "i32", "8)"
        ])
        self.assertEqual(result[0],
                         "extractvalue {i32, float} {i32 4, float 17.0}, 0")
        self.assertEqual(result[1], ["i32", "8)"])

        result = get_value([
            "extractvalue", "({i32,", "float}", "{i32", "4,", "float",
            "17.0},", "0)(@\"foo\")"
        ])
        self.assertEqual(result[0],
                         "extractvalue {i32, float} {i32 4, float 17.0}, 0")
        self.assertEqual(result[1], ["(@\"foo\")"])

        result = get_value([
            "insertvalue", "{i32,", "float}", "{i32", "4,", "float", "17.0},",
            "i32", "4,", "0"
        ])
        self.assertEqual(
            result[0],
            "insertvalue {i32, float} {i32 4, float 17.0}, i32 4, 0")
def analyze_select(tokens):
    statement = Select()

    # pop the potential assignment
    while tokens[0] != "select":
        tokens.pop(0)

    # pop the select token
    tokens.pop(0)

    # pop the potential fast-math flags
    while is_fast_math_flag(tokens[0]):
        tokens.pop(0)

    # get the condition
    _, tokens = get_type(tokens)
    condition, tokens = get_value(tokens)
    statement.set_condition(condition)

    # get the if true option
    _, tokens = get_type(tokens)
    val1, tokens = get_value(tokens)
    statement.set_val1(val1)

    # get the if false option
    _, tokens = get_type(tokens)
    val2, tokens = get_value(tokens)
    statement.set_val2(val2)

    return statement
Beispiel #13
0
 def test_hex_numeric_constants(self):
     self.assertEqual(
         get_value(["0x432ff973cafa8000"])[0], "0x432ff973cafa8000")
     self.assertEqual(
         get_value(["0x432ff973cafa323,", "i1", "true"])[0],
         "0x432ff973cafa323")
     self.assertEqual(
         get_value(["0x432ff973cafa323)"])[0], "0x432ff973cafa323")
Beispiel #14
0
 def test_vector_constants(self):
     self.assertEqual(
         get_value(
             ["<i32", "42,", "i32", "11,", "i32", "74,", "i32", "100>"])[0],
         "<i32 42, i32 11, i32 74, i32 100>")
     self.assertEqual(
         get_value(["<i32", "42>,", "i32", "0)"])[0], "<i32 42>")
     self.assertEqual(get_value(["<i32", "42>)"])[0], "<i32 42>")
Beispiel #15
0
 def test_metadata(self):
     self.assertEqual(
         get_value(["!{!0,", "!{!2,", "!0},", "!\"test\"}"])[0],
         "!{!0, !{!2, !0}, !\"test\"}")
     self.assertEqual(
         get_value([
             "!{!0,", "i32", "0,", "i8*", "@global,", "i64", "(i64)*",
             "@function,", "!\"str\"}"
         ])[0], "!{!0, i32 0, i8* @global, i64 (i64)* @function, !\"str\"}")
Beispiel #16
0
    def test_const_other(self):
        result = get_value(["select", "i1", "true,", "i8", "17,", "i8", "42"])
        self.assertEqual(result[0], "select i1 true, i8 17, i8 42")

        result = get_value(["icmp", "eq", "(i32", "4,", "5),", "i32", "8)"])
        self.assertEqual(result[0], "icmp eq i32 4, 5")
        self.assertEqual(result[1], ["i32", "8)"])

        result = get_value(["fcmp", "oeq", "float", "4.0,", "5.0"])
        self.assertEqual(result[0], "fcmp oeq float 4.0, 5.0")
Beispiel #17
0
 def test_structure_constants(self):
     self.assertEqual(
         get_value(["{", "i32", "4,", "float", "17.0,", "i32*", "@G",
                    "}"])[0], "{ i32 4, float 17.0, i32* @G }")
     self.assertEqual(
         get_value(["{i32", "4,", "float", "17.0})"])[0],
         "{i32 4, float 17.0}")
     self.assertEqual(
         get_value(["{i32", "4,", "float", "17.0},", "i32", "5", ")"])[0],
         "{i32 4, float 17.0}")
Beispiel #18
0
def analyze_load(tokens):
    load = Load()

    # pop the assignment instruction
    while tokens[0] != "load":
        tokens.pop(0)

    # pop the load instruction
    tokens.pop(0)

    # check for atomic
    if tokens[0] == "atomic":
        tokens.pop(0)

    # check for volatile
    if tokens[0] == "volatile":
        tokens.pop(0)

    # skip type
    resulting_type, tokens = get_type(tokens)
    load.set_type(resulting_type)

    # check for ,
    if tokens[0] == ",":
        tokens.pop(0)

    # skip type
    _, tokens = get_type(tokens)

    # get the value
    value, tokens = get_value(tokens)
    load.set_value(value)

    return load
Beispiel #19
0
    def test_const_getelementptr(self):
        result = get_value([
            "getelementptr", "inbounds", "[5", "x", "i8*],", "[5", "x",
            "i8*]*", "@_ZTV9Rectangle,", "i32", "0,", "i32", "2"
        ])
        self.assertEqual(
            result[0],
            "getelementptr inbounds [5 x i8*], [5 x i8*]* @_ZTV9Rectangle, i32 0, i32 2"
        )

        result = get_value([
            "getelementptr", "inbounds", "([5", "x", "i8*],", "[5", "x",
            "i8*]*", "@_ZTV9Rectangle,", "i32", "0,", "i32", "2),", "i32", "5)"
        ])
        self.assertEqual(
            result[0],
            "getelementptr inbounds [5 x i8*], [5 x i8*]* @_ZTV9Rectangle, i32 0, i32 2"
        )
Beispiel #20
0
 def test_numeric_constants(self):
     self.assertEqual(get_value(["123"])[0], "123")
     self.assertEqual(get_value(["-4"])[0], "-4")
     self.assertEqual(get_value(["123.321"])[0], "123.321")
     self.assertEqual(get_value(["1.23321e+2"])[0], "1.23321e+2")
     self.assertEqual(
         get_value(["1.23321e+2,", "i1", "false"])[0], "1.23321e+2")
     self.assertEqual(get_value(["1.23321e+2)"])[0], "1.23321e+2")
Beispiel #21
0
def analyze_cmpxchg(tokens):
    statement = Cmpxchg()

    # pop a potential assignment instruction
    while tokens[0] != "cmpxchg":
        tokens.pop(0)

    # pop the cmpxchg token
    tokens.pop(0)

    # pop the weak token, if present
    if tokens[0] == "weak":
        tokens.pop(0)

    # pop the volatile token, if present
    if tokens[0] == "volatile":
        tokens.pop(0)

    # get the address value
    _, tokens = get_type(tokens)
    address, tokens = get_value(tokens)
    statement.set_address(address)

    # get the cmp value
    _, tokens = get_type(tokens)
    cmp, tokens = get_value(tokens)
    statement.set_cmp(cmp)

    # get the new value
    _, tokens = get_type(tokens)
    new, tokens = get_value(tokens)
    statement.set_new(new)

    # we are not interested in ordering instructions, and these can therefore be popped
    while tokens:
        tokens.pop(0)

    return statement
    def analyze_binary_op(self, tokens: list):
        op = BinOp()

        # pop the assignment
        while tokens[0] not in self.operations:
            tokens.pop(0)

        # pop the operation
        op.set_op(self.op_symbols[tokens.pop(0)])

        # pop potential nuw token
        if tokens[0] == "nuw":
            tokens.pop(0)

        # pop potential nsw token
        if tokens[0] == "nsw":
            tokens.pop(0)

        # pop potential exact token
        if tokens[0] == "exact":
            tokens.pop(0)

        # pop potential fastmath flags
        while is_fast_math_flag(tokens[0]):
            tokens.pop(0)

        # get the type
        _, tokens = get_type(tokens)

        # get the first op
        value1, tokens = get_value(tokens)
        op.set_value1(value1)

        # get the second op
        value2, tokens = get_value(tokens)
        op.set_value2(value2)

        return op
Beispiel #23
0
def analyze_ret(tokens: list):
    ret = Ret()

    # pop the return command
    tokens.pop(0)

    # get the return type
    ret_type, tokens = get_type(tokens)

    # if any, get the return value
    if ret_type != "void":
        ret_value, tokens = get_value(tokens)
        ret.set_value(ret_value)

    return ret
Beispiel #24
0
def analyze_resume(tokens):
    resume = Resume()

    # pop the resume instruction
    tokens.pop(0)

    # get the ex type
    ex_type, tokens = get_type(tokens)
    resume.set_type(ex_type)

    # get the value
    value, tokens = get_value(tokens)
    resume.set_value(value)

    return resume
Beispiel #25
0
def analyze_freeze(tokens):
    statement = Freeze()

    # pop the potential assignment
    while tokens[0] != "freeze":
        tokens.pop(0)

    # pop the freeze token
    tokens.pop(0)

    # get the value
    _, tokens = get_type(tokens)
    value, tokens = get_value(tokens)
    statement.set_value(value)

    return statement
Beispiel #26
0
def analyze_fneg(tokens):
    fneg = Fneg()

    # pop potential assignment
    while tokens[0] != "fneg":
        tokens.pop(0)

    # pop the fneg command
    tokens.pop(0)

    # pop potential fast math flags
    while is_fast_math_flag(tokens[0]):
        tokens.pop(0)

    # skip the type
    _, tokens = get_type(tokens)

    # get the value
    value, tokens = get_value(tokens)
    fneg.set_value(value)

    return fneg
def analyze_extractvalue(tokens):
    extractvalue = Extractvalue()

    # skip initial assignment part
    while tokens[0] != "extractvalue":
        tokens.pop(0)

    # pop the extractvalue token
    tokens.pop(0)

    # pop the type
    _, tokens = get_type(tokens)

    # get the value
    value, tokens = get_type(tokens)
    extractvalue.set_value(value)

    # get the indices
    while len(tokens) != 0:
        index, tokens = get_value(tokens)
        extractvalue.add_index(index)

    return extractvalue
def analyze_getelementptr(tokens: list):
    op = Getelementptr()

    # skip potential assignment tokens
    while tokens[0] != "getelementptr":
        tokens.pop(0)

    # pop getelementptr
    tokens.pop(0)

    # pop a potential inbounds keyword
    if tokens[0] == "inbounds":
        tokens.pop(0)

    # pop the type
    _, tokens = get_type(tokens)

    # pop the second type
    _, tokens = get_type(tokens)

    # get the value
    value, tokens = get_value(tokens)
    op.set_value(value)

    # access potential further indices
    while len(tokens) != 0:
        if tokens[0] == "inrange":
            tokens.pop(0)

        # get the index type
        _, tokens = get_type(tokens)

        # get the index value
        op.add_index(tokens.pop(0).replace(",", ""))

    return op
Beispiel #29
0
def analyze_callbr(tokens: list):
    br = CallBr()

    # pop the potential assignment
    while tokens[0] != "callbr":
        tokens.pop(0)

    # pop the callbr command
    tokens.pop(0)

    # pop the calling convention
    if is_calling_convention(tokens[0]):
        tokens.pop(0)

    # pop the parameter attributes
    while is_parameter_attribute(tokens[0]):
        open_brackets = tokens[0].count("(") - tokens[0].count(")")
        tokens.pop(0)
        while open_brackets != 0:
            open_brackets += tokens[0].count("(") - tokens[0].count(")")
            tokens.pop(0)

    # pop the address space
    if is_address_space(tokens[0]):
        tokens.pop(0)

    # get the return type
    ret_type, tokens = get_type(tokens)
    br.set_return_type(ret_type)

    # skip potential redundant tokens
    while tokens[0].count("(") == 0 and "bitcast" not in tokens[0]:
        tokens.pop(0)

    # get the function name
    if "bitcast" in tokens[0]:
        conversion = analyze_conversion(tokens)
        br.set_function(conversion.get_value())
    else:
        temp = tokens[0].split("(", 1)
        br.set_function(temp[0])
        tokens[0] = temp[1]

    # read the argument list
    while tokens and \
            not is_group_attribute(tokens[0]) and \
            not is_function_attribute(tokens[0]) and \
            ("(" in tokens[0] or ")" not in tokens[0]):
        argument = Argument()

        # read argument type
        parameter_type, tokens = get_type(tokens)
        argument.set_parameter_type(parameter_type)

        # read potential parameter attributes
        while is_parameter_attribute(tokens[0]):
            open_brackets = tokens[0].count("(") - tokens[0].count(")")
            attribute = tokens.pop(0)
            while open_brackets != 0 or attribute == "align":
                open_brackets += tokens[0].count("(") - tokens[0].count(")")
                attribute += tokens.pop(0)
            argument.add_parameter_attribute(attribute)

        # read register
        value, tokens = get_value(tokens)
        argument.set_register(value)

        br.add_function_argument(argument)

    # pop potential function attributes
    while is_function_attribute(tokens[0]):
        tokens.pop(0)

    # pop operand bundles
    while tokens[0] != "to":
        tokens.pop(0)

    tokens.pop(0)
    tokens.pop(0)

    # pop the fallthrough label
    br.set_fallthrough_label(tokens.pop(0))

    while tokens:
        # pop the label token
        tokens.pop(0)

        # pop the label specification
        br.add_indirect_label(tokens.pop(0).replace("]", ""))

    return br
Beispiel #30
0
    def test_const_conversion(self):
        result = get_value(["trunc", "i32", "257", "to", "i8"])
        self.assertEqual(result[0], "trunc i32 257 to i8")

        result = get_value([
            "zext", "(<2", "x", "i16>", "<i16", "8,", "i16", "7>", "to", "<2",
            "x", "i32>)"
        ])
        self.assertEqual(result[0],
                         "zext <2 x i16> <i16 8, i16 7> to <2 x i32>")

        result = get_value(["sext", "(i8", "-1", "to", "i16),", "i32", "5)"])
        self.assertEqual(result[0], "sext i8 -1 to i16")
        self.assertEqual(result[1], ["i32", "5)"])

        result = get_value(["fptrunc", "double", "16777217.0", "to", "float"])
        self.assertEqual(result[0], "fptrunc double 16777217.0 to float")

        result = get_value(["fpext", "double", "%X", "to", "fp128"])
        self.assertEqual(result[0], "fpext double %X to fp128")

        result = get_value(["fptoui", "float", "1.04E+17", "to", "i8"])
        self.assertEqual(result[0], "fptoui float 1.04E+17 to i8")

        result = get_value(["fptosi", "float", "1.0E-247", "to", "i1"])
        self.assertEqual(result[0], "fptosi float 1.0E-247 to i1")

        result = get_value(["uitofp", "i8", "-1", "to", "double"])
        self.assertEqual(result[0], "uitofp i8 -1 to double")

        result = get_value(["sitofp", "i8", "-1", "to", "double"])
        self.assertEqual(result[0], "sitofp i8 -1 to double")

        result = get_value(
            ["ptrtoint", "<4", "x", "i32*>", "%P", "to", "<4", "x", "i64>"])
        self.assertEqual(result[0], "ptrtoint <4 x i32*> %P to <4 x i64>")

        result = get_value(
            ["inttoptr", "<4", "x", "i32>", "%G", "to", "<4", "x", "i8*>"])
        self.assertEqual(result[0], "inttoptr <4 x i32> %G to <4 x i8*>")

        result = get_value(
            ["bitcast", "(<2", "x", "i32*>", "%V", "to", "<2", "x", "i64*>)"])
        self.assertEqual(result[0], "bitcast <2 x i32*> %V to <2 x i64*>")

        result = get_value([
            "addrspacecast", "<4 x i32*>", "%z", "to", "<4", "x", "float",
            "addrspace(3)*>"
        ])
        self.assertEqual(
            result[0],
            "addrspacecast <4 x i32*> %z to <4 x float addrspace(3)*>")