Forum: Compiler & IDEs Tabellen aus Konstanten in Programm linken?


von Joern (Gast)


Lesenswert?

Moin,

in einem Programm moechte ich zwei relativ grosse binaere Tabellen 
(~300KByte pro Tabelle) verwenden und suche nach einer eleganten 
Moeglichkeit diese im Code unterzubringen. Aufgrund der Groesse wuerde 
ich sie ungern in ASCII-Daten umwandeln und als Assemblerdatei 
hinzulinken. Gibt es irgendeine Moeglichkeit, Binaerdateien mit Daten 
direkt in ein Programm zu linken? Und wie gelingt dann elegant eine 
Benennung der Bereiche als Variable? (Bislang ist mir nur eingefallen, 
die an eine feste Adresse zu linken und einen Pointer darauf zu setzen.)

Gruss, Joern

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

GCC?
Dann mit objcopy aus dem Binary eine .o Datei machen:
1
$ dd if=/dev/random of=test.bin bs=1024 count=1024
2
$ objcopy -I binary -O elf32-little test.bin test.o
3
$ objdump.exe -t test.o 
4
5
test.o:     file format elf32-little
6
7
SYMBOL TABLE:
8
00000000 l    d  .data  00000000 .data
9
00000000 g       .data  00000000 _binary_test_bin_start
10
00100000 g       .data  00000000 _binary_test_bin_end
11
00100000 g       *ABS*  00000000 _binary_test_bin_size

Das entstandene .o kannst du dann dazulinken und mittels der Symbole 
_binary_test_bin_* darauf zugreifen:
1
uint8_t* p;
2
3
p = &_binary_test_bin_start;
4
5
while(p != &_binary_test_bin_end)
6
{
7
  doSomething(*p++);
8
}

Mittels --redefine-sym kannst du mit objcopy auch noch die Symbolnamen 
ändern.

Matthias

von Joern (Gast)


Lesenswert?

Danke erstmal, Dein Tipp hat anfaenglich tatsaechlich geholfen, nur 
stehe ich damit nun vor einem neuen Problem. Leider habe ich gerade die 
Ausgabe des Linkers nicht vorliegen, aber sie ist sinngemaess, dass das 
Alignment der Variable in test.o (in Deinem Beispiel) 1 ist und damit 
kleiner als in main.o (wo ich den Pointer _binary_test_bin_start 
verwende) wo es 4 ist. Wie bekomme ich das behoben? Zusaetzlich ist die 
architecture der datei test. o unbekannt und es ist mir auch leider 
nicht gelungen die architecture mit der -B - Option in objcopy zu 
aendern. Das beides sind nur Warnungen und ich wuerde mich nicht darum 
kuemmern, stuerzte das Programm nicht immer ab, wenn ich den Pointer zu 
verwenden versuche. (Alignment-Fehler? Eigentlich sollten die Adressen 
trotzdem zum 4Byte Alignment taugen)

Gruss, Joern

von Joern (Gast)


Lesenswert?

Wollte noch mal den genauen Wortlaut der Warnmeldung nachtragen:
1
bfin-elf-ld: Warning: alignment 1 of symbol `_undistort_left_start' in undistort
2
_left.o is smaller than 4 in main.o
3
4
bfin-elf-ld: warning: unknown architecture of input file `undistort_left.o' is i
5
ncompatible with bfin output

Gruss, Joern

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

definiere bitte mal deinen Compiler etwas exakter. Es scheint ja ein GCC 
zu sein aber für welche Architektur? Wenn ich raten müßte würde ich auf 
ARM tippen.

Wie greifst du auf die Daten zu? Sourcecode! Ich hab diese Methode schon 
erfolgreich bei Architekturen mit striktem Alignment eingesetzt.

Matthias

von Joern (Gast)


Lesenswert?

Wahr, ein paar Worte zur Architektur waeren wahrscheinlich nicht 
verkehrt gewesen. Du liegst aber falsch, ich verwende einen Blackfin.

Die Object-Datei erzeuge ich wie folgt aus einer Datei (die einen 
Integer-String enthaelt):
1
bfin-elf-objcopy -I binary -O elf32-little --readonly-text --redefine-syms symbols.txt undistort_right.dat undistort_right.o

In geistiger Umnachtung habe ich bislang darauf (nach Umbenennung) wie 
folgt zugegriffen:
1
unsigned int * undistort_left_start;
2
unsigned int * undistort_right_start;

Das habe ich mittlerweile in
1
extern unsigned int undistort_left_start[];
2
extern unsigned int undistort_right_start[];

geaendert, was zumindest den ersten Fehler beim Kompilieren behebt. 
Ausprobieren konnte ich leider noch nicht ob es auch den Fehler beim 
Ausfuehren behebt, weil ich mein Board gerade nicht da habe. Bin da aber 
ganz guter Hoffnung.
Bleibt nur noch der zweite Fehler, von dem ich fuerchte, er koenne 
ziemlich Compiler-spezifisch sein.
Vielleicht hat aber dennoch jemand ne Idee, waere ne eins.

Gruss, Joern

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

versuch mal
1
bfin-elf-objcopy -I binary -O elf32-bfin --readonly-text --redefine-syms symbols.txt undistort_right.dat undistort_right.o

Du kannst auch mal schauen was deine anderen Objekte (die aus .c 
erstellten) für ein Format haben:
1
bfin-elf-objdump -a test.o

Daraus kannst du dann evtl. das Target für den objcopy Aufruf ableiten.

Matthias

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.