Question

Je produis un fichier hexadécimal à exécuter sur un processeur ARM que je souhaite conserver en dessous de 32 Ko. Il est actuellement beaucoup plus volumineux que cela et je me demandais si quelqu'un aurait des conseils sur la meilleure approche à adopter pour réduire les coûts?

Voici ce que j'ai fait jusqu'à présent

  1. J'ai donc "taille" dessus pour déterminer la taille du fichier hexadécimal.
  2. Puis "taille" à nouveau pour voir quelle est la taille de chaque fichier objet qui lie pour créer les fichiers hexadécimaux. Il semble que la majorité de la taille provient de bibliothèques externes.
  3. Ensuite, j'ai utilisé 'readelf' pour voir quelles fonctions occupent le plus de mémoire.
  4. J'ai parcouru le code pour voir si je pouvais éliminer les appels à ces fonctions.

C’est là que je me trouve bloqué. Il ya des fonctions que je n’appelle pas directement (par exemple, _vfprintf) et je ne trouve pas ce qui l’appelle pour pouvoir supprimer l’appel (je pense ne pas en avoir besoin).

Alors, quelles sont les prochaines étapes?

Réponse aux réponses:

  • Comme je peux le constater, il existe des fonctions appelées qui occupent beaucoup de mémoire. Je ne peux cependant pas trouver ce qui l'appelle.
  • Je souhaite supprimer ces fonctions (si possible), mais je ne trouve pas ce qui les appelle! Pourrait être appelé depuis n'importe quel nombre de fonctions de bibliothèque, je suppose.
  • L'éditeur de liens fonctionne comme vous le souhaitez, il ne comprend que les fichiers de bibliothèque pertinents. Comment savoir si seules les fonctions pertinentes sont incluses? Pouvez-vous définir un drapeau ou quelque chose pour cela?
  • J'utilise GCC
Était-ce utile?

La solution

Liste générale:

  • Assurez-vous que les options de débogage du compilateur et de l'éditeur de liens sont désactivées
  • Compiler et lier avec toutes les options de taille activées (-Os dans gcc)
  • Exécuter strip sur l'exécutable
  • Générez un fichier de carte et vérifiez la taille de vos fonctions. Vous pouvez soit obtenir l’éditeur de liens pour générer votre fichier de carte ( -M lorsque vous utilisez ld), ou vous pouvez utiliser objdump sur l’exécutable final (notez que cela ne fonctionnera que sur un exécutable non décomposé!). ne résoudra pas le problème, mais cela vous permettra de connaître les pires contrevenants.
  • Utilisez nm pour rechercher les symboles appelés à partir de chacun de vos fichiers d'objet. Cela devrait vous aider à trouver qui appelle des fonctions que vous ne voulez pas appeler.

Dans la question initiale, il y avait une sous-question sur l'inclusion des seules fonctions pertinentes. gcc inclura toutes les fonctions dans chaque fichier d'objet utilisé. En d'autres termes, si vous avez un fichier objet contenant 10 fonctions, celles-ci sont incluses dans votre exécutable, même si l'une d'elles est appelée.

Les bibliothèques standard (par exemple, libc) diviseront les fonctions en plusieurs fichiers d’objets distincts, qui seront ensuite archivés. L'exécutable est alors lié à l'archive. En se scindant en plusieurs fichiers objets, l'éditeur de liens est capable d'inclure uniquement les fonctions réellement appelées. (cela suppose que vous liez statiquement)

Il n'y a aucune raison pour que vous ne puissiez pas faire le même tour. Bien sûr, vous pouvez dire que si les fonctions ne sont pas appelées, vous pouvez probablement les supprimer vous-même.

Si vous établissez une liaison statique avec d'autres bibliothèques, vous pouvez également exécuter les outils énumérés ci-dessus pour vous assurer qu'elles respectent les mêmes règles.

Autres conseils

Une autre optimisation qui pourrait vous faire économiser du travail est -ffunction-sections, -Wl, - gc-sections, en supposant que vous utilisez GCC. Cela dit, une bonne chaîne d’outils n’aura pas besoin d’être dite.

Explication: GNU ld relie des sections et GCC émet une section par unité de traduction, sauf indication contraire de votre part. Mais en C ++, les nœuds du graphe de dépendance sont des objets et des fonctions.

Juste pour vérifier et documenter pour référence future, mais utilisez-vous les instructions Thumb? Ce sont des versions 16 bits des instructions normales. Parfois, vous aurez peut-être besoin de 2 instructions 16 bits pour ne pas économiser 50% sur l'espace de code.

Un bon éditeur de liens ne devrait prendre que les fonctions nécessaires. Cependant, vous aurez peut-être besoin du compilateur & amp; linke settings pour intégrer les fonctions aux liens individuels.

Sur les projets profondément intégrés, j'essaie toujours d'éviter d'utiliser des fonctions de bibliothèque standard. Même des fonctions simples comme "strtol ()" sauter la taille binaire. Si possible, évitez simplement ces appels.

Dans la plupart des projets profondément intégrés, vous n’avez pas besoin de fonctions "printf ()" polyvalentes. ou allocation de mémoire dynamique (de nombreux contrôleurs disposent de 32 ko ou moins de RAM).

Au lieu d'utiliser simplement "printf () " J'utilise un très simple "printf ()" personnalisé, cette fonction ne peut imprimer que des nombres au format hexadécimal ou décimal, pas plus. La plupart des structures de données sont préallouées au moment de la compilation.

Ok, donc au final, je viens de réduire le projet à sa forme la plus simple, puis d’ajouter lentement les fichiers un à un jusqu’à ce que la fonction que je voulais supprimer apparaisse dans le fichier 'readelf'. Puis, quand j’ai eu le fichier, j’ai tout commenté et j’ajoute lentement des choses jusqu’à ce que la fonction réapparaisse. Alors à la fin, j’ai trouvé comment l’appeler et enlevé tous ces appels ... Maintenant, ça marche comme on le souhaite ... doux!

Doit être un meilleur moyen de le faire cependant.

Andrew EdgeCombe a une excellente liste, mais si vous voulez vraiment supprimer chaque dernier octet, sstrip est un bon outil qui ne figure pas dans la liste et qui permet de gagner quelques kilos en plus.

Par exemple, lorsqu'il est exécuté sur la bande elle-même, cela peut réduire d'environ 2 Ko .

Extrait d'un ancien fichier README (voir les commentaires en haut de ce fichier source indirect):

  

sstrip est un petit utilitaire qui supprime le contenu à la fin d’un processus.   Fichier ELF ne faisant pas partie de l'image mémoire du programme.

     

La plupart des exécutables ELF sont construits avec une table d’en-tête de programme et une   table d'en-tête de section. Cependant, seul le premier est requis pour   pour que le système d'exploitation charge, relie et exécute un programme. sstrip tente de   extraire l'en-tête ELF, la table des en-têtes de programme et son contenu,   en laissant tout le reste dans le seau. Il ne peut enlever que des parties de   le fichier qui se produit à la fin, après les pièces à sauvegarder. cependant,   cela inclut presque toujours la table d'en-tête de section, et parfois   quelques sections aléatoires qui ne sont pas utilisées lors de l'exécution d'un programme.

Notez qu'en raison de certaines informations qu'il supprime, un exécutable sstrip'd est rumeur d'avoir des problèmes avec certains outils. Ceci est davantage discuté dans les commentaires de la source.

Aussi ... pour une lecture amusante / folle sur la création du plus petit exécutable possible, cet article mérite une lecture.

Pour répondre à ce besoin spécifique:

  

& # 8226; Je souhaite supprimer ces fonctions (si possible) mais je ne trouve pas ce qui est   en les appelant !! Pourrait être appelé depuis n'importe quel nombre de fonctions de bibliothèque I   devinez.

Si vous souhaitez analyser votre base de code pour savoir qui appelle quoi, par qui une fonction donnée est appelée, etc., il existe un outil formidable appelé "Comprendre C". fourni par SciTools.

https://scitools.com/

Je l'ai utilisé très souvent dans le passé pour effectuer une analyse de code statique. Cela peut vraiment aider à déterminer l’arbre de dépendance de la bibliothèque. Cela permet, entre autres, de parcourir facilement l’arbre des appels.

Ils fournissent une évaluation limitée dans le temps, vous devez donc acheter une licence.

Vous pourriez envisager quelque chose comme la la compression des exécutables .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top