Несовместимость ABI исполняемого файла Rust с динамической библиотекой C++

В настоящее время я пытаюсь связать исполняемый файл 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.


person kodr    schedule 23.07.2019    source источник
comment
Я не думаю, что есть что-то, что гарантирует бинарную совместимость с ржавчиной/С++.. по крайней мере, ничего, о чем я слышал.   -  person Jesper Juhl    schedule 23.07.2019
comment
Ничто не гарантирует совместимость с C++ ABI, и точка.   -  person Shepmaster    schedule 23.07.2019
comment
@Eljay, это поверхность API общей библиотеки — github.com/Azure/iotedge/blob/master/edgelet/hsm-sys/ Исходный код в связанном репозитории полностью C, но у меня есть реализация этой поверхности API который вместо этого представляет собой комбинацию C и C++. Исходный код в связанном репозитории при компиляции с тем же набором инструментов linaro дает библиотеку с SYSV ABI (что, как я предполагаю, связано только с использованием gcc), тогда как компиляция моей реализации (с обоими C/C++) дает двоичный файл с вместо этого GNU/Linux ABI   -  person kodr    schedule 23.07.2019
comment
@JesperJuhl знаете ли вы какие-либо рекомендации о том, как связать динамические библиотеки с исполняемыми файлами Rust? Репозиторий, на который я ссылался в своем комментарии выше, содержит исполняемый файл Rust, о котором я упоминал в своем вопросе (github.com/Azure/iotedge/tree/master/edgelet/iotedged), который успешно связывается с реализацией C общей библиотеки, представленной здесь: github.com/Azure/iotedge/tree/master/edgelet/hsm-sys/   -  person kodr    schedule 23.07.2019
comment
Спасибо. Я не знал, что существуют различия в C ABI для GNU/Linux и SYSV. Я узнал кое-что новое. +1   -  person Eljay    schedule 23.07.2019
comment
@Shepmaster отмечает вас здесь, чтобы узнать ваше мнение по тому же вопросу, который я задал в своем ответе JesperJuhl выше.   -  person kodr    schedule 23.07.2019
comment
Возможный дубликат Могу ли я вызывать функции C или C++ из Rust? код?   -  person Stargateur    schedule 23.07.2019
comment
Знаете ли вы какие-либо рекомендации о том, как связать динамические библиотеки с исполняемыми файлами Rust? Нет. Извините.   -  person Jesper Juhl    schedule 23.07.2019
comment
@Stargateur Кажется, я просмотрел этот пост ранее. Как вы упоминаете в своем ответе на вопрос в этом посте: Итак, чтобы вызвать С++ из Rust, вы должны пройти через C., это именно то, что происходит и в моем случае. Проблема здесь больше связана с несовместимостью ABI с целевыми архитектурами aarch64. Как было сказано ранее, динамическая загрузка общей библиотеки отлично работает на машинах с процессором AMD64.   -  person kodr    schedule 23.07.2019
comment
В своем вопросе вы смешиваете C и C++, C/C++, что очень неясно, когда вы хотите говорить о C или когда вы хотите говорить о C++. Пожалуйста, отредактируйте свой вопрос, чтобы избежать смешивания двух языков, особенно когда вы говорите об ABI, которые являются поведением реализации и полностью различаются между C и С++.   -  person Stargateur    schedule 23.07.2019
comment
@Stargateur Только что отредактировал вопрос, добавив немного пояснений. Причина, по которой я упомянул оба C/C++, заключается в том, что в библиотеке есть код на обоих языках. Чтобы дать краткий обзор, библиотека представляет собой реализацию этого файла заголовка: github.com/Azure/iotedge/blob/master/edgelet/hsm-sys/ Я сохранил большую часть кода реализации C из связанный репозиторий, но изменили реализацию некоторых заголовков, чтобы вместо этого использовать C++. Я тоже добавлю эту информацию к вопросу   -  person kodr    schedule 23.07.2019