Forum: Mikrocontroller und Digitale Elektronik Ram und Rom größe aus Elf executable auslesen


von Lukas H. (lukas_hoenn)


Lesenswert?

Hallo,

ich versuche aus einem .elf Executable die Startaddresse und Größe von 
Ram und Rom zu bestimmen.
Es handelt sich um einen dsPIC Controller mit der Bezeichnung 
"33EV128GM104", das parser Skript soll aber möglichst auch für diverse 
Arm Prozessoren nutzbar sein.
Die Toolchain besteht aus einer abewandelten Form des gcc, ist aber 
gefühlt zu 99% gcc.
Bei den Arm Prozessor legt der linker für beide Bereiche ein Segment im 
header der .elf an, sodass ich die gewünschten Informationen mit einem 
objdump erhalte. Beim dsPIC passiert dies leider nicht.

Lösungsidee 1:
Eine statische map erstellen um die sektionen des dsPIC .elf dem Ram und 
Rom zuzuweisen. Anschließend die niedrigste Adresse finden und alle 
sektionen des jeweiligen Bereiches aufaddieren. Dabei gehe ich davon 
aus, dass beide Bereiche nicht unterbrochen werden. Da der dsPIC jedoch 
eine sehr wilde Sektionsbenennung hat, wäre dieser Weg recht komplex.

Lösungsidee 2:
Per linker Skript ein leeres Symbol an den Start und Ende des jeweiligen 
Segmentes setzen und per objdump auslesen. Das wäre zumindest in der 
Theorie recht einfach, ich hab jedoch durch recherche und gcc Handbuch 
bisher leider keine Möglichkeit gefunden, die Symbole einzufügen.

Hat jemand eine weitere Idee oder kann mir etwas zu meinen bestehenden 
Ideen sagen?
Falls etwas an der Beschreibung unklar ist lasst es mich wissen, ich 
werde das so schnell wie möglich nachbesser.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lukas H. schrieb:
> Beim dsPIC passiert dies leider nicht.

Wie sieht denn die Ausgabe von <toolchain>-objdump -h vom ELF-File bei 
dsPIC aus?

von my2ct (Gast)


Lesenswert?

Lukas H. schrieb:
> ich versuche aus einem .elf Executable die Startaddresse und Größe von
> Ram und Rom zu bestimmen.

Was verstehst du unter "Ram"? In dem gewöhnlich als RAM bezeichneten 
Speicherbereich liegen gewöhnlich auch dynamische Variablen, Heap und 
Stack. Da ist wohl eine tiefgreifendere Programmanalyse nötig. Ein 
einfacher Blick in den .elf-File wird nicht reichen, um die (maximale) 
RAM-Belegung zu bestimmen.
ROM wirst du in kaum einem Prozessorchip mehr finden.
Die Zeiten sind vorbei ;-)

von Lukas H. (lukas_hoenn)


Lesenswert?

Jörg W. schrieb:
> Wie sieht denn die Ausgabe von <toolchain>-objdump -h vom ELF-File bei
> dsPIC aus?

Das spuckt mir eine wilde Liste von sections aus. Diese lassen sich 
durch analyse von Hand dem ram oder rom zuweisen, es ist aber schwierig 
ein Skript automatisiert entscheiden zu lassen.

my2ct schrieb:
> In dem gewöhnlich als RAM bezeichneten
> Speicherbereich liegen gewöhnlich auch dynamische Variablen, Heap und
> Stack

Im linker Skript wird aktuell zwischen Stack und sonstigem Ram 
unterschieden, wobei ich den Stack als Blackbox konstanter Größe 
betrachte. Es geht mir lediglich darum die effektive Größe des sonstigen 
Rams zu bestimmen.

my2ct schrieb:
> ROM wirst du in kaum einem Prozessorchip mehr finden.
Es handelt sich natürlich um Flash mit emuliertem EPROM :)

von M. Н. (Gast)


Lesenswert?

Ich weiß nicht, was es für ein Compiler es genau ist, aber bei einem GCC 
Derivat, wie du schreibst, sollte folgendes gehen:

<toolchain>-size <ELF-Datei>

Beispiel für einen ARM: arm-none-eabi-size my-project.elf

von Lukas H. (lukas_hoenn)


Lesenswert?

M. H. schrieb:
> Ich weiß nicht, was es für ein Compiler es genau ist, aber bei einem GCC
> Derivat, wie du schreibst, sollte folgendes gehen:
>
> <toolchain>-size <ELF-Datei>

Der Befehl gibt mir die Größe von Ram und Rom aus, damit ist etwas 
gewonnen. Leider ist es unmöglich damit die Startadresse zu bestimmen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lukas H. schrieb:
>> Wie sieht denn die Ausgabe von <toolchain>-objdump -h vom ELF-File bei
>> dsPIC aus?
>
> Das spuckt mir eine wilde Liste von sections aus.

Kannst du diese denn nicht hier mal posten?

von M. Н. (Gast)


Lesenswert?

Habe dir mal noch was rausgesucht. Vielleicht gefällt dir das besser :)
1
% arm-none-eabi-readelf -l test.elf
2
3
Elf file type is EXEC (Executable file)
4
Entry point 0x80026dd
5
There are 4 program headers, starting at offset 52
6
7
Program Headers:
8
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
9
  LOAD           0x010000 0x08000000 0x08000000 0x0286c 0x0286c R E 0x10000
10
  LOAD           0x020000 0x20000000 0x0800286c 0x0002c 0x0002c RW  0x10000
11
  LOAD           0x020030 0x20000030 0x08002898 0x00000 0x00040 RW  0x10000
12
  LOAD           0x020070 0x20000070 0x08002898 0x00000 0x02000 RW  0x10000
13
14
 Section to Segment mapping:
15
  Segment Sections...
16
   00     .isr_vector .text 
17
   01     .data 
18
   02     .bss 
19
   03     ._user_heap_stack

Mittels readelf -l kannst du die Sections und Adressen ausgeben lassen
Das ist ein Programm von mir auf einem STM32.

PhysAddr ist die Adresse, an der die Daten beim Programmieren geschriebn 
werden (Load Address) und VirtAddr ist die Adresse an der Das Programm 
die Daten verwendet (VMA), vereinfacht gesagt.

Bei mir sieht man da jetzt zum Beispiel, dass die Sections .isr-vector 
und .text (Programmcode) an die Adresse  0x08000000 geladen werden und 
0x0286c groß sind.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.