2017-07-27 2 views
1

Ich habe einen LLVM-Pass verwendet, um Funktionen umzubenennen. Gegeben einige Quelldatei file.cc, erzeuge ich LLVM Bitcode wie folgt:Wie kann man eine Funktion während des LLVM-Passes verfälschen und dann abmildern?

clang -c -o foo.bc -emit-llvm foo.cc.

Ich möchte ein LLVM übergehen foo.bc und benennen Sie alle Globals, Funktionen und Aliase, so dass ich ausgeben kann das transformierte Bitcode in eine neue Datei file_renamed.bc und dann Link file.bc und file_renamed.bc in einer einzigen Datei file_linked.bc, auszuführen.

Eines meiner Probleme ist mir begegnet, dass einfach F.setName(F.getName() + "_renamed") tun, wird das Suffix nach dem verstümmelten Namen von F.getName() zurück hinzufügen.

Ein weiteres Problem: Ich habe eine Funktion demangle(const std::string &Name) darunter, dass erfolgreich Name, aber ich habe Probleme, diesen Namen wieder Mangeln.

Wenn es eine bessere Möglichkeit gibt, Kennungen in LLVM-Bitcode umzubenennen oder zwei Instanzen desselben Bitcodes zu verknüpfen, aber die Funktionen und globalen Variablen in jeder Version eindeutig zu identifizieren, können Sie sie in Ihrer Antwort vorschlagen .

Hier ist mein LLVM-Pass. Beachten Sie, dass ich mit LLVM 3.4 (es eine Abhängigkeit für das Projekt arbeite ich an.)

Headers

#include <vector> 
#include <iostream> 
#include <fstream> 
#include <string> 
#include <sstream> 
#include <cxxabi.h> 
#include <memory> 

#include "llvm/Pass.h" 
#include "llvm/IR/Function.h" 
#include "llvm/Support/raw_ostream.h" 
#include "llvm/ADT/STLExtras.h" 
#include "llvm/ADT/SmallString.h" 
#include "llvm/ADT/SmallVector.h" 
#include "llvm/ADT/StringRef.h" 
#include "llvm/ADT/Twine.h" 
#include "llvm/IR/DerivedTypes.h" 
#include "llvm/IR/Module.h" 
#include "llvm/IR/Type.h" 
#include "llvm/IR/TypeFinder.h" 
#include "llvm/Transforms/IPO.h" 
#include "llvm/IR/Argument.h" 
#include "llvm/IR/GlobalValue.h" 
#include "llvm/IR/DataLayout.h" 
#include "llvm/Target/Mangler.h" 

-Code

using namespace llvm; 

namespace { 

    struct FunctionRename : public ModulePass { 
    static char ID; // Pass identification 

    FunctionRename() : ModulePass(ID) {} 

    bool runOnModule(Module &M) override { 

     // Rename all globals and references to them 
     for (auto it = M.global_begin(); it != M.global_end(); ++it) 
     {...} 

     // Rename all aliases and references to them 
     for (auto it = M.alias_begin(); it != M.alias_end(); ++it) 
     {...} 

     // Rename all functions and references to them 
     for (auto &F : M) 
     { 
     StringRef Name = F.getName(); 
     if (F.isDeclaration()) 
      continue; 

     std::string demangled_name = demangle(Name.str()); 
     std::string new_name = rename(demangled_name); 
     F.setName(mangle(new_name, &F)); 
     F.setLinkage(GlobalValue::WeakAnyLinkage); 
     } 
     return true; 
    } 

    std::string demangle(const std::string &Name) 
    { 
     int status; 
     char* demangled_name = NULL; 
     char* cstr_name = new char[Name.length() + 1]; 
     strcpy(cstr_name, Name.c_str()); 
     demangled_name = __cxxabiv1::__cxa_demangle(cstr_name, NULL, NULL, &status); 
     if (status != 0) 
     { 
     errs() << "Demangling operation failed:\n"; 
     switch (status) 
     {...} 
     exit(-1); 
     } 
     std::string s(demangled_name); 
     return s; 
    } 

    std::string rename(std::string &Name) 
    { 
     std::string search_str = std::string("("); 
     std::string suffix_str = std::string("_renamed"); 
     size_t i = Name.find_first_of(search_str); 
     if (i == std::string::npos) 
     Name.append(suffix_str); 
     else 
     Name.insert(i, suffix_str); 
     return Name; 
    } 

    /* PROBLEMATIC FUNCTION */ 
    std::string mangle(const std::string &Name, const GlobalValue *GV) 
    { 
     SmallString<256> MangledName(StringRef(Name)); 

     Mangler m; 
     m.getNameWithPrefix((SmallVectorImpl<char>&) MangledName, GV, false, true); 
     Twine T; 
     StringRef S = T.toStringRef((SmallVectorImpl<char>&) MangledName); 
     return S.str(); 
    } 
    }; 
} 

// Register Pass 
char FunctionRename::ID = 0; 
static RegisterPass<FunctionRename> X("functionrename", "Function Rename Pass"); 
+1

Ich denke, Ihre 'Entmagnetisierung'-Funktion ist auch falsch. Es fordert ab, C++ - ABI-Bibliothek zu verwenden, für die LLVM kompiliert wurde, und Bitcode kann von Compiler mit anderem C++ - ABI erzeugt werden. – arrowd

+0

Wenn ich mich richtig erinnere, ist der in LLVM enthaltene "Mangler" kein C++ - Mangler, sondern ein C-Mangler, der den Symbolnamen normalerweise ein "_" hinzufügt, um C-Symbole von Assembly-Symbolen zu unterscheiden, wenn Sie C++ zerlegen möchten Link zu den clang-Bibliotheken, die dem Signal entsprechen, mit dem Sie den Bitcode erzeugt haben. – PaulR

Antwort

1

Sie können nicht einfach Mangle die C++ - Bezeichner nur aus der Zeichenfolge. Sie müssen richtige C++ AST haben. In der Tat, ich verstehe nicht, warum Sie dieses Mangle/Demangle-Ding überhaupt brauchen würden. Da Sie auf LLVM-IR-Ebene arbeiten, sollten Sie sich nicht mit Sprachdetails (wie dem ursprünglichen nicht verwalteten Namen) beschäftigen.

Verwandte Themen