Двоичный интерфейс приложения (Application binary interface, ABI)
Этот раздел документирует особенности, которые влияют на ABI скомпилированного вывода крейта.
См. внешние функции для информации о указании ABI для экспорта функций. См. внешние блоки для информации о указании ABI для линковки внешних библиотек.
Атрибут used
Атрибут used может быть применен только к static элементам. Этот атрибут принуждает
компилятор сохранять переменную в выходном объектном файле (.o, .rlib, и т.д., исключая финальные бинарные файлы)
даже если переменная не используется или не ссылается никаким другим элементом в крейте.
Однако, линковщик все еще свободен удалить такой элемент.
Ниже приведен пример, который показывает, при каких условиях компилятор сохраняет static элемент в
выходном объектном файле.
#![allow(unused)] fn main() { // foo.rs // Это сохраняется из-за `#[used]`: #[used] static FOO: u32 = 0; // Это удаляемо, потому что не используется: #[allow(dead_code)] static BAR: u32 = 0; // Это сохраняется, потому что публично достижимо: pub static BAZ: u32 = 0; // Это сохраняется, потому что на него ссылается публичная, достижимая функция: static QUUX: u32 = 0; pub fn quux() -> &'static u32 { &QUUX } // Это удаляемо, потому что на него ссылается приватная, неиспользуемая (мертвая) функция: static CORGE: u32 = 0; #[allow(dead_code)] fn corge() -> &'static u32 { &CORGE } }
$ rustc -O --emit=obj --crate-type=rlib foo.rs
$ nm -C foo.o
0000000000000000 R foo::BAZ
0000000000000000 r foo::FOO
0000000000000000 R foo::QUUX
0000000000000000 T foo::quux
Атрибут no_mangle
Атрибут no_mangle может быть использован на любом элементе для отключения стандартного
искажения имен символов (name mangling). Символ для элемента будет идентификатором
имени элемента.
Дополнительно, элемент будет публично экспортирован из произведенной библиотеки или
объектного файла, аналогично атрибуту used.
Этот атрибут небезопасен, так как немангированный символ может столкнуться с другим символом с тем же именем (или с хорошо известным символом), приводя к неопределенному поведению.
#![allow(unused)] fn main() { #[unsafe(no_mangle)] extern "C" fn foo() {} }
2024 Edition differences
До редакции 2024 года разрешалось использовать атрибут
no_mangleбез квалификацииunsafe.
Атрибут link_section
Атрибут link_section определяет секцию объектного файла, в которую будет помещено
содержимое функции или статической переменной.
Атрибут link_section использует синтаксис MetaNameValueStr для указания имени секции.
#![allow(unused)] fn main() { #[unsafe(no_mangle)] #[unsafe(link_section = ".example_section")] pub static VAR1: u32 = 1; }
Этот атрибут небезопасен, так как позволяет пользователям помещать данные и код в секции памяти, не ожидающие их, такие как изменяемые данные в области только для чтения.
2024 Edition differences
До редакции 2024 года разрешалось использовать атрибут
link_sectionбез квалификацииunsafe.
Атрибут export_name
Атрибут export_name определяет имя символа, который будет
экспортирован для функции или статической переменной.
Атрибут export_name использует синтаксис MetaNameValueStr для указания имени символа.
#![allow(unused)] fn main() { #[unsafe(export_name = "exported_symbol_name")] pub fn name_in_rust() { } }
Этот атрибут небезопасен, так как символ с пользовательским именем может столкнуться с другим символом с тем же именем (или с хорошо известным символом), приводя к неопределенному поведению.
2024 Edition differences
До редакции 2024 года разрешалось использовать атрибут
export_nameбез квалификацииunsafe.