Bij het werken met uitvoerbare bestanden en bibliotheken voor ARM rijst vroeg of laat de vraag: Is het gecompileerd met hard-float (ARMHF) of met soft-float (ARMEL)? Het verschil is significant, omdat het de compatibiliteit en prestaties van binaire gegevens bij floating-pointbewerkingen beïnvloedt. Gelukkig bevat het ELF-binaire bestand zelf de nodige aanwijzingen om dit betrouwbaar te bepalen.
In dit artikel bespreken we hoe u een ARM ELF kunt inspecteren met behulp van het hulpprogramma lees zelf Om onderscheid te maken tussen de twee varianten, bespreken we op welke labels je moet letten, welke outputverschillen je kunt vinden afhankelijk van de versie van de tool, en hoe je details zoals Thumb of NEON moet interpreteren. We bespreken ook waarom de keuze tussen ARMEL en ARMHF tijdens de compilatie wordt gemaakt. niet in het runtime-systeemen we verhelderen veelvoorkomende twijfels over multiarch-omgevingen waarin arm-linux-gnueabihf en arm-linux-gnueabi naast elkaar bestaan.
Wat betekenen ARMHF (hard-float) en ARMEL (soft-float)?
Dit gedrag wordt gedefinieerd door de AAPCS (ARM Architecture Procedure Call Standard), die beschrijft hoe parameters worden doorgegeven en waarden worden geretourneerd. De AAPCS heeft variantenEn de indicator die ons interesseert om ARMHF te onderscheiden, is degene die geassocieerd wordt met VFP, een indicator die we weerspiegeld zullen zien in de kenmerken van het binaire systeem.
ELF en zijn header: waarom geeft het ons al die informatie?
ELF (Executable and Linkable Format) is de feitelijke standaard in Linux en slaat gegevens op in de header- en attribuutsecties. informatie over de doelarchitectuur en ABI-conventies die gebruikt worden om het uitvoerbare bestand of de bibliotheek te compileren. Als u geïnteresseerd bent in uitgebreide details, kunt u eenvoudig de ELF-headerspecificatie doorzoeken om alle bestaande velden te zien.
Om een ELF te inspecteren, is het gereedschap lees zelf Het is de directe route. Optie -a draait praktisch alles om, en optie -A staat toe focus op architectuurafhankelijke informatie (ARM in ons geval), met kenmerken zoals het type floating point, of Thumb is ingeschakeld, NEON-ondersteuning en andere relevante vlaggen.
Bereid een omgeving voor met ARMEL en ARMHF
Als je de output uit de praktijk wilt vergelijken, is het een praktische manier om de gcc/g++-toolchains voor beide varianten op een Ubuntu-machine te installeren. Je krijgt systeembibliotheken voor armel en armhf naast elkaar geïnstalleerd dankzij multiarch.
Na de installatie zijn de typische bibliotheekroutes: /usr/arm-linux-gnueabihf/lib voor ARMHF y /usr/arm-linux-gnueabi/lib voor ARMELAls u beide hebt, kunt u bijvoorbeeld de wiskundige bibliotheek libm.so.6 vergelijken en bekijken hoe de kenmerken veranderen afhankelijk van de variant.
De definitieve aanwijzing: Tag_ABI_VFP_args met readelf
De praktische test omvat het analyseren van de ELF met readelf en het zoeken naar verwijzingen naar FP in de attributen. Een zeer eenvoudige tactiek is om de uitvoer te filteren op de string FP om te focussen op de drijvendekommagetallen. omdat de meest onthullende indicator het Tag_ABI_VFP_args-kenmerk is.
In de libm.so.6-bibliotheek, gecompileerd als ARMEL (soft-float), ziet u de typische ARM-kenmerken, maar De regel Tag_ABI_VFP_args zal niet verschijnenDaarentegen wordt in het ARMHF (hard-float) bestand libm.so.6 een extra regel met dat kenmerk weergegeven, waarmee het gebruik van de VFP-aanroepconventie wordt bevestigd.
readelf -A /usr/arm-linux-gnueabi/lib/libm.so.6 | grep FP
In ARMEL zal het filteren op FP informatie tonen die betrekking heeft op algemene floating-point-mogelijkheden, maar zonder het kenmerk dat VFP-argumenten declareertHerhaal dit over ARMHF:
readelf -A /usr/arm-linux-gnueabihf/lib/libm.so.6 | grep FP
U vindt een extra vermelding van het type Tag_ABI_VFP_args wat het onmiskenbare teken is van een harde float. Dit detail is wat in de praktijk... Dit stelt ons in staat om betrouwbaar te stellen dat de binaire waarde de ABI hard-float volgt.
Uitvoervariaties afhankelijk van de readself-versie
Afhankelijk van de implementatie en versie van readelf kan de exacte vorm van de tekst variëren. Bijvoorbeeld, met readelf gecompileerd van elftoolchain-0.6.1De extra regel geeft niet alleen het kenmerk aan, maar kan ook worden beschreven als: Tag_ABI_VFP_args: AAPCS (VFP-variant).
In dezelfde familie van uitvoer kunnen er nog twee andere waarden voor Tag_ABI_VFP_args voorkomen: “AAPCS (basisvariant)” en “toolchain-specifiek”De beschikbare literatuur vermeldt deze alternatieven, hoewel het niet altijd duidelijk is onder welke voorwaarden elk ervan precies wordt geretourneerd. Het belangrijkste is om te erkennen dat de vermelding van de VFP-variant Het wordt geassocieerd met het hard-float geval.
Naast de beroepsopleiding: -A geeft ook les in architectuur, Thumb en NEON
Hoewel we ons hier concentreren op het onderscheid tussen ARMHF en ARMEL, is het de moeite waard om te onthouden dat readself -A Het biedt een breder beeld van het binaire bestand. De uitvoer toont, naast floating-point-attributen, ook de exacte doelarchitectuur, indien het binaire bestand Het is gebouwd met Thumb en of de ondersteuning is ingeschakeld NEON, naast andere relevante mogelijkheden voor optimalisatie en compatibiliteit.
Dit alles helpt valideren dat het binaire bestand niet alleen overeenkomt met de FP-variant die u verwacht, maar ook Het is afgestemd op de instructieset en extensies die beschikbaar zijn op het apparaat waarop de update wordt uitgevoerd.
Voorbeeld van een aanbevolen workflow
Een typische vergelijkingsreeks voor beide varianten van libm.so.6 zou er als volgt uit kunnen zien: Routes weergeven, readelf uitvoeren en filteren op FPZo ziet u in één oogopslag het belangrijkste verschil tussen armel en 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
Als je in ARMHF de lijn met Tag_ABI_VFP_args En aangezien het niet in ARMEL voorkomt, kunt u het verschil als geverifieerd beschouwen. En als u liever alles wilt zien, kunt u altijd... readself -a voor een compleet overzicht van headers, secties, attributen en symbolen.
Compilatie, niet systeem: wie beslist over ARMEL of ARMHF?
Het is belangrijk om één concept te benadrukken: De ARMEL/ARMHF-variant wordt bepaald door de binaire code.Het is het compilatieproces dat de structuur van het ELF-bestand bepaalt, niet het abstracte "systeem". Als u uw uitvoerbare bestand compileert met hard-float-ondersteuning, krijgt u een ARMHF ELF; anders is het een ARMEL. Dit onderscheid komt voort uit het buildproces en is hardgecodeerd in de kenmerken van het ELF.
Als u zich zorgen maakt over welke weg u in uw eigen project wilt bewandelen, is dat meestal eenvoudiger. los het op tijdens het compileren met compiler- en linkeropties en met preprocessor-geconditioneerde code. Het is niet gebruikelijk om tijdens runtime in hetzelfde binaire bestand te willen schakelen tussen ARMEL en ARMHF. omdat het verschillende ABI's betreft.
Door de Makefile gegenereerde headers: een praktische techniek
Als u wilt dat het uitvoerbare bestand zelf zijn 'identiteit' aangeeft tijdens het bouwen, is een zeer nuttige techniek om een header van de Makefile Tijdens de buildfase detecteert het buildsysteem of u voor armel of armhf compileert en dumpt een constante in een headerbestand, dat vervolgens wordt opgenomen in de broncode.
Met deze aanpak kan het uiteindelijke binaire bestand bijvoorbeeld een opdracht weergeven -versie die aangeeft of het is geconstrueerd als ARMEL of ARMHF, zonder dat er tijdens runtime iets hoeft te worden "gedetecteerd". Over het algemeen past deze praktijk beter bij het feit dat De ABI wordt ingesteld bij het compileren en mag niet dynamisch variëren.
Waarom zou je dat tijdens runtime willen weten?
Degenen die deze vraag stellen, proberen soms hun gedrag aan te passen in de hitte van het moment. Maar de realiteit is dat De gebruikelijke praktijk is om de code te scheiden met behulp van preprocessorrichtlijnen en compileer verschillende varianten, één voor armel en één voor armhf. Het is niet realistisch om beide in hetzelfde artefact te combineren, omdat elk is afhankelijk van zijn eigen set bibliotheken en een andere ABI.
Daarom is de algemene aanbeveling om de beslissing te nemen vóór het samenstellenen valideer tijdens runtime eenvoudigweg of de doelomgeving de juiste bibliotheken heeft voor het binaire bestand dat u wilt starten. Om een reeds gebouwd binair bestand te controleren, lees zelf Het blijft het meest directe instrument.
Multiarch: Waarom je zowel arm-linux-gnueabihf als arm-linux-gnueabi hebt
Als u bij het weergeven van de mappen op uw systeem ziet dat u arm-linux-gnueabihf en arm-linux-gnueabi Samenleven is niet per se een fout: dat is multi-archHiermee kunt u meerdere architecturen of ABI-varianten parallel installeren en gebruiken, waardoor kruiscompilaties en testen eenvoudiger worden.
In Debian-omgevingen waren er bijvoorbeeld momenten waarop werd besloten Multiarch verwijderen uit standaard Wheezy-afbeeldingen omdat de steun groen was en meer problemen dan voordelen opleverde. Vervolgens, Jessie en latere versies hebben verbeterde ondersteuning multiarch, waardoor armel/armhf-coexistentie levensvatbaarder wordt zonder al te veel hoofdpijn.
Het correct interpreteren van de routes is niet voldoende
Een bibliotheek in /usr/arm-linux-gnueabihf/lib suggereert dat het ARMHF is, en hetzelfde geldt voor /usr/arm-linux-gnueabi/lib voor ARMEL. Maar als je het zeker wilt weten, Open de ELF en bekijk de kenmerken ervanDe paden zijn nuttig als leidraad, hoewel in complexe systemen met meerdere archieven of handmatige back-ups, kan misleiden.
Opnieuw de uitgang van readself -A Het levert sluitend bewijs: de aanwezigheid van Tag_ABI_VFP_args voor hard-float en de afwezigheid ervan voor soft-float. Bovendien zullen de andere vlaggen dit bevestigen. instructies en uitbreidingen die het binaire bestand nodig heeft.
Wat kun je nog meer leren van -A, behalve FP?
De ARM-attributensectie die -A laat zien, vertelt je niet alleen of er een VFP is. Het vertelt je ook of de binaire Het is gemarkeerd als Duim, de architectuurvariant (bijvoorbeeld ARMv7) en of er ondersteuning is NEONMet deze gegevens kunt u controleren of het binaire bestand compatibel is met de doelhardware. Zo voorkomt u verrassingen tijdens de implementatie.
Denk bijvoorbeeld aan het valideren van een runtime-omgeving: naast het verifiëren van ARMEL versus ARMHF, Controleer duim en NEON Het kan u waarschuwen voor subtiele incompatibiliteiten die op het eerste gezicht niet zichtbaar zijn.
Veelgestelde vragen en snelle tips
- Kan ik het detecteren zonder het zelf te lezen? Technisch gezien zou je het kunnen afleiden uit het pad of uit de manier waarop je eigen project is gebouwd, maar de beste manier is om het ELF-bestand te inspecteren. `readelf -A` levert het bewijs in het binaire bestand zelf.
- Is het voldoende om "VFP" bij de uitgang te zien? Als we algemene verwijzingen naar VFP zien, duidt dat op mogelijkheden, maar de beslissende lijn is Tag_ABI_VFP_args in ARMHF. De afwezigheid ervan in ARMEL is eveneens significant.
- Wat als mijn reader zegt "AAPCS (VFP-variant)"? Het is een alternatieve vorm van hetzelfde idee dat we zien in bepaalde bouwwerken, zoals die gebaseerd op elftoolchain-0.6.1Ook kan 'AAPCS (basisvariant)' of 'toolchain-specifiek' verschijnen.
- Waarom heb ik beide versies geïnstalleerd? door multi-archDit is normaal in sommige omgevingen. Zorg ervoor dat u de bibliotheekset koppelt en uitvoert die overeenkomt met de binaire code die u gebruikt.
Een korte notitie over de bronnen en hun financiering
Sommige technische publicaties die deze onderwerpen behandelen, bevatten berichten voor hun werk ondersteunen via cryptovalutadonaties, platforms zoals Patreon of affiliatelinks naar winkels zoals Amazon of AliExpress. Het is een gangbare praktijk in onafhankelijke media, die soms Ze gebruiken affiliate links in hun artikelen om commissie te verdienen als u na het klikken een aankoop doet.
Mentale checklist bij het auditen van een binair bestand
Voordat u een bibliotheek of uitvoerbaar bestand voor uw apparaat accepteert, dient u de volgende punten te controleren: readself query -A, zoekt naar de aanwezigheid of afwezigheid van Tag_ABI_VFP_argsBekijk de doelarchitectuur en controleer of Thumb en NEON passen bij de hardware waarop u het systeem gaat draaien.
Als u met meerdere toolchains werkt die via multiarch zijn geïnstalleerd, Besteed speciale aandacht aan de routes De compiler- en linkeromgevingsvariabelen moeten zo worden geconfigureerd dat ARMEL-headers en -bibliotheken niet worden vermengd met ARMHF-binaries, of andersom. Een kleine onoplettendheid kan problemen veroorzaken. verwarrende symptomen tijdens de linktijd of runtime.
Typische fouten om te vermijden
Een klassieke fout is om overmoedig te zijn en aan te nemen dat een bibliotheek hard-float is omdat deze zich onder arm-linux-gnueabihf bevindt, zonder de ELF-kenmerken te bevestigenEen andere veelvoorkomende fout is het proberen te koppelen van een ARMHF-uitvoerbaar bestand aan ARMEL-bibliotheken (of andersom), wat meestal resulteert in symboolfouten of vreemd gedrag.
Het is ook gebruikelijk om "detecteren tijdens runtime" te willen gebruiken om bibliotheekpaden on-the-fly te wijzigen. Onthoud dat De ARMEL/ARMHF-keuze wordt niet geïmproviseerd tijdens de uitvoeringHet is hardgecodeerd in het binaire bestand. Pas je implementaties en pakketten aan zodat elk uitvoerbaar bestand de bibliotheken voor zijn eigen variant ontvangt.
Als u snel een referentie nodig hebt, kunt u de volgende stappen volgen: zoek de bibliotheek of het uitvoerbare bestand (bijvoorbeeld libm.so.6), start readelf -A Filter het bestand op FP als u direct ter zake wilt komen en controleer of er een regel is Tag_ABI_VFP_args (hard-float) of, indien ontbrekend, (soft-float). Controleer vervolgens de architectuur, Thumb en NEON om het binaire profiel te voltooien.
Bij vergelijking van ARMEL en ARMHF in hetzelfde systeem, onthoud de multiarchcontext En het belangrijkste verschil zit in de floating-point ABI die door de AAPCS is gedefinieerd. Vanuit dat perspectief wordt het interpreteren van de kenmerken van readelf een snelle en nauwkeurige oefening.
Het is duidelijk dat je met het juiste gereedschap en de kennis waar je moet zoeken, Bepalen of een ARM ELF een ARMHF of ARMEL is, is een kwestie van secondenDe sleutel is om het Tag_ABI_VFP_args-kenmerk voor hard-float te identificeren en readelf -A te gebruiken om aanvullende context over de architectuur, Thumb en NEON te verkrijgen. Rekening houdend met de specifieke kenmerken van multiarch en het feit dat de ABI-keuze vastligt tijdens de compilatie, U voorkomt verwarring en bespaart tijd bij het valideren van binaire bestanden en bibliotheken in uw projecten.