Frage

Ich bin Herstellung eine Hex-Datei auf einem ARM-Prozessor laufen zu lassen, die ich unter 32K behalten will. Es ist derzeit viel größer als das, und ich fragte mich, ob jemand könnte einige Ratschläge, was ist der beste Ansatz für schlanke it down?

Hier ist, was ich bisher getan

  1. Also habe ich laufen ‚Größe‘ auf sie, um zu bestimmen, wie groß die Hex-Datei ist.
  2. Dann wieder ‚Größe‘, um zu sehen, wie groß jede der Objektdateien ist, dass Link, um die Hex-Dateien zu erstellen. Es scheint, die Mehrheit der Größe von externen Bibliotheken kommt.
  3. Dann habe ich ‚readelf‘ zu sehen, welche Funktionen die meisten Speicher in Anspruch nehmen.
  4. Ich suchte durch den Code zu sehen, ob ich Anrufe auf diese Funktionen beseitigen könnte.

Hier ist, wo ich nicht weiterkommen, gibt es einige Funktionen, die ich nicht nennen direkt (zB _vfprintf) und ich kann nicht finden, was es nennt, so kann ich den Anruf entfernen (wie ich glaube, ich brauche es nicht).

Also, was sind die nächsten Schritte?

Antwort auf Antwort:

  • Wie kann ich sehen, dass es Funktionen aufgerufen werden, die viel Speicherplatz in Anspruch nehmen. Ich kann jedoch nicht finden, was sie ruft.
  • Ich möchte diese Funktionen (wenn möglich) auszulassen, aber ich kann nicht finden, was sie ruft! Könnte aus einer beliebigen Anzahl von Bibliotheksfunktionen aufgerufen werden, denke ich.
  • Der Linker wie gewünscht funktioniert, wie ich glaube, es enthält nur die entsprechenden Bibliotheksdateien. Wie Sie wissen, ob nur die relevanten Funktionen enthalten werden? Können Sie eine Flagge oder etwas für das Set?
  • Ich bin mit GCC
War es hilfreich?

Lösung

Allgemeine Liste:

  • Stellen Sie sicher, dass Sie die Compiler und Linker Debug-Optionen deaktiviert
  • haben
  • Übersetzen und Link mit allen Größen Optionen eingeschaltet (-Os in gcc)
  • Ausführen strip auf die ausführbare Datei
  • eine Map-Datei generieren und Ihre Funktion Größen überprüfen. Sie können entweder erhalten Sie Ihre Linker Ihre Map-Datei (-M bei der Verwendung von ld) zu erzeugen, oder Sie können auf die endgültige ausführbare Datei verwenden objdump (beachten Sie, dass dies nur auf einer unstripped ausführbare funktionieren!) Dies wird nicht wirklich das Problem beheben, aber es wird Ihnen der schlimmsten Übeltäter kennen.
  • Verwenden Sie nm die Symbole zu untersuchen, die von jedem Ihrer Objektdateien aufgerufen werden. Dies sollte bei der Suche nach, wer anruft Funktionen helfen, die Sie nicht genannt werden sollen.

In der ursprünglichen Frage war eine Unterfrage über nur relevante Funktionen einschließlich. gcc enthält alle Funktionen in jeder Objektdatei, die verwendet wird. Um dies anders auszudrücken, wenn Sie eine Objektdatei haben, die 10 Funktionen enthalten, wird alle 10 Funktionen sind in der ausführbaren Datei enthält, selbst wenn man 1 tatsächlich genannt.

Die Standardbibliotheken (zB. Libc) werden Funktionen in viele separate Objektdateien aufgeteilt, die dann archiviert werden. Die ausführbare Datei wird dann gegen das Archiv verknüpft. Durch die Aufteilung in viele Objektdateien der Linker nur die Funktionen enthalten ist in der Lage, die tatsächlich aufgerufen werden. (Dies setzt voraus, dass Sie statisch verknüpfen)

Es gibt keinen Grund, warum Sie nicht den gleichen Trick tun können. Natürlich könnte man argumentieren, dass, wenn die Funktionen der nicht genannt werden, können Sie wahrscheinlich sie selbst entfernen.

Wenn Sie statisch sind Verknüpfung mit anderen Bibliotheken können Sie die Werkzeuge laufen sie auch oben aufgeführten über, um sicherzustellen, dass sie folgende ähnliche Regeln.

Andere Tipps

Eine weitere Optimierung, die Sie vielleicht sparen arbeiten ist -ffunction Schnitte, -Wl, - gc-Abschnitte, vorausgesetzt, Sie verwenden GCC. Eine gute Werkzeugkette wird nicht müssen gesagt, dass, obwohl.

Erläuterung: GNU ld Links Abschnitte und GCC emittiert einen Abschnitt pro Übersetzungseinheit, wenn Sie es anders sagen. Aber in C ++, die Knoten in den dependecy Graphen sind Objekte und Funktionen.

Just nochmals zu überprüfen und zu dokumentieren für die Zukunft, aber verwenden Sie Thumb Anweisungen? Sie sind 16-Bit-Versionen der normalen Anweisungen. Manchmal müssen Sie möglicherweise zwei 16-Bit-Befehle, so dass es nicht mehr als 50% im Coderaum speichern.

Ein anständiger Linker sollte nehmen nur die Funktionen benötigt. Allerdings könnten Sie Compiler & linke Einstellungen benötigen Funktionen für die individuelle Verknüpfung zu verpacken.

Auf tief eingebettete Projekten versuche ich immer zu vermeiden, keine Standard-Bibliothek Funktionen. Selbst einfache Funktionen wie „strtol ()“ blasen die binäre Größe auf. Wenn möglich, einfach nur diese Anrufe vermeiden.

In den meisten tief eingebettete Projekte, die Sie brauchen nicht zu einem vielseitig „printf ()“ oder dynamische Speicherzuweisung (viele Controller haben 32kb oder weniger RAM).

Statt nur „printf ()“ mit Ich benutze eine sehr einfache benutzerdefinierte „printf ()“ Diese Funktion kann nur Druck Zahlen in Hexadezimal oder Dezimal-Format nicht mehr. Die meisten Datenstrukturen werden bei der Kompilierung vorbelegt.

Ok, so am Ende habe ich reduziert nur das Projekt der einfachsten Form, dann langsam Dateien nacheinander, bis die Funktion, die ich wollte in der ‚readelf‘ Datei erschien zu entfernen. Dann, wenn ich die Datei hatte, kommentierte ich alles aus und langsam Dinge wieder hinzufügen, bis die Funktion wieder aufgetaucht. Also am Ende fand ich heraus, was es genannt und entfernt alle diese Anrufe ... Jetzt funktioniert es wie gewünscht ... süß!

muss einen besseren Weg, es zu tun though.

Andrew Edgecombe hat eine große Liste, aber wenn Sie wirklich wollen, jeden letzten Byte kratzen, sstrip ist ein gutes Werkzeug, das aus der Liste fehlt, und und kann noch ein paar kB abrasieren.

Wenn zum Beispiel auf strip laufen selbst, kann es abrasieren ~ 2kB .

Von einem alten Readme (siehe die Kommentare an der Spitze der diese indirekte Quelldatei):

  

sstrip ist ein kleines Programm, das den Inhalt am Ende eines entfernt   ELF-Datei, die nicht Teil des Speicherbildes des Programms ist.

     

Die meisten ELF-Executables sind sowohl mit einer Programmkopftabelle aufgebaut und einem   Abschnitt Kopftabelle. Allerdings wird nur die ehemalige erforderlich, um   für das Betriebssystem, Link zu laden und ein Programm ausführen. sstrip versucht   extrahieren Sie die ELF-Header, die Programmkopftabelle und sein Inhalt,   alles andere in der Bit-Eimer zu verlassen. Es kann nur entfernen Teile   die Datei, die am Ende, nachdem die Teile auftreten zu speichern. Jedoch,   Dazu gehören fast immer den Abschnitt Kopftabelle und gelegentlich   ein paar zufälligen Abschnitte, die nicht verwendet werden, wenn ein Programm ausgeführt wird.

, dass auf einige der Informationen aufgrund Beachten Sie, dass es entfernt, eine sstrip'd ausführbar ist dieser Artikel ist lesenswert.

Diese spezifische Notwendigkeit zu beantworten:

  

• Ich möchte diese Funktionen (wenn möglich) auszulassen, aber ich kann nicht finden, was   nannte sie !! Könnte aus einer beliebigen Anzahl von Bibliotheksfunktionen aufgerufen werden I   erraten.

Wenn Sie Ihren Code-Basis analysieren wollen zu sehen, wer anruft, was, von wem eine bestimmte Funktion wie das genannt und Dinge wird, gibt es ein großes Werkzeug da draußen genannt „Verstehen C“ von SciTools zur Verfügung gestellt.

https://scitools.com/

Ich habe es sehr oft in der Vergangenheit verwendet, um statische Code-Analyse durchzuführen. Es kann wirklich Bibliothek Abhängigkeitsbaum bestimmen helfen. Es erlaubt auf einfache Weise unter anderem nach oben und unten dem anrufenden Baum zu sehen.

Sie bieten eine begrenzte Zeitauswertung, dann müssen Sie eine Lizenz erwerben.

Sie auf etwas aussehen könnte ausführbare Kompression .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top