2016-07-11 19 views
2

ich die Verknüpfung von Binärdaten in meiner C-Programm für ARM Cortex-M mit GCC, wie folgt aus:Seltsames Verhalten, wenn sie mit GCC binären Blob Verknüpfung

arm-none-eabi-ld.exe -r -b binary -o html.o index.html 

mit den Daten arbeiten ich diese externen Variablen haben:

extern const unsigned char _binary_index_html_start; 
extern const unsigned char _binary_index_html_end; 
extern const uint32_t _binary_index_html_size; 

static const char* html = &_binary_index_html_start; 
static const size_t html_len = &_binary_index_html_size; 

Was ich nicht verstehe ist, warum muss ich die Adresse der _binary_index_html_size Variable erhalten, die Größe Wert zu haben?

Das würde bedeuten, dass die Speicheradresse (Zeiger) der Variablen _binary_index_html_size den Größenwert des Blobs in Byte darstellt. Wenn ich das debugge, scheint es richtig zu sein, aber für mich erscheint es als eine sehr seltsame Lösung, dies zu lösen.

Edit:
Ich denke, der Grund dafür sein kann: weil die Größe des Blobs nie größer als die native Datengröße sein kann (in meinem Fall 2^32), anstatt Raum verschwenden und Speicherung der Größe GCC erstellt nur eine Variable, die auf die Speicheradresse verweist, die die Größe des Blobs darstellt. Der Wert ist also völlig zufällig und hängt von anderem Code ab (ich habe das getestet). Dies scheint eine clevere Sache zu sein, da die Größe keinen Platz einnimmt und der Zeiger zur Kompilierzeit aufgelöst wird. Wenn man also die Größe nicht benötigt, wird kein Platz verschwendet.
Ich denke, ich werde stattdessen (&_binary_index_html_end) - (&_binary_index_html_start) verwenden, das scheint besser und wird von allen Compilern unterstützt.

+0

'statische const size_t html_len = & _binary_index_html_size;' sieht für mich wie ein Fehler aus. Wer sagt, dass du es brauchst? –

+0

Die Variable '_binary_index_html_size' enthält einige zufällige Daten, die bei der Neukompilierung geändert werden können. Aber die Adresse dieser Variablen ist genau die Größe des Blobs. –

+0

Dies ist eine clevere Methode, um Speicherplatz zu sparen, aber es ist nicht kompatibel mit Standard C. Wenn das Blob teilweise in Assembly geschrieben wurde, könnte es diese Methode verwenden. –

Antwort

1

Alle Symbole, mit denen Sie zu tun haben, sind Linker-Skript definierten Variablen und sie sind genau so zugegriffen, wie Sie es taten. Die Erklärung dafür ist sehr deutlich in der ld documentation gegeben.

Wenn ein Symbol in einer Hochsprache wie C deklariert wird, passieren zwei Dinge: . Der erste ist, dass der Compiler genügend Speicherplatz in des Programmspeichers reserviert, um den Wert des Symbols zu halten. Der zweite ist , dass der Compiler einen Eintrag in der Symboltabelle des Programms erstellt, der die Adresse des Symbols enthält. dh die Symboltabelle enthält die Adresse des Speicherblocks, der den Wert des Symbols enthält.

Und dann, etwas später im Dokument, können wir folgendes finden.

Linker Skripte Symboldeklarationen hingegen erstellen einen Eintrag in die Symboltabelle, aber weisen Sie ihnen keinen Speicher zu. Somit sind sie eine Adresse ohne Wert.

Dies bedeutet, dass die Adresse eines Linkers definierten Variablen in der Tat seinen tatsächlichen Wert ist, und das ist, warum Sie eine solche Adresse zu ergreifen, um den Wert im Zusammenhang mit dem Linker Symbol zu lesen.