Hallo,
ich habe ein mit avr-g++ kompiliertes Programm, welches aus einem
globalen Objekt besteht. Dieses Objekt enthält rekursiv verschaltet
wiederum viele weitere Objekte. In der main-Funktion wird in eine
Methode dieses globalen Objektes gesprungen und so das Programm
gestartet.
Nun landet dieses globale Objekt mit all seinen Membern in der
bss-Sektion hinter den statischen Variablen. Mit Hilfe von avr-objdump
-D bekomme ich auch Startadresse heraus, bei der das globale Objekt in
der bss-Sektion beginnt.
Nun möchte ich gern eine Layout-Übersicht über den gesamten Rest der
bss-Sektion bekommen. Die einzige Variante, die mir dazu einfallen
würde, wäre, das Gesamtheader-File herzunehmen, zu parsen und alle
Offsets der Membervariablen auf deren Namen abzubilden. Dazu müsste ich
natürlich auch die Größen aller Klassen bestimmen, also sizeof(). Daraus
würden sich dann die Adressen zur Laufzeit berechnen lassen.
Hat jemand einen Tipp für mich, ob es für so etwas Werkzeuge gibt? Mein
KnowHow ist für solch einen Parser nicht ausreichend. Welche
Unterstützung kann mir gcc da bieten?
Vielen Dank und
Herzliche Grüße
Richard
Danke, aber das Mapfile (wenn du die Memorymap des Linkers meinst),
enthält leider nicht die Informationen, die ich benötige.
Ich benötige eine Übersicht über die Offsets der einzelnen Member in
allen Klassen.
Das ganze ist tatsächlich für Debugging-Zwecke gedacht. Wenn ich die
Adressen aller global angelegten Objekte kenne, kann ich von außen zum
Beispiel zur Laufzeit einzelne Methoden anstoßen und schauen, was
passiert.
Richard
Nicht ganz das, was Du suchst, aber das folgende Skript gibt alle
Symbole, sortiert nach ihren Adressen, aus. Mit einem Argument
(Variablenname) gibt es die Umgebung dieser Variablen aus.
Du musst folgene Zeile ändern. Angenommen, Dein Object-File heißt
pgm.elf:
EDIT: Es läuft nur mit der Bash -- also das, was ich oben zu #!/bin/bash
geschrieben habe, gilt nicht. Ist keine Bash vorhanden, kannst Du
eventuell etwas aus dem Gerüst übernehmen.
Und noch was, was mir aufgefallen ist: zwischen ${BASH_REMATCH[1]} und
${BASH_REMATCH[2]} ist genau 1 Space und 1 Tab. Den Tab scheint die
Forensoftware trotz pre../pre zu expandieren.
A. K. schrieb:> Evtl. das Debugging-Format des erzeugten Binaries analysieren. Da steht> sowas drin.
Für C-Code gibt es pstruct, das ist bei Perl mit dabei (als Variante von
c2ph, womit zu C-Headern automatisch Perl-Module generiert werden
können), damit kann aus dem generierten Assemblercode das Layout einer
struct extrahiert werden.
Erste Zahlen-Spalte ist der Offset, zweite die Grösse des Feldes.
Leider kommt das Tool derzeit mit C++-Debuginformationen nicht klar
(auch nicht für eine simple struct, wenn g++ verwendet wird), aber
vielleicht kann der Code als Ausgangspunkt verwendet werden.
Andreas
@mizch:
danke erst einmal. Dein Script läuft unter Cygwin, aber ich kann nicht
erkennen, was es anderes ausgibt, als eine Auswahl der Symbole nebst
ihrer Größe und Ladeadresse die ich auch mit "avr-objdump -t" oder über
die Memory-Map des Linkers herausbekommen würde.
@aferber:
Ja, so etwas wie pstruct bräuchte ich, dass auch mit C++ umgehen kann.
Ich habe gerade mal ddd ausprobiert. Damit kann ich mir immerhin schon
einmal meine globale Systemvariable mit allen Elementen als grafischen
Baum anschauen. Allerdings gibt es mir keine Informationen über die
einzelnen Größen/Offsets der Variablen und überhaupt bekomme ich diesen
Baum nur als Bild aus ddd exportiert.
Ich habe das ELF mal in den gdb geladen. Mit Aufrufen wie "print
&globalesObjekt.member.tiefer.undnochTiefer" kann ich mir alle Adressen
von beliebigen Membern anzeigen lassen. Jetzt möchte ich das ganze aber
umgekehrt machen. Das heißt: Ich möchte eine Adresse eingeben und eine
Variable zurück bekommen. Dafür konnte ich aber (noch) keinen Befehl
finden.
rw schrieb:> Das heißt: Ich möchte eine Adresse eingeben und eine> Variable zurück bekommen. Dafür konnte ich aber (noch) keinen Befehl> finden.
1
(gdb) info symbol 0x0804957b
2
test_var + 11 in section .bss
Allerdings erhältst du so keine Informationen darüber, welchen Member du
"getroffen" hast, nur den nackten Offset in die Variable. Um die
komplette Struct anschliessend auszugeben reicht es aber natürlich.
Funktioniert natürlich nur mit statischen Variablen (static storage
duration, nicht static linkage).
Andreas
Japp. Das habe ich auch gesehen, aber das nützt mir nicht viel.
Um zum Ziel zu kommen, habe ich es jetzt folgendermaßen gemacht:
1
print meinGlobalesObjekt
gibt mir einen String zurück, welcher den gesamten rekursiven Aufbau von
meinGlobalesObjekt mit allen Membern nebst ihren Typen enthält. Da diese
Ausgabe wohlstrukturiert ist, kann mir ein kleines Script alle
Variablennamen (eines bestimmten Typs) zusammenbauen.
Dieser Liste kann ich dann mit
1
print &variable
die jeweiligen Adressen zuordnen und sie so weiterverarbeiten.
Vielen Dank für's Mitdenken.
Richard
Eine weitere Möglichkeit ist
avr-readelf -wi test.elf
damit wird die komplette Symboltabelle ausgegeben, aus der sich alle
Informationen zusammenbauen lassen.