Quan treballes amb executables i biblioteques per a ARM, tard o d'hora sorgeix el dubte: està compilat amb hard-float (ARMHF) o amb soft-float (ARMEL)? La diferència no és menor, perquè afecta la compatibilitat de binaris i el rendiment en operacions de coma flotant. Per sort, el mateix binari ELF conté les pistes necessàries per esbrinar-ho de manera fiable.
En aquest article repassem com inspeccionar un ELF d'ARM amb la utilitat readelf per distingir les dues variants, quines etiquetes mireu, quines diferències de sortida podeu trobar segons la versió de l'eina i com interpretar detalls com Thumb o NEON. A més, comentem per què la decisió ARMEL vs ARMHF es pren a la compilació, no al sistema en temps d'execució, i aclarim dubtes comuns sobre entorns amb multiarch on conviuen arm-linux-gnueabihf i arm-linux-gnueabi.
Què signifiquen ARMHF (hard-float) i ARMEL (soft-float)
Aquest comportament està definit per l'ARM Architecture Procedure Call Standard (AAPCS), que descriu com es passen paràmetres i es tornen valors. L'AAPCS compta amb variants, i la que ens interessa per diferenciar ARMHF és l'associada a VFP, indicador que veurem reflectit als atributs del binari.
ELF i la seva capçalera: per què ens dóna tota la informació
El format ELF (Executable and Linkable Format) és l'estàndard de facto a Linux i guarda a la capçalera i seccions d'atributs informació sobre l'arquitectura objectiu i convencions ABI utilitzades per compilar l'executable o la biblioteca. Si us interessa el detall exhaustiu, només cal buscar l'especificació de la capçalera ELF per veure tots els camps que existeixen.
Per inspeccionar un ELF, l'eina readelf és la via directa. L'opció -a bolca pràcticament tot, i l'opció -A permet centrar-se en la informació dependent de larquitectura (ARM en el nostre cas), mostrant atributs com el tipus de coma flotant, si s'ha habilitat Thumb, suport NEON, i altres banderes rellevants.
Preparar un entorn amb ARMEL i ARMHF
Si vols comparar sortides reals, una manera pràctica és instal·lar en una màquina Ubuntu els toolchains de gcc/g++ per a totes dues variants. En fer-ho, obtindràs biblioteques de sistema per a armel i armhf instal·lades costat a costat gràcies a multiarch.
Després de la instal·lació, les rutes típiques de les biblioteques són: /usr/arm-linux-gnueabihf/lib per ARMHF y /usr/arm-linux-gnueabi/lib per ARMEL. Tenir totes dues et permet contrastar, per exemple, la biblioteca matemàtica libm.so.6 i observar com canvien els atributs en funció de la variant.
La pista definitiva: Tag_ABI_VFP_args amb readelf
La comprovació pràctica consisteix a analitzar l'ELF amb readelf i cercar referències a FP en els atributs. Una tàctica molt directa és filtrar la sortida per la cadena FP per centrar-te en els punts flotants, ja que l'indicador més aclaridor és l'atribut Tag_ABI_VFP_args.
A la biblioteca libm.so.6 compilada com ARMEL (soft-float), veuràs els atributs típics d'ARM, però no apareixerà la línia Tag_ABI_VFP_args. En canvi, a la libm.so.6 d'ARMHF (hard-float) es mostrarà una línia addicional amb aquest atribut que confirma l'ús de la convenció de trucades de VFP.
readelf -A /usr/arm-linux-gnueabi/lib/libm.so.6 | grep FP
A ARMEL, el filtratge per FP mostrarà informació relacionada amb capacitats de coma flotant generals, però sense l'atribut que declara arguments VFP. En repetir-ho sobre ARMHF:
readelf -A /usr/arm-linux-gnueabihf/lib/libm.so.6 | grep FP
Trobareu una entrada addicional del tipus Tag_ABI_VFP_args que és el senyal inequívoc de hard-float. Aquest detall és el que, a la pràctica, ens permet afirmar de manera fiable que el binari segueix l'ABI hard-float.
Variacions de sortida segons la versió de readelf
Segons la implementació i versió de readelf, la forma exacta del text pot variar. Per exemple, amb readelf compilat a partir de elftoolchain-0.6.1, la línia addicional no només indica l'atribut, sinó que es pot descriure com: Tag_ABI_VFP_args: AAPCS (VFP variant).
En aquesta mateixa família de sortides, hi ha dos valors més que et poden aparèixer per Tag_ABI_VFP_args: AAPCS (base variant) i toolchain-specific. La literatura disponible esmenta aquestes alternatives, si bé no sempre queda clar en quines condicions exactes es tornen cadascuna. L'important és reconèixer que la menció a la variant VFP està associada al cas hard-float.
Més enllà de l'FP: -A també ensenya arquitectura, Thumb i NEON
Tot i que aquí ens centrem a distingir ARMHF i ARMEL, convé recordar que readelf -A ofereix una panoràmica més àmplia del binari. A la sortida podràs veure, a més d'atributs de punt flotant, l'arquitectura destinació exacta, si el binari està construït amb Thumb i si s'ha habilitat suport NEON, entre altres capacitats rellevants per a optimització i compatibilitat.
Tot això ajuda a validar que el binari no només correspon a la variant de FP que esperes, sinó que està alineat amb el conjunt d'instruccions i extensions que tens disponibles al dispositiu on s'executarà.
Exemple de flux de treball recomanat
Una seqüència típica per comparar ambdues variants de libm.so.6 podria ser tan simple com aquesta: llistar rutes, executar readelf i filtrar per FP. Amb això obtindràs la diferència clau entre armel i armhf d'un cop d'ull.
# 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
Si a ARMHF observes la línia amb Tag_ABI_VFP_args ia ARMEL no apareix, pots donar per verificada la diferència. I si ho prefereixes veure tot, sempre pots fer servir readelf -a per a un bolcat complet de capçaleres, seccions, atributs i símbols.
Compilació, no sistema: qui decideix ARMEL o ARMHF
És important subratllar un concepte: la variant ARMEL/ARMHF la determina el binari, per com s'ha compilat, no “el sistema” en abstracte. Si compileu el vostre executable amb suport hard-float, obtindreu un ELF d'ARMHF; si no, serà ARMEL. Aquesta distinció s'arrossega des del procés de construcció i està codificada als atributs de l'ELF.
Per aquest motiu, si el que et preocupa és decidir quin camí prendre en el teu projecte, sol ser més senzill resoldre'l en temps de compilació amb opcions del compilador i de l'enllaçador, i amb codi condicionat per preprocessador. No és habitual voler commutar entre ARMEL i ARMHF al mateix binari en temps d'execució, perquè implica ABIs diferents.
Capçaleres generades pel Makefile: una tècnica pràctica
Si us interessa que el mateix executable declari la seva «identitat» en temps de construcció, una tècnica molt útil és generar una capçalera des del Makefile a la fase de build. El sistema de construcció detecta si estàs compilant per armel o armhf i bolca una constant a un fitxer de capçalera que després s'inclou al codi font.
Amb aquest enfocament, el binari final pot exposar, per exemple, una ordre -versió que imprimiu si va ser construït com ARMEL o ARMHF, sense necessitat de «detectar» res en execució. En general, aquesta pràctica encaixa millor amb el fet que l'ABI es fixa en compilar i no ha de variar dinàmicament.
Per què ho voldries saber en temps d'execució?
Els qui plantegen aquesta pregunta de vegades busquen adaptar el comportament en calent. Però la realitat és que el més habitual és separar el codi amb directives del preprocessador i compilar variants diferents, una per armel i una altra per armhf. Barrejar totes dues en un mateix artefacte no és realista, perquè cadascuna depèn del seu propi conjunt de biblioteques i d'una ABI diferent.
Per això la recomanació general és prendre la decisió abans de compilar, i en temps d'execució limitar-se a validar que l'entorn de destinació té les biblioteques adequades per al binari que llançaràs. Per auditar un binari ja construït, readelf continua sent l'eina més directa.
Multiarch: per què tens arm-linux-gnueabihf i arm-linux-gnueabi alhora
Si en llistar directoris al teu sistema veus que tens arm-linux-gnueabihf i arm-linux-gnueabi coexistint, no és necessàriament un error: això és multiarch. Permet instal·lar i utilitzar múltiples arquitectures o variants ABI en paral·lel, facilitant compilacions creuades i proves.
En entorns Debian, per exemple, hi va haver moments en què es va decidir retirar multiarch en imatges per defecte de wheezy perquè el suport estava verd i causava més problemes que beneficis. Posteriorment, Jessie i versions posteriors van millorar el suport multiarch, fent més viable la coexistència armel/armhf sense tants mals de cap.
Interpretar bé les rutes no és suficient
Veure una biblioteca a /usr/arm-linux-gnueabihf/lib suggereix que és ARMHF, i el mateix amb /usr/arm-linux-gnueabi/lib per a ARMEL. Però si vols estar segur, obre l'ELF i mira els seus atributs. Les rutes ajuden com a guia, encara que en sistemes complexos amb multiarch o amb còpies manuals, poden induir a error.
De nou, la sortida de readelf -A aporta la prova concloent: presència de Tag_ABI_VFP_args per a hard-float, i la seva absència a soft-float. A més, la resta de flags et corroboraran instruccions i extensions que pot requerir el binari.
Què més pots aprendre de -A, a més de l'FP
La secció d'atributs d'ARM que mostra -A no només us explica si hi ha VFP. També et diu si el binari està marcat com a Thumb, la variant d'arquitectura (per exemple, ARMv7), i si hi ha suport NEON. Aquests detalls us ajuden a corroborar que el binari és compatible amb el maquinari objectiu i eviten sorpreses en desplegar.
Penseu, per exemple, en validar un entorn d'execució: juntament amb la verificació d'ARMEL vs ARMHF, comprovar Thumb i NEON pot avisar-te d'incompatibilitats subtils que no es veuen a primera vista.
Preguntes freqüents i consells ràpids
- Puc detectar-ho sense readelf? Tècnicament, podries inferir-lo per la ruta o com va ser construït el teu propi projecte, però el mètode sòlid és inspeccionar l'ELF. readelf -A ofereix l'evidència dins del mateix binari.
- Només cal veure «VFP» a la sortida? Veure referències generals a VFP indica capacitats, però la línia decisiva és Tag_ABI_VFP_args a ARMHF. La seva absència a ARMEL és igual de significativa.
- I si el meu readelf diu AAPCS (VFP variant)? És una forma alternativa de la mateixa idea vista en certes builds, com les basades en elftoolchain-0.6.1. També poden aparèixer AAPCS (base variant) o toolchain-specific.
- Per què tinc les dues variants instal·lades? Per multiarch. És normal en alguns entorns. Només assegureu-vos d'enllaçar i executar amb el conjunt de biblioteques que correspongui al binari que utilitzeu.
Petita nota sobre les fonts i el seu finançament
Algunes publicacions tècniques que aborden aquests temes inclouen missatges per donar suport a la seva feina a través de donacions a criptomonedes, plataformes com Patreon o mitjançant enllaços d'afiliat a botigues com Amazon o Aliexpress. És una pràctica comuna en mitjans independents, que de vegades utilitzen enllaços d'afiliat als seus articles per obtenir una comissió si fas una compra després de fer clic.
Checklist mental quan audites un binari
Abans de donar per bona una llibreria o executable per al dispositiu, repassa aquests punts: consulta readelf -A, cerca la presència o absència de Tag_ABI_VFP_args, mira l'arquitectura objectiu, i verifica si Thumb i NEON encaixen amb el maquinari on el correràs.
Si treballes amb diverses toolchains instal·lades per multiarch, presta especial atenció a les rutes ia les variables dentorn del compilador i enllaçador, per no barrejar capçaleres i biblioteques dARMEL amb binaris dARMHF o viceversa. Una petita distracció pot causar símptomes confusos en temps denllaç o execució.
Errors típics que convé evitar
Un clàssic és confiar-se i assumir que una biblioteca està en hard-float perquè es troba sota arm-linux-gnueabihf, sense confirmar els atributs de l'ELF. Un altre error freqüent és intentar enllaçar un executable ARMHF amb biblioteques ARMEL (o al revés), cosa que sol acabar en fallades de símbol o comportaments estranys.
També és habitual que es vulgui "detectar en execució" per canviar rutes de biblioteques sobre la marxa. Recorda que l'elecció ARMEL/ARMHF no s'improvisa en temps d'execució; està gravada al binari. Ajusta els desplegaments i els paquets perquè cada executable rebi les biblioteques de la seva pròpia variant.
Si necessites una referència ràpida, pensa en aquests gestos: localitza la biblioteca o executable (per exemple, libm.so.6), llança readelf -A contra el fitxer, filtra per FP si vols anar al gra, i comprova si hi ha línia Tag_ABI_VFP_args (hard-float) o si falta (soft-float). Després revisa arquitectura, Thumb i NEON per quadrar el perfil complet del binari.
Quan compares ARMEL i ARMHF en un mateix sistema, recorda el context de multiarch i el fet que la diferència clau resideix a l'ABI de coma flotant definida per l'AAPCS. Amb aquesta perspectiva, interpretar els atributs de readelf esdevé un exercici ràpid i precís.
Queda clar que, amb l'eina adequada i sabent on mirar, determinar si un ELF d'ARM és ARMHF o ARMEL és qüestió de segons. La clau és identificar l'atribut Tag_ABI_VFP_args per a hard-float i aprofitar readelf -A per obtenir context addicional sobre l'arquitectura, el Thumb i el NEON. Tenint presents les particularitats de multiarch i que l'elecció d'ABI es fixa en la compilació, evitaràs confusions i estalviaràs temps en validar binaris i biblioteques als teus projectes.