Как да се открие дали ARM ELF двоичен файл е с твърда плаваща точка (ARMHF) или мека плаваща точка (ARMEL)

  • Ключовият ключ за ARMHF спрямо ARMEL в ELF е атрибутът Tag_ABI_VFP_args.
  • readelf -A показва информация, зависима от архитектурата, включително FP, Thumb и NEON.
  • arm-linux-gnueabihf и arm-linux-gnueabi могат да съществуват едновременно чрез multiarch, внимавайте да не ги объркате.

сървър за ръце

Когато работите с изпълними файлове и библиотеки за ARM, рано или късно възниква въпросът: Компилира ли се с hard-float (ARMHF) или със soft-float (ARMEL)? Разликата е значителна, тъй като влияе върху съвместимостта с двоични файлове и производителността при операции с плаваща запетая. За щастие, самият ELF двоичен файл съдържа необходимите улики за надеждно определяне на това.

В тази статия ще разгледаме как да инспектираме ARM ELF с помощта на помощната програма Риделф За да разграничим двата варианта, ще разгледаме кои етикети да търсите, какви разлики в изхода може да откриете в зависимост от версията на инструмента и как да интерпретирате подробности като Thumb или NEON. Ще обсъдим и защо решението за ARMEL срещу ARMHF се взема по време на компилация. не е в системата за изпълнениеи изясняваме често срещани съмнения относно мултиархивни среди, където arm-linux-gnueabihf и arm-linux-gnueabi съществуват едновременно.

Какво означават ARMHF (твърдо-флоатинг) и ARMEL (меко-флоатинг)?

Това поведение е дефинирано от AAPCS (ARM Architecture Procedure Call Standard), който описва как се предават параметри и как се връщат стойности. AAPCS има вариантиИ този, който ни интересува, за да разграничим ARMHF, е този, свързан с VFP, индикатор, който ще видим отразен в атрибутите на двоичния файл.

ELF и неговият заглавен файл: защо ни дава цялата информация

ELF (Executable and Linkable Format) е де факто стандартът в Linux и съхранява данни в заглавните и атрибутните си секции. информация за целевата архитектура и ABI конвенции, използвани за компилиране на изпълнимия файл или библиотеката. Ако се интересувате от изчерпателни подробности, просто потърсете в спецификацията на ELF заглавката, за да видите всички съществуващи полета.

За да инспектирате ELF, инструментът Риделф Това е директният път. Вариант -а преобръща практически всичко, а вариант -А позволява фокус върху информация, зависима от архитектурата (ARM в нашия случай), показвайки атрибути като типа на числата с плаваща запетая, дали Thumb е активиран, поддръжката на NEON и други съответни флагове.

Подгответе среда с ARMEL и ARMHF

Ако искате да сравните резултатите от реалния свят, практичен начин е да инсталирате инструментариума gcc/g++ за двата варианта на машина с Ubuntu. По този начин, Ще получите системни библиотеки за armel и armhf инсталирани един до друг благодарение на мултиарката.

След инсталирането, типичните библиотечни маршрути са: /usr/arm-linux-gnueabihf/lib за ARMHF y /usr/arm-linux-gnueabi/lib за ARMELНаличието и на двете ви позволява да сравните например математическата библиотека libm.so.6 и да наблюдавате как атрибутите се променят в зависимост от варианта.

Окончателната улика: Tag_ABI_VFP_args с readelf

Практическият тест включва анализ на ELF с readelf и търсене на препратки към FP в атрибутите. Много проста тактика е да се филтрира изходът по низа FP, за да се фокусираме върху числата с плаваща запетая. тъй като най-показателният индикатор е атрибутът Tag_ABI_VFP_args.

В библиотеката libm.so.6, компилирана като ARMEL (soft-float), ще видите типичните ARM атрибути, но Редът Tag_ABI_VFP_args няма да се появиЗа разлика от това, във файла ARMHF (hard-float) libm.so.6 ще се покаже допълнителен ред с този атрибут, потвърждаващ използването на конвенцията за извикване на VFP.

readelf -A /usr/arm-linux-gnueabi/lib/libm.so.6 | grep FP

В ARMEL, филтрирането по FP ще покаже информация, свързана с общите възможности за операции с плаваща запетая, но без атрибута, който декларира VFP аргументиКогато го повтарям върху ARMHF:

readelf -A /usr/arm-linux-gnueabihf/lib/libm.so.6 | grep FP

Ще намерите допълнителен запис от типа Аргументи на Tag_ABI_VFP което е безпогрешен признак на твърда плувка. Този детайл е това, което на практика Това ни позволява надеждно да заявим, че двоичният файл следва ABI hard-float.

Вариации на изхода в зависимост от версията на readelf

В зависимост от имплементацията и версията на readelf, точният вид на текста може да варира. Например, с readelf, компилиран от elftoolchain-0.6.1Допълнителният ред не само показва атрибута, но може да бъде описан като: Tag_ABI_VFP_args: AAPCS (вариант на VFP).

В същото семейство от изходи има две други стойности, които могат да се появят за Tag_ABI_VFP_args: „AAPCS (базов вариант)“ и „специфични за инструменталната верига“В наличната литература се споменават тези алтернативи, въпреки че не винаги е ясно при какви точни условия се връща всяка от тях. Важното е да се осъзнае, че споменаването на варианта VFP Свързано е с корпуса с твърд поплавък.

Отвъд професионалното обучение: -A също преподава архитектура, Thumb и NEON

Въпреки че тук се фокусираме върху разграничението между ARMHF и ARMEL, струва си да се помни, че readelf -A Той предлага по-широк поглед върху двоичния файл. Изходът му ще покаже, освен атрибутите с плаваща запетая, точната целева архитектура, ако двоичният файл е... Изграден е с Thumb и ако поддръжката е активирана NEON, наред с други подходящи възможности за оптимизация и съвместимост.

Всичко това помага да се потвърди, че двоичният файл не само съответства на очаквания от вас FP вариант, но и Той е съобразен с набора от инструкции и разширенията които имате на разположение на устройството, където ще се изпълнява.

Пример за препоръчителен работен процес

Типична последователност за сравняване на двата варианта на libm.so.6 може да бъде толкова проста, колкото следната: Избройте маршрути, изпълнете readelf и филтрирайте по FPТова ще ви даде ключовата разлика между armel и armhf с един поглед.

# ARMEL (soft-float)
ls -l /usr/arm-linux-gnueabi/lib/libm.so.6
readelf -A /usr/arm-linux-gnueabi/lib/libm.so.6 | grep FP

# ARMHF (hard-float)
ls -l /usr/arm-linux-gnueabihf/lib/libm.so.6
readelf -A /usr/arm-linux-gnueabihf/lib/libm.so.6 | grep FP

Ако в ARMHF наблюдавате линията с Аргументи на Tag_ABI_VFP И тъй като не се появява в ARMEL, можете да считате разликата за потвърдена. А ако предпочитате да видите всичко, винаги можете да използвате readelf -a за пълен дъмп на заглавки, секции, атрибути и символи.

Компилация, а не система: кой решава ARMEL или ARMHF

Важно е да се подчертае една концепция: Вариантът ARMEL/ARMHF се определя от двоичния код.Процесът на компилация определя структурата на ELF файла, а не абстрактната „система“. Ако компилирате изпълнимия си файл с поддръжка на hard-float, ще получите ARMHF ELF; в противен случай ще получите ARMEL. Това разграничение произтича от процеса на компилация и е твърдо кодирано в атрибутите на ELF.

Поради тази причина, ако това, което ви тревожи, е да решите кой път да поемете в собствения си проект, обикновено е по-лесно. решете го по време на компилация с опции за компилатор и линкер, както и с код, обусловен от препроцесор. Не е обичайно да се иска превключване между ARMEL и ARMHF в един и същ двоичен файл по време на изпълнение. защото включва различни ABI.

Заглавки, генерирани от Makefile: практичен метод

Ако искате самият изпълним файл да декларира своята „идентичност“ по време на компилация, много полезна техника е да генерирате заглавка от Makefile По време на фазата на компилиране, системата за компилиране разпознава дали компилирате за armel или armhf и записва константа в заглавен файл, който след това се включва в изходния код.

С този подход, крайният двоичен файл може да изложи, например, команда -version който отпечатва дали е конструиран като ARMEL или ARMHF, без да е необходимо да се „открива“ каквото и да било по време на изпълнение. Като цяло, тази практика се вписва по-добре с факта, че ABI се задава при компилиране и не трябва да се променя динамично.

Защо бихте искали да знаете това по време на изпълнение?

Тези, които задават този въпрос, понякога се опитват да адаптират поведението си в разгара на момента. Но реалността е, че Обичайната практика е кодът да се разделя с помощта на препроцесорни директиви и компилирайте различни варианти, един за armel и друг за armhf. Смесването и на двете в един и същ артефакт не е реалистично, защото всеки зависи от собствен набор от библиотеки и различен ABI.

Следователно общата препоръка е да вземете решение преди компилиранеи по време на изпълнение просто проверете дали целевата среда има подходящите библиотеки за двоичния файл, който ще стартирате. За да одитирате вече изграден двоичен файл, Риделф Той остава най-директният инструмент.

Мултиархитектура: Защо имате и arm-linux-gnueabihf, и arm-linux-gnueabi

Ако при изброяване на директории във вашата система видите, че имате arm-linux-gnueabihf и arm-linux-gnueabi съвместното съществуване не е непременно грешка: това е мултиархТова ви позволява да инсталирате и използвате множество архитектури или ABI варианти едновременно, което улеснява кръстосаните компилации и тестване.

В Debian среди, например, имаше моменти, когато беше решено Премахване на мултиархитектурата в стандартните Wheezy изображения защото подкрепата беше зелена и причиняваше повече проблеми, отколкото ползи. Впоследствие, Jessie и по-късните версии са подобрени в поддръжката мултиархитектура, което прави съвместното съществуване на armel/armhf по-жизнеспособно без толкова много главоболия.

Правилното тълкуване на маршрутите не е достатъчно

Виждането на библиотека в /usr/arm-linux-gnueabihf/lib предполага, че е ARMHF, и същото важи и за /usr/arm-linux-gnueabi/lib за ARMEL. Но ако искате да сте сигурни, Отворете ELF и разгледайте неговите атрибутиПътищата са полезни като ръководство, въпреки че в сложни системи с множество архиви или ръчни резервни копия, може да подведе.

Отново, изходът на readelf -A Това предоставя убедително доказателство: наличието на Tag_ABI_VFP_args за hard-float и отсъствието му за soft-float. Освен това, другите флагове ще потвърдят това. инструкции и разширения които двоичният файл може да изисква.

Какво друго можете да научите от -A, освен FP

Разделът с атрибути на ARM, който показва -A, не само ви казва дали има VFP. Той също така ви казва дали двоичният файл Маркирано е като „Палец“, вариантът на архитектурата (напр. ARMv7) и дали има поддръжка NEONТези подробности ви помагат да проверите дали двоичният файл е съвместим с целевия хардуер и да предотвратите изненади по време на внедряването.

Да разгледаме например валидирането на среда за изпълнение: заедно с проверката на ARMEL спрямо ARMHF, Проверете палеца и NEON Може да ви предупреди за фини несъвместимости, които не са видими на пръв поглед.

Често задавани въпроси и бързи съвети

  • Мога ли да го открия без readelf? Технически, бихте могли да го заключите от пътя или начина, по който е бил изграден вашият проект, но най-добрият метод е да проверите ELF файла. `readelf -A` предоставя доказателствата в самия двоичен файл.
  • Достатъчно ли е да се види "VFP" на изхода? Виждането на общи препратки към VFP показва възможности, но решаващата линия е Аргументи на Tag_ABI_VFP в ARMHF. Отсъствието му в ARMEL е също толкова важно.
  • Ами ако моят четец каже „AAPCS (вариант VFP)“? Това е алтернативна форма на същата идея, наблюдавана в определени конструкции, като например тези, базирани на elftoolchain-0.6.1Може да се появи и „AAPCS (базов вариант)“ или „специфично за инструменталната верига“.
  • Защо имам инсталирани и двете версии? Por мултиархТова е нормално в някои среди. Просто се уверете, че свързвате и изпълнявате с библиотечния набор, който съответства на двоичния файл, който използвате.

Кратка бележка за източниците и тяхното финансиране

Някои технически публикации, които разглеждат тези теми, включват съобщения за подкрепят работата им чрез дарения с криптовалута, платформи като Patreon или партньорски връзки към магазини като Amazon или AliExpress. Това е често срещана практика в независимите медии, които понякога Те използват партньорски връзки в своите статии, за да печелят комисионна, ако направят покупка след кликване.

Контролен списък за ментални цели при одитиране на двоичен файл

Преди да приемете библиотека или изпълним файл за вашето устройство, прегледайте тези точки: заявка за readelf -A, търси наличието или отсъствието на Аргументи на Tag_ABI_VFPРазгледайте целевата архитектура и проверете дали Thumb и NEON са съвместими с хардуера, на който ще я стартирате.

Ако работите с множество вериги инструменти, инсталирани чрез multiarch, Обърнете специално внимание на маршрутите Променливите на средата на компилатора и линкера трябва да бъдат конфигурирани така, че да се избегне смесването на ARMEL заглавни файлове и библиотеки с ARMHF двоични файлове или обратното. Дори малък пропуск може да причини проблеми. объркващи симптоми по време на свързване или по време на изпълнение.

Типични грешки, които трябва да се избягват

Класическа грешка е да бъдем прекалено самоуверени и да приемаме, че дадена библиотека е hard-float, защото се намира под arm-linux-gnueabihf. без потвърждаване на ELF атрибутитеДруга често срещана грешка е опитът за свързване на изпълним файл на ARMHF с библиотеки на ARMEL (или обратното), което обикновено води до неуспехи със символи или странно поведение.

Също така е често срещано да искате да „откриете по време на изпълнение“, за да промените пътищата към библиотеките в движение. Не забравяйте, че Изборът ARMEL/ARMHF не е импровизиран по време на изпълнениеТова е твърдо кодирано в двоичния файл. Настройте внедряванията и пакетите си така, че всеки изпълним файл да получава библиотеките за собствения си вариант.

Ако имате нужда от бърза справка, помислете за тези стъпки: намерете библиотеката или изпълнимия файл (например libm.so.6), стартиране на readelf -A Спрямо файла, филтрирайте по FP, ако искате да стигнете директно до същината, и проверете дали има ред Аргументи на Tag_ABI_VFP (твърдо плаващ) или ако липсва (меко плаващ). След това проверете архитектурата, Thumb и NEON, за да завършите двоичния профил.

Когато сравняваме ARMEL и ARMHF в една и съща система, запомнете мултиархичния контекст И фактът, че ключовата разлика се крие в ABI с плаваща запетая, дефиниран от AAPCS. От тази гледна точка, интерпретирането на атрибутите на readelf се превръща в бързо и точно упражнение.

Ясно е, че с правилния инструмент и знаейки къде да търсите, Определянето дали даден ARM ELF е ARMHF или ARMEL е въпрос на секунди.Ключът е да се идентифицира атрибутът Tag_ABI_VFP_args за hard-float и да се използва readelf -A, за да се получи допълнителен контекст относно архитектурата, Thumb и NEON. Имайки предвид особеностите на multiarch и факта, че изборът на ABI е фиксиран при компилация, Ще избегнете объркване и ще спестите време при валидиране на двоични файлове и библиотеки във вашите проекти.

Какво представляват ARM Cortex-R и Cortex-M?
Свързана статия:
ARM Cortex-R и Cortex-M: какво представляват, разлики и кога да изберете всеки от тях