2013-08-25 19 views
5

Ich muss eine Funktion in C aufrufen, nur wissen, Adresse, und keine Informationen auf es Prototyp (ich kann es nicht auf einen C-Funktionszeiger werfen).Call-C-Adresse als Funktion ohne Prototyp

Die Information, die ich über diese Funktion habe, ist die Adresse.

Ich kenne auch die Parameter, die ich übergeben möchte (Dank eines void-Zeigers) und die Größe des arguments array (zugegriffen durch den void-Zeiger).

Ich möchte auch die C-Aufruf Konvention einhalten. Für x86-Version, ich ziemlich viel wissen, wie es geht (zuteilen Sie den Platz auf dem Stapel, kopieren Sie die Parameter diesen Raum und schließlich rufen Sie die Funktion).

Das Problem ist mit x64 Konvention (Linux für jetzt), wo die Parameter durch die Register übergeben werden. Ich habe keine Ahnung von der Größe der einzelnen Parameter zu füllen richtig registriert, ich kenne nur die Größe des Parameter-Array.

Auch ich möchte nicht auf gcc abhängen, so dass ich __builtin_apply nicht verwenden kann, scheint nicht Standard zu sein und auch ziemlich dunkel sein.

Ich möchte meinen eigenen Code schreiben, um Multi-Compiler und auch interessante Dinge zu lernen.

Also im Grunde die Funktion Ich möchte als den gleichen Prototyp wie __builtin_apply schreiben, das ist:

void *call_ptr(void (*fun)(), void *params, size_t size); 

Ich mag auch den Code in C (dank asm inline) zu schreiben oder reinem x64 asm .

Also gibt es eine Möglichkeit, dies richtig und in Bezug auf die rufenden Konvention zu tun? Oder ist das mit der x64-Konvention unmöglich, ohne genau den Prototyp der Funktion zu nennen?

+4

Werfen Sie einen Blick auf [libffi] (http://sourceware.org/libffi/). – tangrs

+0

Dies könnte eine gute Alternative sein, aber das Problem mit libffi ist, dass es den Typ jedes Parameters und den Rückgabetyp der Funktion kennen muss. Ich möchte vermeiden, diese Informationen zu sammeln, um Zeitverlust zu vermeiden. Ist das mit x64-Architektur möglich? – Zerkan

+1

@Zerkan nein es ist nicht, Sie brauchen die Arten der Parameter, es gibt keine Magie, die Parameter in den richtigen Registern oder Stapelplatz platzieren können, wenn eine Funktion ohne die Argumente zu wissen – nos

Antwort

0

denke ich, alle Ihre Entscheidung nicht Multi-Compiler unterstützt werden, da der Mechanismus des Führens Argumente Funktion (Register, deren Reihenfolge, Stapel, Speicher) - es Feature Compiler Abhängigkeit ist ...

+3

_ "Es ist Compiler Abhängigkeitsfunktion" _. Zum Glück ist es nicht. Zumindest nicht, wenn der Compiler sich an die [ABI] (http://en.wikipedia.org/wiki/Application_binary_interface) des Ziel-BS hält. – Michael

+0

Ja, natürlich unterstützt es einige externe Low-Level-Schnittstellen. Aber die Unterstützung von ABI ist auch Compiler-abhängige Funktion =) Nur eine Sache, die jeder Compiler genau unterstützen sollte - Language Standart –

2

Besonders für x64-Aufrufkonvention unter Linux wird dies überhaupt nicht funktionieren.

Der Grund ist die sehr komplizierte Aufrufkonvention.

Einige Beispiele:

void funcA(float64 x); 
void funcB(int64 x); 

In diesen beiden Fällen ist der Wert „x“ wird unterschiedlich auf die Funktionen übergeben, weil Gleitkomma- und Ganzzahl sind in verschiedenen Registern zu den Funktionen übergeben.

void funcC(float64 x,int64 y); 
void funcD(int64 y,float64 x); 

In diesen beiden Fällen sind die Argumente "x" und "y" in anderer Reihenfolge. Sie werden jedoch auf die gleiche Weise an die Funktion übergeben (beide Funktionen verwenden dasselbe Register für "x" und dasselbe Register für "y").

Fazit: Um eine Funktion zu erstellen, die das tut, was Sie wollen, müssten Sie eine Zeichenfolge, die die Argumenttypen jedes Arguments enthält, an die Assembler-Funktion übergeben. Die Anzahl/Größe der Argumente ist definitiv nicht genug.Allerdings wäre es definitiv möglich - solange es nur unter Linux funktionieren muss.

Verwandte Themen