2012-02-06 12 views
11

Chcę odczytać (przeanalizować) kod LLVM IR (który jest zapisany w pliku tekstowym) i dodać do niego trochę mojego własnego kodu. Potrzebuję tego przykładu, czyli sposobu, w jaki to robi się za pomocą bibliotek dostarczonych przez LLVM w tym celu. Więc w zasadzie to, czego chcę, to odczytanie w kodzie IR z pliku tekstowego do pamięci (być może biblioteka LLVM reprezentuje ją w formie AST, nie wiem), wprowadzanie modyfikacji, jak dodawanie kolejnych węzłów w AST i wreszcie pisanie cofnij AST w pliku tekstowym IR.Parsowanie i modyfikowanie kodu LLVM IR

Chociaż muszę zarówno czytać, jak i modyfikować kod IR, byłbym bardzo wdzięczny, gdyby ktoś mógł podać lub odesłać mnie do jakiegoś przykładu, który po prostu czyta (parsuje).

Odpowiedz

24

Po pierwsze, aby naprawić oczywiste nieporozumienie: LLVM to framework do manipulowania kodem w formacie IR. Nie widać żadnych AST (*) - czytasz IR, transformujesz/manipulujesz/analizujesz, a Ty odpisujesz IR.

Reading IR jest bardzo prosta:

int main(int argc, char** argv) 
{ 
    if (argc < 2) { 
     errs() << "Expected an argument - IR file name\n"; 
     exit(1); 
    } 

    LLVMContext &Context = getGlobalContext(); 
    SMDiagnostic Err; 
    Module *Mod = ParseIRFile(argv[1], Err, Context); 

    if (!Mod) { 
     Err.print(argv[0], errs()); 
     return 1; 
    } 

    [...] 
    } 

Kod ten przyjmuje nazwę pliku. Powinien to być plik IR LLVM (tekstowy). Następnie przetwarza go na Module, który reprezentuje moduł podczerwieni w wewnętrznym formacie pamięci w LLVM. Można to następnie zmanipulować za pomocą różnych przejść, które LLVM ma lub dodajesz sam. Spójrz na kilka przykładów w bazie kodu LLVM (takich jak lib/Transforms/Hello/Hello.cpp) i przeczytaj to - http://llvm.org/docs/WritingAnLLVMPass.html.

Pętla podczerwona z powrotem do pliku jest jeszcze łatwiejsza. Klasa Module po prostu zapisuje się do strumienia:

some_stream << *Mod; 

To wszystko.

Teraz, jeśli masz jakiekolwiek konkretne pytania dotyczące specyficznych modyfikacji chcesz zrobić do kodu IR, należy naprawdę coś zapytać bardziej skoncentrowany. Mam nadzieję, że ta odpowiedź pokazuje, jak przetworzyć IR i zapisać go.


(*) IR nie ma reprezentacji AST wewnątrz LLVM, ponieważ jest to prosty język podobny do zestawu. Jeśli pójdziesz o jeden krok w górę, do C lub C++, możesz użyć Clanga, by przeanalizować to w AST, a następnie wykonać manipulacje na poziomie AST. Clang wie, jak wytworzyć LLVM IR ze swojej AST. Jednak musisz zacząć od C/C++ tutaj, a nie LLVM IR. Jeśli potrzebujesz LLVM IR, zapomnij o AST.

+0

Dzięki Eli. Twoja odpowiedź była bardzo pomocna. – MetallicPriest

+0

Podejrzewam, myślę, że powinien to być "parseIRFile" z małymi literami p. http://llvm.org/docs/doxygen/html/IRReader_2IRReader_8h_source.html – user2027722

+0

@ user2027722: tak, interfejsy API LLVM zmieniają się tak często, że aktualizowanie próbek jest bardzo trudne. Mam repozytorium Github dla tego: https://github.com/eliben/llvm-clang-samples, które robię, zachowuję jak zsynchronizowane, jak to możliwe, i to jest bardziej źródło prawdy niż losowe odpowiedzi SO –

1

Najprostszym sposobem, aby to zrobić, jest przejrzenie jednego z istniejących narzędzi i wykradanie z niego kodu. W takim przypadku możesz chcieć spojrzeć na źródło dla llc. Może to być plik typu bitcode lub .ll. Możesz zmodyfikować plik wejściowy w dowolny sposób, a następnie zapisać plik przy użyciu czegoś podobnego do kodu w llvm-dis, jeśli chcesz plik tekstowy.

2

Zwykle wykonuje się to za pomocą wprowadzenia hasła/transformacji LLVM. W ten sposób nie musisz analizować IR w ogóle, ponieważ LLVM zrobi to za ciebie i będziesz operował na OO-zorientowanej w pamięci reprezentacji IR.

to punkt wejścia do zapisu przepustki LLVM. Następnie możesz przejrzeć dowolne z wcześniej wdrożonych standardowych karnetów dostarczanych w pakiecie z LLVM (spójrz na lib/Transforms).

+0

To będzie to, co zrobię ostatecznie. Ale w tej chwili, ponieważ jestem w fazie uczenia się, chcę móc zobaczyć IR w plikach tekstowych. – MetallicPriest

+3

Nie widzę problemu. Większość narzędzi LLVM może czytać/pisać tekstową reprezentację IR. W szczególności, aby emitować tekstową reprezentację, dodaj przełącznik -S do linii poleceń. (Pamiętaj też, że reprezentacja binarna i tekstowa są absolutnie równoważne). – CAFxX

1

Narzędzie Opt pobiera kod IP IRV, uruchamia go, a następnie wypluwa przekształcone IR IR po drugiej stronie.

Najprostszym sposobem na rozpoczęcie hakowania jest lib \ Transforms \ Hello \ Hello.cpp. Zhakuj go, przeprowadź opt przez plik źródłowy jako dane wejściowe, sprawdź dane wyjściowe.

Poza tym dokumentacja do pisania jest bardzo dobra.

1

Jak wspomniano powyżej, najlepiej napisać podanie. Ale jeśli chcesz po prostu powtórzyć instrukcje i zrobić coś z LLVM pod warunkiem klasy InstVisitor. Jest to klasa, która implementuje wzorzec odwiedzającego w celu uzyskania instrukcji. Jest bardzo prosty w obsłudze dla użytkownika, więc jeśli chcesz uniknąć uczenia się, jak wprowadzić karnet, możesz to zrobić.

Powiązane problemy