mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
a13c3e5ac2
Some files had discordant executable bit presence and shebang presence. This commit fixes these occurrences by adding removing the required feautures where needed.
76 lines
2.7 KiB
Python
Executable File
76 lines
2.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# This file is distributed under the MIT License. See LICENSE.md for details.
|
|
#
|
|
# flake8: noqa: E800
|
|
|
|
import sys
|
|
|
|
from llvmcpy import llvm
|
|
|
|
|
|
def main():
|
|
context = llvm.get_global_context()
|
|
|
|
# Load and parse the input file
|
|
buffer = llvm.create_memory_buffer_with_contents_of_file(sys.argv[1])
|
|
module = context.parse_ir(buffer)
|
|
|
|
# Identify the CSV (global variable) for the register containing the syscall
|
|
# number (r7 for ARM)
|
|
r7 = module.get_named_global("r7")
|
|
|
|
# Prepare requirements to build our call to dprintf
|
|
|
|
# 1) Identify the dprintf function (prototype)
|
|
dprintf = module.get_named_function("dprintf")
|
|
|
|
# 2) Create an integer constant for stderr
|
|
two = context.int32_type().const_int(2, True)
|
|
|
|
# 3) Create the message to print
|
|
message_str = context.const_string("%d\n", 4, True)
|
|
message = module.add_global(message_str.type_of(), "message")
|
|
message.set_initializer(message_str)
|
|
message_ptr = message.const_bit_cast(context.int8_type().pointer(0))
|
|
|
|
# Identify the function generated by revng (root)
|
|
root_function = module.get_named_function("root")
|
|
|
|
# Loop over all the generated instructions and add instrumentation code
|
|
builder = context.create_builder()
|
|
for basic_block in root_function.iter_basic_blocks():
|
|
for instruction in basic_block.iter_instructions():
|
|
# Check if the current instruction is a call
|
|
if instruction.instruction_opcode == llvm.Call:
|
|
# The callee is the last operand
|
|
last_operand_index = instruction.get_num_operands() - 1
|
|
callee = instruction.get_operand(last_operand_index)
|
|
|
|
# If there's a bitcast, skip it
|
|
if not callee.name:
|
|
assert callee.get_num_operands() == 1
|
|
callee = callee.get_operand(0)
|
|
|
|
# Check if it's performing a syscall
|
|
if callee.name.startswith("helper_exception_with_syndrome_"):
|
|
# Set the builder's insert point before the call instruction
|
|
builder.position_builder_before(instruction)
|
|
|
|
# Load the value of r7 (which contains the syscall number)
|
|
load_r7 = builder.build_load(r7, "")
|
|
|
|
# Create the list of arguments for dprintf
|
|
arguments = [two, message_ptr, load_r7]
|
|
|
|
# Create the function call to dprintf:
|
|
# dprintf(2, "%d\n", r7)
|
|
builder.build_call(dprintf, arguments, "")
|
|
|
|
# Produce the instrumented LLVM IR to file
|
|
module.print_module_to_file(sys.argv[2])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|