2014-06-23 21 views
6

Für Unit-Tests eines eingebetteten Projekts auf dem Host habe ich begonnen, Funktionszeiger zu verwenden, um zur Laufzeit zwischen der "echten" Implementierung einer Funktion und einem Mock wechseln zu können. So sieht meine Funktion ‚foo‘, wie dies in der C-Datei:gcc: Können Sie Funktionszeiger auf einen anderen Abschnitt (nicht .data) setzen?

// the 'real' implementation of the function to be used during runtime 
void fooImplementation () 
{ 
    /* ... */ 
} 
// the function pointer, initialized to the 'real' implementation 
void (*foo) () = fooImplementation; 

Es stellte sich heraus, dass der Zielprozessor (Blackfin) eine Ausnahme erzeugt, da der Funktionszeiger in dem internen L1-Datenspeicher befindet sich die ist nicht erlaubt, Code zu tragen, sondern nur Daten.

Eine Lösung, die funktioniert, ist ein Attribut für jeden Funktionszeiger zuzuweisen, damit es in einem anderen Abschnitt versetzt wird, die in L1-Datenspeicher, beispielsweise befindet sich nicht:

void (*foo) () __attribute__ ((section(".ext_mem"))) = fooImplementation; 

Aber das macht den Code ein ein wenig schwer zu lesen und ist fehleranfällig (wenn Sie vergessen, das Attribut zuzuweisen, werden Komponententests problemlos ausgeführt, aber der Code generiert die Ausnahme, sobald die Funktion für das Ziel aufgerufen wird).

Also meine Frage ist, ob es eine Möglichkeit gibt zu sagen, gcc alle Funktionszeiger standardmäßig auf einen anderen Abschnitt zu setzen.

Antwort

1

In gcc gibt es keine solche Option, um alle Funktionszeiger standardmäßig in einem bestimmten Abschnitt zu platzieren. Es sei denn, Sie schreiben die Compiler- und Linker-Regeln um.

Sie müssen das Schlüsselwort __attribute__ verwenden, wie Sie in der Frage erwähnt haben. Wenn der Code-Komplex sieht, könnte man ein Makro um es zu erstellen:

#define SPECIAL_FOO(x) void (*x) () __attribute__ ((section(".ext_mem"))) 

und es dann wie folgt verwenden:

SPECIAL_FOO(foo) = fooImplementation; 

Es gibt jedoch eine andere Art und Weise, auch. Sie können diesen SO-Thread sehen, um mehr über das Erstellen von benutzerdefinierten Linker-Scripts zur Erfüllung Ihrer Aufgabe zu erfahren: Forcing certain compiler-generated variables into specific ELF sections (with gcc)