LLVMCreateDisasm gibt NULL zurück

8

Ich versuche, einige Bytes mit LLVM C-Schnittstelle zu zerlegen.  % Co_de% gibt jedoch NULL zurück.

%Vor%

Ich bin auf x64 Linux. Ein Blick auf die Dokumentation scheint mir alles richtig zu machen.

%Vor%
  

Erstellen Sie einen Disassembler für TripleName. Die symbolische Disassemblierung wird unterstützt, indem ein Informationsblock im DisInfo-Parameter übergeben und die Funktionen TagType und Callback wie oben beschrieben angegeben werden. Diese können alle als NULL übergeben werden. Wenn dies erfolgreich ist, gibt dies einen Disassembler-Kontext zurück. Wenn nicht, gibt es NULL zurück.

Aktualisieren

  1. Meine llvm-Version ist 3.4
  2. Ich habe jedes denkbare Tripel / Ziel ausprobiert, immer noch dasselbe.
  3. LLVMCreateDisasm() eingefügt in lib / MC / MCDisassembler / Disassembler.cpp: LLVMCreateDisasmCPU () und scheitert beim ersten printf check. Die Zeichenfolge if an diesem Punkt ist Error

    %Vor%

    So schlägt es bei "Unable to find target for this triple (no targets are registered)" call.

  4. Wenn Sie lib / Support / TargetRegistry.cpp: lookupTarget () aufrufen, schlägt es beim ersten% co_de fehl % prüfen. Der Kommentar gibt einige Hinweise:

    %Vor%

    Es stellt sich also heraus, dass ich zuerst ein Ziel initialisieren muss.

  5. In meinem Code rufe ich zuerst lookupTarget aus dem Header if auf. Jetzt schlägt es am zweiten LLVMInitializeAllTargetInfos(); ein Disassembler.cpp: LLVMCreateDisasmCPU ()

    %Vor%

    mit diesem llvm-c/Target.h string: if

Endlich gelöst!

Ich musste einfach Error , Could not create disassembler , LLVMInitializeAllTargetInfos(); aufrufen, bevor ich einen Disasm-Kontext erstellt habe:

%Vor%     
Babken Vardanyan 30.01.2014, 17:04
quelle

1 Antwort

6

Das erste Argument von LLVMCreateDisasm , das

%Vor%

ist nicht gültig TripleName . TripleName weist den LLVM an, was Ihr Ziel ist, und dies ist erforderlich, da LLVM Unterstützung für mehrere Ziele in der einzelnen Installation enthält.

Sie können unterstützte Zielarchitekturen auflisten, indem Sie den Befehl

ausführen %Vor%

Und es gibt Ziele für x86 und x86_64

%Vor%

Um den richtigen TripleName zu konstruieren, sollten Sie für Ihr Ziel einige gute Unterarchive (i486 oder x86_64) finden, dann Hersteller und Betriebssystem hinzufügen:

Ссылка

%Vor%

Es gibt eine ArchType-Enumeration mit der Liste der erkannten Archs im Kommentar (der eigentliche Parser ist lib / Support / Triple.cpp - parseArch ), wie

%Vor%

In derselben Datei befinden sich gültige Anbieter ( enum VendorType ), Betriebssystemtypen ( enum OSType ) und Envrontments ( enum EnvironmentType ). In den meisten Fällen können Sie "unknown" für Vendor und OS verwenden, aber oft wird "-unknown-linux-gnu" verwendet.

Einige Beispiele für gültige TripleName s:

%Vor%

Es gibt mehr Beschreibung von gültigen Dreifachklängen hier: Ссылка und einige gültige Namen, die in Ссылка

Eine weitere Einschränkung in LLVMCreateDisasm ist, dass nicht alle Ziele die MCDisassembler s implementiert haben. Zum Beispiel gibt es in LLVM-2.9 MCDissaseblemers nur für X86, X86_64, ARM und MBlaze; in neueren (svn vom 01.02.2014) auch für Sparc, PPC, MIPS, SystemZ, XCore und AArch64.

Wenn Sie MCDisassembler nicht einmal mit dem richtigen Triple erstellen konnten, gibt es mehrere Optionen zum Debuggen der Funktion LLVMCreateDisasmCPU aus der Datei MC / MCDisassembler / Disassembler.cpp. Du kannst mit gdb eindringen und dann "next" -stepping machen bis Fehler (das wird mit debug build von LLVM schöner und einfacher); oder Sie können einige Fehlersuche printfs in die LLVMCreateDisasmCPU oder temporäre Änderung Rückgabewert von Plain NULL Info einige verschiedene für jeden Fehler hinzufügen.

UPDATE: Scheint, dass Ihr LLVM zum Zeitpunkt des Anrufs nicht initialisiert wurde. Es gibt viele LLVM-Initialisierer in der llvm-c / Target.h Kopfzeile in der aktuellen LLVM (~ 3.4 oder neuer):

  

LLVMInitializeAllTargetInfos() - Das Hauptprogramm sollte diese Funktion aufrufen, wenn       Es möchte Zugriff auf alle verfügbaren Ziele haben, für die LLVM konfiguriert ist       Unterstützung.

     

LLVMInitializeAllTargets() - Das Hauptprogramm sollte diese Funktion aufrufen, wenn es das tut       möchte alle verfügbaren Ziele verknüpfen, für die LLVM konfiguriert ist       Unterstützung.

     

LLVMInitializeAllTargetMCs() - Das Hauptprogramm sollte diese Funktion aufrufen, wenn       es möchte Zugriff auf alle verfügbaren Ziel-MCs haben, für die LLVM konfiguriert ist       Unterstützung.

     

LLVMInitializeAllDisassemblers() - Das Hauptprogramm sollte diese Funktion aufrufen       wenn es alle Disassembler, die LLVM konfiguriert ist, unterstützen soll, zu machen       Sie sind über die TargetRegistry verfügbar.

     

LLVMInitializeAllAsmPrinters() - Das Hauptprogramm sollte diese Funktion aufrufen, wenn       Es möchte alle Asm-Drucker, die LLVM unterstützt, um sie zu erstellen       verfügbar über die TargetRegistry.

und so weiter ( Ссылка ).

Es gibt sogar LLVMInitializeNativeTarget function, die das native Ziel initialisiert:

  

LLVMInitializeNativeTarget() - Das Hauptprogramm sollte diese Funktion aufrufen       initialisieren Sie das native Ziel, das dem Host entspricht. Das ist nützlich       für JIT-Anwendungen, um sicherzustellen, dass das Ziel korrekt verknüpft wird.

    
osgx 04.02.2014, 22:44
quelle

Tags und Links