Wie bekomme ich einen Zeiger auf einen binären Abschnitt in MSVC?

8

Ich schreibe einen Code, der einige Datenstrukturen in einem speziell benannten binären Abschnitt speichert. Dies sind alle Instanzen derselben Struktur, die über viele C-Dateien verstreut sind und nicht innerhalb des Bereichs voneinander liegen. Indem ich sie alle in den genannten Abschnitt platziere, kann ich über alle hinweg iterieren.

In GCC verwende ich _ Attribut _ ((Abschnitt (...)) plus einige speziell benannte externe Zeiger, die vom Linker magisch ausgefüllt werden. Hier ein triviales Beispiel:

%Vor%

Ich versuche herauszufinden, wie man das in MSVC macht, aber ich zeichne ein Leerzeichen. Ich sehe aus der Compiler-Dokumentation, dass ich den Abschnitt mit __pragma (Abschnitt (...)) deklarieren kann und deklarieren Daten in diesem Abschnitt mit __declspec (allocate (...)), aber ich kann nicht sehen, wie ich bekommen kann ein Zeiger auf den Anfang und das Ende des Abschnitts zur Laufzeit.

Ich habe einige Beispiele im Web gesehen, die mit _ attribut _ ((Konstruktor)) in MSVC zu tun haben, aber es scheint so zu sein, als würde es CRT-spezifisch hacken und keine generelle Methode, einen Zeiger zu bekommen zum Anfang / Ende eines Abschnitts. Hat jemand irgendwelche Ideen?

    
Andrew B. 27.09.2010, 21:31
quelle

3 Antworten

4

Es gibt auch eine Möglichkeit, dies ohne Verwendung einer Assembly-Datei zu tun.

%Vor%

Die erste 3 Zeile definiert die Segmente. Diese definieren die Abschnitte und ersetzen die Montagedatei. Im Gegensatz zum Pragma data_seg erstellt das Abschnittspragma nur den Abschnitt. Die Zeilen __declspec (allocate ()) weisen den Compiler an, das Element in diesem Segment zu platzieren.

Von der Microsoft-Seite: Die Reihenfolge hier ist wichtig. Abschnittsnamen müssen maximal 8 Zeichen lang sein. Die Abschnitte mit dem gleichen Namen vor dem $ werden in einem Abschnitt zusammengeführt. Die Reihenfolge, in der sie zusammengeführt werden, wird durch Sortieren der Zeichen nach dem $ bestimmt.

Ein weiterer wichtiger Punkt, den Sie sich merken sollten, sind Abschnitte, die zu 256 Bytes aufgefüllt sind. Die START- und END-Zeiger stehen NICHT direkt davor und danach, wie Sie es erwarten würden.

Wenn Sie Ihre Tabelle als Zeiger auf Funktionen oder andere NULL-Werte einrichten, sollte es leicht möglich sein, NULL-Einträge vor und hinter der Tabelle zu überspringen, aufgrund des Abschnitts padding

Weitere Informationen finden Sie auf dieser msdn-Seite .

    
shimpossible 09.02.2013, 00:57
quelle
3

Zunächst müssen Sie eine ASM-Datei erstellen, die alle Abschnitte enthält, die Sie interessieren (z. B. section.asm):

%Vor%

Als nächstes können Sie in Ihrem Code Folgendes verwenden:

%Vor%

Dies ergibt eine solche MAP-Datei:

%Vor%

Wie Sie sehen können, wird der Abschnitt mit dem Namen .init$u zwischen .init$a und .init$z eingefügt. Dies gibt Ihnen die Möglichkeit, den Zeiger über __InitSectionStart symbol auf den Anfang der Daten zu bringen bis zum Ende der Daten über __InitSectionEnd symbol.

    
Ilya Matveychikov 07.05.2011 19:01
quelle
0

Ich habe hier ein bisschen experimentiert und versucht, die Version ohne eine Assemblydatei zu implementieren, hatte jedoch mit der zufälligen Anzahl von Füllbytes zwischen den Abschnitten zu kämpfen, was es fast unmöglich macht, den Start des .init $ u-Abschnitts zu finden Teil, wenn Inhalt nicht nur Zeiger oder andere einfache Elemente ist, die auf NULL oder ein anderes bekanntes Muster überprüft werden könnten. Ob Padding eingefügt wird, scheint mit der Verwendung der Debug-Option Zi zu korrelieren. Wenn angegeben, wird ein Padding eingefügt, ohne dass alle Abschnitte genau so angezeigt werden, wie man sie haben möchte.

    
don 03.07.2013 00:07
quelle

Tags und Links