ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
22 февраля
1500472 Топик полностью
SciFi (Вчера, 22:44, просмотров: 80) ответил Rainman62 на Хочется странного.. А именно, доступа из рантайма к именам полей структур. Ну, например, что бы вывести в консоль значения полей структуры вместе с именами. Если программа скомпилирована с отладочной информацией то , слышал что это, типа, возможно, с использованием библиотеки libdwarf. Не богат ли кто минимальным примером? Вообще хотелось бы из МК с линуксом, но рад был бы и примеру для PC/Linux ..
DeepSeek: 

Для получения доступа к именам полей структур в программе на языке C с использованием библиотеки libdwarf, вам нужно будет работать с отладочной информацией, которая обычно содержится в файлах DWARF. DWARF — это формат отладочной информации, который используется компиляторами для хранения данных о типах, переменных, функциях и структурах программы.

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

  1. Инициализация libdwarf: Сначала вам нужно инициализировать libdwarf для работы с отладочной информацией в вашем бинарном файле.

  2. Поиск структуры: Найдите информацию о структуре, которую вы хотите исследовать. Это можно сделать, просматривая отладочную информацию и ища записи, соответствующие структурам (например, DW_TAG_structure_type).

  3. Получение информации о полях: Для найденной структуры получите информацию о её полях. Поля структуры будут представлены как дочерние элементы структуры (например, DW_TAG_member).

  4. Извлечение имен полей: Для каждого поля извлеките его имя, используя соответствующие атрибуты DWARF (например, DW_AT_name).

Вот пример кода на C, который демонстрирует этот процесс:

#include <dwarf.h>
#include <libdwarf.h>
#include <stdio.h>
#include <stdlib.h>

void handle_structure(Dwarf_Die die) {
    Dwarf_Error error;
    Dwarf_Die child_die;
    Dwarf_Attribute attr;
    char *name;

    // Получаем первое дочернее DIE структуры
    if (dwarf_child(die, &child_die, &error) == DW_DLV_OK) {
        do {
            // Проверяем, является ли дочерний элемент полем структуры
            Dwarf_Half tag;
            dwarf_tag(child_die, &tag, &error);
            if (tag == DW_TAG_member) {
                // Получаем имя поля
                if (dwarf_attr(child_die, DW_AT_name, &attr, &error) == DW_DLV_OK) {
                    if (dwarf_formstring(attr, &name, &error) == DW_DLV_OK) {
                        printf("Field name: %s\n", name);
                    }
                    dwarf_dealloc_attribute(attr);
                }
            }
        } while (dwarf_siblingof(child_die, &child_die, &error) == DW_DLV_OK);
    }
}

void process_die(Dwarf_Debug dbg, Dwarf_Die die) {
    Dwarf_Error error;
    Dwarf_Half tag;

    dwarf_tag(die, &tag, &error);
    if (tag == DW_TAG_structure_type) {
        handle_structure(die);
    }

    Dwarf_Die child_die;
    if (dwarf_child(die, &child_die, &error) == DW_DLV_OK) {
        do {
            process_die(dbg, child_die);
        } while (dwarf_siblingof(child_die, &child_die, &error) == DW_DLV_OK);
    }
}

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <binary>\n", argv[0]);
        return 1;
    }

    Dwarf_Debug dbg;
    Dwarf_Error error;
    int fd = open(argv[1], O_RDONLY);
    if (dwarf_init(fd, DW_DLC_READ, 0, 0, &dbg, &error) != DW_DLV_OK) {
        fprintf(stderr, "Failed to initialize libdwarf\n");
        return 1;
    }

    Dwarf_Die cu_die;
    while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &error) == DW_DLV_OK) {
        if (dwarf_siblingof(dbg, NULL, &cu_die, &error) == DW_DLV_OK) {
            process_die(dbg, cu_die);
        }
    }

    dwarf_finish(dbg, &error);
    close(fd);
    return 0;
}
  • dwarf_init: Инициализирует libdwarf для работы с указанным бинарным файлом.
  • dwarf_next_cu_header: Переходит к следующей единице компиляции (Compilation Unit, CU) в файле.
  • dwarf_siblingof и dwarf_child: Используются для обхода дерева отладочной информации.
  • dwarf_tag: Определяет тип текущего DIE (Debugging Information Entry).
  • dwarf_attr и dwarf_formstring: Используются для извлечения атрибутов DIE, таких как имя поля.
  • Этот код является примером и может потребовать доработки в зависимости от ваших конкретных требований и структуры отладочной информации.
  • Убедитесь, что ваш бинарный файл содержит отладочную информацию в формате DWARF (обычно это требует компиляции с флагом -g).

Этот код должен помочь вам начать работу с libdwarf для извлечения информации о полях структур в вашей программе на C.

ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้