Journal Un utilitaire pour formater la sortie de avr-objdump

Posté par  . Licence CC By‑SA.
16
4
juil.
2022

… ou l'heure de l'auto-promo a sonné :-D.

Bonjour à tous.

Un de mes passe-temps est le développement embarqué, notamment avec les micro-contrôleurs et surtout ceux de Atmel (aujourd'hui Microchip). J'ai toujours été quelque peu insatisfait de la sortie de l'outil avr-objdump. En effet, ce dernier, s'il demande le type de processeur (plus exactement l'architecture), est incapable de sortir autre chose que les adresses mémoire des registres au lieu de leur nom.

Alors, ça me chatouille. Ou ça me gratouille, je sais plus trop.

Ni une ni deux, j'ai un jour dégainé Geany, Python et mon envie de corriger ça. Le tout a donné adump.py, un script qui s'enroule autour de avr-objdump et en transforme la sortie en remplaçant les adresses "connues" par le nom des registres correspondants.

Et comme ça ne suffisait pas, j'ai ajouté un peu de style avec couleurs et quelques attributs de texte (gras et italique) pour faciliter la consultation.

Voici ce que ça donne, en n'images:

Le style "papyrus":
Désassemblage avec le style "papyrus"

Le style "marine":
La même vue avec le style "marine"

Le style par défaut:
Le style de coloriage par défaut

Il y en a d'autres et on peut en ajouter à volonté. Bien sûr, la traduction des adresses en noms de registres:

Exemple de désassemblage pour l'ATtiny1634

Le dépôt

Comme ça fait quelques années que ce petit outil me sert, j'ai décidé de le partager. Le code est disponible sur mon dépôt SourceForge. Je n'ai pas suivi de ligne de conduite… Pythonique et me suis contenté de déposer les fichiers dans /usr/local/bin. Je n'ai pas prévu d'en faire un paquet Python et les processeurs disponibles ne sont que ceux dont je me suis servis jusqu'à présent mais l'outil est extensible, je l'espère très facilement.

La syntaxe

L'utilisation en ligne de commande est quasiment identique à avr-objdump, à ceci près que c'est le nom du CPU qui est demandé au lieu de l'architecture (e.g. avr5, avr35, …)

adump.py atmega328 --color -SCt app.elf # Coloration par défaut pour l'ATmega328[p]
adump.py attiny45 -D -b binary demo.bin # Désassemblage d'une image binaire

L'argument --help donne une explication sommaire sur la syntaxe.

Le fonctionnement interne

Le script reconnaît des arguments supplémentaires grâce au module argparse. Les arguments non reconnus sont passés au programme avr-objdump, qui est ensuite exécuté. Le script analyse chaque ligne depuis l'interface standard de sortie. Si celle-ci contient l'adresse d'un registre, elle est aussitôt traduite.

La correspondance CPU/liste des registres se fait par un module spécifique au CPU indiqué à la ligne de commandes. Le fichier principal, arch.py recense les correspondances entre les CPU et l'architecture, telles qu'apparaissant dans la documentation de avr-gcc.

Cerise sur le gâteau, j'ai aussi voulu trier par ordre numérique les adresses de la table des symbôles (lorsque l'argument -t est passé à avr-objdump). L'outil emploie les expressions régulières pour l'analyse de la syntaxe.

N'hésitez pas à me faire part de tout commentaire éventuel sur ce projet. J'espère juste qu'il sera utile à plus d'une personne que moi tout seul…

  • # Manque de pratique...

    Posté par  . Évalué à 2.

    … j'oublie bien évidemment qu'on ne peut modifier un journal une fois modifié, contrairement aux forums.

    Coquille 1: s/Cerise, sur/Cerise sur
    Coquille 2: s/les adresse de la table/les adresse*s* de la table

  • # SourceForge ?

    Posté par  . Évalué à 6.

    Merci pour ce partage !

    Le code est disponible sur mon dépôt SourceForge.

    Par curiosité : pour quelle(s) raison(s) as-tu choisi, pour ce nouveau projet, cette forge plutôt qu'une autre ?

    • [^] # Re: SourceForge ?

      Posté par  (site web personnel, Mastodon) . Évalué à -8.

      /me se retient de marquer le commentaire comme inutile
      /me se demande pourquoi faut-il justifier d'utiliser une forge

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: SourceForge ?

        Posté par  . Évalué à 4.

        sourceforge a tout de même un énorme passif vraiment problématique. Remplacer les téléchargements de projets par des adwares ou prendre le contrôles de pages des projets qui se barrent, je pense que c'est suffisant pour fuir cette plateforme.

        Aujourd'hui elle a arrêté ça, mais après avoir passé plusieurs années à la fuir et à expliquer à tout le monde qu'il ne faut rien télécharger sur sourceforge, il faut une bonne raison pour y retourner.

        Oui ça pourrait arriver ailleurs, mais ça n'est pas arrivé ailleurs et tu as des plateformes communautaires qui ont une probabilité faible d'en arriver là.

        https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: SourceForge ?

          Posté par  (site web personnel, Mastodon) . Évalué à -1. Dernière modification le 07 juillet 2022 à 00:25.

          Ah d'accord, mais faut le dire (qu'il y a un passif etc) au lieu de tourner autour du pot. C'est comme de demander à Michou : pourquoi t'as choisi le rose, alors que l'autre n'y voyait pas à mal et ignore vos véléïté face à cette couleur.

          Pour les probabilités sur autres, ne lisant pas dans le marc de café je ne me prononce pas. Certaines personnes ont eu récemment la surprise de fermeture intempestives sous prétexte de leur faciès et pourtant ce n'était pas supposé arriver.

          /me toujours contre les accusations qui veulent avancer masquées même si c'est supposément pour de bonnes raisons.

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: SourceForge ?

            Posté par  . Évalué à 3.

            /me toujours contre les accusations qui veulent avancer masquées même si c'est supposément pour de bonnes raisons.

            Je sais pas de quoi tu parles. J'ai dit que ça pouvait arriver ailleurs parce que c'est un argument recevable. À part le fait que ça s'est mal passé pour sourceforge rien ne garantit que github1, gitlab ou atlassian ne s'y mettent. Les forges communautaires je pense ont moins de chances car elles sont moins mercantiles.

            Par contre oui te fermer ton compte ça existe partout par exemple framasoft se donne le droit de fermer n'importe quel dépôt selon des critères à leur discrétion. C'est dans leur gcu.


            1. il ne s'agit pas d'une accusation, je suis un utilisateur très content de github. Mais comme sourceforge github peut être revendu et c'est après un rachat que sourceforge s'est mis à troller 

            https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

            • [^] # Re: SourceForge ?

              Posté par  (site web personnel, Mastodon) . Évalué à 1. Dernière modification le 07 juillet 2022 à 12:19.

              Calmos, je ne t'accuse de rien ! Je constate juste que tu as une justification/explication qui m'était inconnue ainsi qu'à beaucoup d'autres comme le témoigne ce journal comme cette autre dépêche :
              https://linuxfr.org/news/un-logiciel-libre-de-coloriage-pour-enfants-et-d-apprentissage-des-departements-francais
              De ce fait, si c'est ça le sous-entendu de la question initiale, je trouve dommage que la personne ayant initié ce fil de discussion ne mette pas ça sur la table directement. Cela aurait été plus utile que de demander de se justifier d'un choix personnel et de moinser les gens qui s'en étonnent.
              Ne vois pas une attaque personnelle, je dénonce un truc général que je note souvent par ci par là (surtout avec des français hexagonaux). Mais bon, j'ai oublié de te remercier d'avoir éclairé la lanterne de beaucoup qui vont juste voir les accuser sous-jacentes sans comprendre l'entre-soi (ce qui encore une fois n'aide pas ou pire peut faire fuir toute nouvelle personne ayant envie de partager.)

              “It is seldom that liberty of any kind is lost all at once.” ― David Hume

              • [^] # Re: SourceForge ?

                Posté par  . Évalué à 4. Dernière modification le 07 juillet 2022 à 12:51.

                C'est quelque chose qui a était médiatisé ici un certain nombres de fois (ici, ici ou ici). Ne pas connaître tout l'historique de linuxfr je veux bien, mais on est pas dans de la référence abscons difficile à retrouver. Mon moteur de recherche me donne aussi des liens comme ça dès la première page quand je cherche sourceforge. C'est aussi la perte de d’engouement pour sourceforge qui a permis à github d'exister (et c'est aussi l'existence de github qui réduit la popularité de sourceforge). Évidement les pages wikipedia de sourceforge parlent abondament du sujet (ça représente plus de moitié de la page fr et peut être un tiers pour la page anglaise).

                Ne pas savoir quelque chose ça arrive bien sûr à tout le monde, mais je réfute que ce soit de l'entre-soi (tout en utilisant /me…).

                Je voudrais bien te parler d'entre-soi, mais je crains que mon clavier se blo

                https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

      • [^] # Re: SourceForge ?

        Posté par  . Évalué à 3. Dernière modification le 07 juillet 2022 à 08:42.

        /me se retient [...]
        /me se demande [...]
        

        D'où vient ce genre de construction "/me" ? je suppose qu'il y a une référence (informatique a priori) qui m'échappe. Quel est l’intérêt de l'utiliser ? Je le lis comme "moi se retient…, moi se demande", alors ça peut-être amusant/original les premières fois qu'on le voit, mais vu que ça revient assez régulièrement…

        • [^] # Re: SourceForge ?

          Posté par  . Évalué à 7.

          C'est une notation qui vient de l'IRC, quand on tapait ça dans la discussion, ça remplaçait automatiquement par le pseudo.

          Les vrais naviguent en -42

          • [^] # Re: SourceForge ?

            Posté par  (site web personnel, Mastodon) . Évalué à 4.

            Tout à fait. Il fallait le taper en début de message pour que ça marche (y a des exceptions mais le principe est celui des messages reconnues comme ^/<commande> arguments$ et où la commande non officielle /me est communément reconnue pour remplacer le pseudo qui écrit)
            Je m'excuse de continuer à utiliser cette facilité qui me permet de continuer à utiliser la troisième personne (je fais partie des gens qui parle parfois d'elle-même avec un regard extérieur) et se traduit aisément à la première personne en français (je suppose que beaucoup ici connaissent un peu d'anglais et sauront corriger le « moi » seul par un « je me » ou un « moi, je » selon le cas, mais trop longs à taper pour ma flemmarde personne.)

            “It is seldom that liberty of any kind is lost all at once.” ― David Hume

            • [^] # Re: SourceForge ?

              Posté par  (site web personnel, Mastodon) . Évalué à 4. Dernière modification le 07 juillet 2022 à 14:53.

              /me se retient […]

              est plus long à taper que "je me retiens". L'excuse du trop long est pourrie.

              « Tak ne veut pas quʼon pense à lui, il veut quʼon pense », Terry Pratchett, Déraillé.

              • [^] # Re: SourceForge ?

                Posté par  . Évalué à 3.

                C'est une figure de style sur irc.

                Ça sert soit à être descriptif :

                /me sort le popcorn et écoute

                Soit c'est le cas ici, comme prétérition.

                https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

              • [^] # Re: SourceForge ?

                Posté par  (site web personnel, Mastodon) . Évalué à 1.

                son blaze est « Gil Cot » et non « je »

                “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: SourceForge ?

            Posté par  . Évalué à 6.

            IRC n'est pas mort tu as encore pas mal de gens qui s'en servent tous les jours ;) (pas moi)

            https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

      • [^] # Re: SourceForge ?

        Posté par  . Évalué à 3.

        /me se demande pourquoi faut-il justifier d'utiliser une forge

        J'administre une forge logicielle (libre). Comme le projet en question n'était pas publié auparavant, le cheminement et les critères de sélection de l'outil/l'instance m'intéressent.

        • [^] # Re: SourceForge ?

          Posté par  (site web personnel, Mastodon) . Évalué à 1.

          Ah merci. Beaucoup. La question du pourquoi de la question se posait quand même donc, vu que beaucoup ont compris ça comme une question rhétorique de pourquoi n'avoir pas boycotté cette forge.

          J'ai vu que la réponse par rapport au projet a été faite entre temps, et je m'y retrouve un peu (j'ai maintenant un Gitea sur un serveur perso exposé, sinon j'ai tendance à utiliser encore mes vieux comptes qui fonctionnent encore.)

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

    • [^] # Re: SourceForge ?

      Posté par  . Évalué à 6. Dernière modification le 08 juillet 2022 à 14:01.

      pour quelle(s) raison(s) as-tu choisi, pour ce nouveau projet, cette forge plutôt qu'une autre ?

      La raison est toute simple: à l'époque où je me suis créé un compte (2005), github, gitlab et cie n'existaient pas encore. Les offres étaient limitées et Sourceforge jouissait encore d'une bonne réputation.

      J'ai ensuite voulu découvrir autre chose mais Github, c'est non pour moi — bien qu'un compte soit obligatoire dans certains projets pour le rapport de bugs et ça me gave un peu, d'ailleurs. J'ai aussi essayé Savannah pour son hébergement éthique, il y a quelques jours. Mais le temps qu'il faut pour seulement déposer une archive dépasse les trois jours… un peu gros quand c'est le seul maillon à prendre autant de temps dans la chaîne. C'est sans doute la rançon du peer-reviewing¹, nécessaire dans de tels cas, j'imagine mais c'est bien frustrant.

      Donc je suis resté avec mon compte Sourceforge. Il a le mérite de déjà exister et de ne pas (plus) me prendre la tête.


      ¹ Je l'appelle ainsi mais sans savoir si c'est le nom approprié.

  • # Idée pour les autres MCU

    Posté par  . Évalué à 4.

    Chouette petit projet.

    Je me permet une suggestion pour résoudre les adresses en leurs macros pour plus de microcontrôleurs.

    Tu as la liste complète dans la avr-libc (par exemple dans iotn20.h pour le ATTiny20). Peut-être qu'avec une combinaison de cpp et de python (ou plus simplement avec pcpp), tu peux reconstruire automatiquement la liste des registres pour tous les processeurs.

    D'ailleurs, j'ai un vague souvenir d'avoir vu une telle liste (probablement sur avrfreaks, ou bien dans avr-gdb ?) il y a quelques années.

    • [^] # Re: Idée pour les autres MCU

      Posté par  . Évalué à 2. Dernière modification le 12 juillet 2022 à 00:28.

      Merci, et aussi pour le tuyau.

      Perso, je me tapais la liste des registres en les pompant depuis la fiche technique (toujours avec un script de mon cru pour formater les résultats). Du coup, je construis cette liste à mesure des micros dont je me sers et j'étoffe les scripts en fonction. Avec une liste prête à l'emploi, je pourrai effectivement répartir les registres par architecture et les spécificités par-CPU.

      Jusqu'à présent, j'ai eu la flemme de "parser" les fichiers *.h pour en faire quelque chose :-D .

    • [^] # Re: Idée pour les autres MCU

      Posté par  . Évalué à 2.

      Ta suggestion a piqué ma curiosité et j'ai essayé d'arriver à ce résultat avec uniquement le préprocesseur avr-cpp. Et bingo! Voici ce que ça donne avec un "bête" programme de démo pour le ATtiny1634, par exemple:

      avr-cpp -E -dM -Os -DF_CPU=8000000 -mmcu=attiny1634 demo.cpp | \
      sed -rne 's/#define\s+(\w+)\s+_SFR_([IM]\w+[0-9]+\(\w+\))/\1: \2/p'

      En gros, ça n'affiche que les lignes de définition des registres (SFR_IOxx et SFR_MEMxx) et le résultat est le suivant:

      TWSSRA: MEM8(0x7D)
      EECR: IO8(0x1C)
      EEDR: IO8(0x1D)
      OSCCAL0: MEM8(0x63)
      MCUCR: IO8(0x36)
      PINA: IO8(0x0F)
      PINB: IO8(0x0B)
      PINC: IO8(0x07)
      ...

      Note que les options -O et -DF_CPU= sont nécessaires pour éviter un avertissement (généré dans les en-têtes).

      Il "suffit" de tripatouiller le script sed pour adapter la sortie en fonction du langage souhaité. Moralité: on a déjà assez avec les outils de base.

      C'est bien entendu un premier jet car, tu l'auras remarqué, on perd l'info du processeur et du fichier d'en-tête incorporé. Je pense que c'est l'objet de l'option -d du préprocesseur. Je suis à peu près certain que c'est là-dessus qu'il faut jouer.

    • [^] # Re: Idée pour les autres MCU

      Posté par  . Évalué à 3.

      C'est fou ce qu'on peut apprendre des macros de GCC!

      Bon, ceci sort du cadre de mon journal mais je voulais aussi afficher des statistiques/renseignements sur le projet, par exemple le nom du fichier d'entête, l'architecture, les fonctionnalités additionnelles, l'ordre des octets, etc. Après avoir "chipoté" quelques heures de plus, voici ce que j'ai fini par utiliser:

      echo -e "#include <avr/io.h>\nvoid main() {}" | sort | \
      avr-gcc -E -dM -Os -DF_CPU=16000000 -mmcu=atmega2560 - | \
      sed -rn \
      -e '/AVR_IOXXX/s/.*\s+"([^"]+)"$/MCU header: \1/p' \
      -e '/__AVR_LIBC_VERSION_STRING__/s/.*\s+"([0-9\-\.]+)"$/AVR libc: version \1/p' \
      -e '/__AVR_DEVICE_NAME__/s/.*\s+(\w+)$/device name: \1/p' \
      -e '/__AVR_ARCH__/s/.*\s+(\w+)$/architecture: avr\1/p' \
      -e '/SIGNATURE/{N;N;s/#define\s+SIG\w+//g;s/\n/,/g;s/^/signature:/gp}' \
      -e '/RAMSIZE/s/.*\s+([0-9]+)$/RAM size: \1 bytes/gp' \
      -e '/E2SIZE/s/.*\s+([0-9]+)$/EEPROM size: \1 bytes/gp' \
      -e '/__SIZEOF_(SHORT|INT|LONG|FLOAT|POINTER|SIZE_T)__/s/.*__SIZEOF_(\w+)__\s+([0-9]+)$/\L\1 size: \2 bytes/gp' \
      -e '/__BYTE_ORDER__/s/.*__ORDER_(\w+)_ENDIAN__/byte ordering: \L\1 endian/gp' \
      -e '/_AVR_HAVE_(MUL|MOVW|E?LPMX?|E?JMP_E?CALL|RAMP[DXYZ])/{s/.*HAVE_(\w+)__.*$/\1/g;H}' \
      -e '${x;s/\n|_/ /g;s/^/features:/gp}'

      C'est imbitable, hein? C'est normal. Comment ça fonctionne? avr-gcc -E invoque le préprocesseur sans compiler quoi que ce soit. La source est une simple fonction main() avec le fichier d'en-tête minimal, io.h. Dans tout ce bazar, sort est essentiel! Ensuite, vient l'analyse:

      • la macro __AVR_IOXXX__ contient le nom du fichier d'en-tête spécifique au processeur,
      • décortiquer __AVR_LIBC_VERSION_STRING__ et ne prendre que la chaîne correspondant à la version de avr-libc,
      • faire pareil avec __AVR_DEVICE_NAME__ et __AVR_ARCH__,
      • la signature est répartie sur 3 lignes, du style #define SIGNATURE_[012] 0x[0-9]+; on jumelle ces trois lignes en ne retenant que les valeurs hexadécimales,
      • les macros RAMSIZE et E2SIZE sont décortiquées comme __AVR_DEVICE_NAME__,
      • extraire les tailles pour des types intéressants (short, int, float, etc.) en rappelant le nom du type, gentiment converti en minuscules (\L)
      • faire de même pour l'agencement avec __BYTE_ORDER__, dont on ne retient que le terme du milieu (peut être "LITTLE", "BIG" ou "PDP")
      • extraire les fonctionnalités __AVR_HAVE_XXX__ et les joindre sur une seule ligne.

      Toutes ces transformations sont aussi préfixées par une étiquette. Voici ce que ça donne, par exemple pour un ATmega2560:

      architecture: avr6
      device name: atmega2560
      MCU header: iomxx0_1.h
      AVR libc: version 2.1.0
      byte ordering: little endian
      signature: 0x1E, 0x98, 0x01
      float size: 4 bytes
      int size: 2 bytes
      long size: 4 bytes
      pointer size: 2 bytes
      short size: 2 bytes
      size_t size: 2 bytes
      features: ELPM ELPMX JMP CALL¹ LPMX MOVW MUL RAMPZ

      Dans un autre fil, j'ai avoué que je sed souvent à la difficulté. Ben voilà.

      La documentation se trouve ici: https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html

      ¹ Noter que les valeurs JMP et CALL sont liées par un underscore avec la macro _AVR_HAVE_JMP_CALL__. J'ai simplement remplacé dans la foulée ce dernier par un espace, comme le marqueur de fin de ligne.

      • [^] # Re: Idée pour les autres MCU

        Posté par  (site web personnel, Mastodon) . Évalué à 3. Dernière modification le 12 juillet 2022 à 18:33.

        Utilise le bloc de code :

        
             ```sh
             # note le saut de ligne avant et après,
             # sh (peut-être aussi shell et/ou bash) ici
             ...
             ```
        
        

        Ça rend moins imbitable. Ici, ce sont des sed sympas ;-)

        “It is seldom that liberty of any kind is lost all at once.” ― David Hume

        • [^] # Re: Idée pour les autres MCU

          Posté par  . Évalué à 3. Dernière modification le 12 juillet 2022 à 18:40.

          Ah, merci mais c'est trop tard pour l'édition… Quand je parlais d'imbitable, c'était au nombre de lignes et à la complexité que je faisais référence, ceci dit. Mais bon, j'ai déjà vu plus compliqué en moins de lignes, aussi.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.