В настоящее время я пытаюсь связать исполняемый файл Rust с общей библиотекой, написанной на C++ и C. Динамическая загрузка общей библиотеки отлично работает на архитектурах amd64, но я сталкиваюсь с ошибками сегментации, когда исполняемый файл пытается загрузить общую библиотеку на Linux-машина aarch64 [Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1033-raspi2 aarch64)].
Я использую набор инструментов Linaro aarch64 (http://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64).-linux-gnu.tar.xz) для кросс-компиляции общей библиотеки (сочетание кода C++ и C).
При проверке с помощью file/readelf результирующая разделяемая библиотека имеет GNU/Linux ABI, что, по-видимому, связано с использованием g++ для сборки кода C++ в библиотеке, тогда как ABI исполняемого файла Rust — SYSV (перекрестно скомпилированный для aarch64 с использованием проект https://github.com/rust-embedded/cross)
Я заметил, что ручное редактирование файла .so общей библиотеки для изменения флага ABI с GNU/Linux на SYSV решает проблему.
Можно ли настроить исполняемый файл или библиотеку на конкретный ABI? В идеале я хотел бы создать исполняемый файл Rust таким образом, чтобы он мог ссылаться на разделяемую библиотеку независимо от ABI библиотеки.
Чтобы дать краткий обзор, общая библиотека является реализацией этого файла заголовка: https://github.com/Azure/iotedge/blob/master/edgelet/hsm-sys/azure-iot-hsm.-c/inc/hsm_client_data.h Я сохранил большую часть кода реализации C из связанного репозитория, но изменил реализацию некоторых заголовков, чтобы вместо этого использовать C++.
Пожалуйста, дайте мне знать, если потребуются какие-либо дополнительные сведения.
Я пытался вернуться к более старым версиям g++ (4.9) для создания общей библиотеки C и C++, но это всегда приводило к артефакту с ABI GNU/Linux.
Этот вопрос был идентифицирован как дубликат этого Могу ли я вызывать функции C или C++ из кода Rust? но ответы на эти вопросы не помогли решить мою проблему, поскольку в предложениях/ответах на этот пост указано, что C++ можно вызывать, проходя через «интерфейс» C, который именно то, что у меня есть. Проблема больше связана с несовместимостью ABI для конкретной целевой архитектуры, например, aarch64. Проблема не воспроизводится на целевой архитектуре amd64.
Ожидается — исполняемый файл Rust и динамическая общая библиотека, созданные с использованием как C, так и C++, будут иметь совместимые ABI для aarch64.
На самом деле — исполняемый файл Rust нацелен на SYSV ABI, а динамическая общая библиотека — на GNU/Linux ABI.