Извлечение кода функции из файла исходного кода c с помощью Python - PullRequest
0 голосов
/ 09 марта 2019

Я ищу способ синтаксического анализа файла c-source в Python.

Я знаю, что есть библиотека типа pycparse, которая может анализировать c-файлы, но кажется, что это зависит от компилятора gcc.,

Я работаю над инструментом вроде readelf, который читает файл ELF, извлекает коды операций из функции.Мне нужно прочитать c-sourcefiles, чтобы получить соответствующий c-код функции из файла.

Так что, если мы думаем на разделенном экране, я хочу видеть ассемблер / коды операций слева, исоответствующий c-код справа.

Так, например, когда я открываю базовый калькулятор, написанный на c, у меня есть функция с именем «add» в моем двоичном файле.Я извлекаю коды операций / ассемблер и показываю его в левой части окна.Теперь мне нужна функция python, которая открывает все c-файлы в каталоге, чтобы найти соответствующий c-код функции.

У кого-нибудь есть идеи, как решить эту проблему?

Вотпример вывода материала, который у меня сейчас есть:

|==================================================================|
| Adress             | Function                       | Size       |
|====================|================================|============|
| 0x000000000000065a | sub                            | 31         |
|==================================================================|
| 55 48 89 e5 89 7d ec 89 75 e8 c7 45 fc 00 00 00 00 8b 45 ec 2b   |
| 45 e8 89 45 fc 8b 45 fc 5d c3                                    |
|==================================================================|
| int sub(int a, int b)                                            |
| {                                                                |
|   int c = 0;                                                     |
|   c = a - b;                                                     |
|   return c;                                                      |
| }                                                                |
|==================================================================|

Но мой код в настоящее время может работать только с pycparse и basic-c-файлами, потому что pycparse завершается ошибкой, если мне приходится искать в разных c-файлах дляфункция.Я думаю, что он использует компилятор для компиляции кода и просто действует как обертка arround gcc.

1 Ответ

0 голосов
/ 10 марта 2019

Я написал небольшую функцию для извлечения тела функции из c-источника, используя ctags и python my self сейчас.

Может быть, это кому-нибудь поможет ...

import subprocess
import glob


def get_line_number(filename, funcname):
    found = False
    cmd = "ctags -x --c-kinds=fp " + filename + " | grep " + funcname

    output = subprocess.getoutput(cmd)
    lines = output.splitlines()

    for line in lines:
        if line.startswith(funcname + " "):    
            found = True

            if output.strip() is not "":
                output = output.split(" ")
                lines = list(filter(None, output))
                line_num = lines[2]

                print("Function found in file " + filename + " on line: " + line_num)
                return int(line_num)

    if found == False:
        #print("Function not found")
        return 0


def process_file(filename, line_num):
    print("opening " + filename + " on line " + str(line_num))

    code = ""
    cnt_braket = 0
    found_start = False
    found_end = False

    with open(filename, "r") as f:
        for i, line in enumerate(f):
            if(i >= (line_num - 1)):
                code += line

                if line.count("{") > 0:
                    found_start = True
                    cnt_braket += line.count("{")

                if line.count("}") > 0:
                    cnt_braket -= line.count("}")

                if cnt_braket == 0 and found_start == True:
                    found_end = True
                    return code


folder = "/usr/src/bash-4.4.18"
funcname = "add_alias"

for filename in glob.iglob(folder + "/*.c", recursive=True):
    line_num = get_line_number(filename, funcname)

    if line_num > 0:
        process_file(filename, line_num)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...