2016-01-03 26 views
5

Attualmente sto lavorando a uno strumento che identifica il carico e memorizza gli accessi su variabili globali e di campo su programmi arbitrari. Inoltre, le variabili accessibili dovrebbero essere identificate dai loro nomi/identificatori del livello sorgente. Per ottenere ciò, compilo il codice sorgente del programma sotto diagnosi in LLVM IR con informazioni di debug. Fin qui tutto bene, i nodi di metadati generati contengono gli identificatori del livello di origine desiderati. Tuttavia, non sono in grado di tracciare connessioni con alcuni identificatori IR LLVM e le informazioni nei metadati.IR LLVM: identificazione di variabili con nodi di metadati

Ad esempio, si consideri un membro satic di una classe:

class TestClass { 
    public: 
    static int Number; 
}; 

La corrispondente LLVM IR si presenta così:

@_ZN12TestClass6NumberE = external global i32, align 4 

... 
!15 = !DIDerivedType(tag: DW_TAG_member, name: "Number", scope: !"_ZTS12TestClass", file: !12, line: 5, baseType: !16, flags: DIFlagPublic | DIFlagStaticMember) 

In questo esempio controllato so che "@ _ZN12TestClass6NumberE" è un identificatore per "Numero". Tuttavia, in generale, non riesco a vedere come posso scoprire quali identificatori IR corrispondono a quali metadati.

Qualcuno può darmi una mano?

risposta

1

Dal momento che nessuno sembra avere una buona soluzione al mio problema, dirò il mio approccio inconviente per gestire questo problema. I nodi MetaData generati da LLVM contengono informazioni sui tipi definiti e sulle variabili del codice. Tuttavia, non ci sono informazioni su quali variabili IR generate corrispondono a quali variabili del codice sorgente. LLVM si limita a collegare le informazioni sui metadati delle istruzioni IR con le ubicazioni delle fonti correttive (linee e colonne). Questo ha senso, poiché il compito principale dei metadati di LLVM non è l'analisi, ma il debug.

Tuttavia, le informazioni contenute non sono inutili. La mia soluzione a questi problemi è di usare il clang AST per l'analisi del codice sorgente. Qui otteniamo informazioni su quale variabile è accessibile in quale posizione di origine. Quindi, al fine di ottenere informazioni sulle identità delle variabili di origine durante la strumentazione IR LLVM, abbiamo solo bisogno di mappare le posizioni di origine per identificare le identità delle variabili durante l'analisi AST clang. Come secondo passo eseguiamo la strumentazione IR utilizzando le informazioni raccolte in precedenza. Quando incontriamo un'archiviazione o un'istruzione di caricamento nell'IR, cerchiamo nel nodo metadati di questa istruzione la sua posizione di origine corrispondente. Poiché abbiamo mappato le posizioni di origine per l'origine delle identità delle variabili, ora possiamo facilmente accedere all'identità della variabile di origine dell'istruzione IR.

Quindi, perché non uso solo clang AST per identificare negozi e carichi su variabili? Perché distinguere letture e scritture in AST non è un compito semplice. L'AST può facilmente dire che si accede a una variabile, ma dipende dall'operazione se la variabile ad essa collegata viene letta o scritta. Quindi, dovrei considerare ogni singola operazione/operatore per determinare se la variabile è scritta/letta o entrambe. LLVM è molto più semplice, più di basso livello, a questo proposito e in quanto tale meno soggetto a errori. Inoltre, la strumentazione reale (inserimento del codice parlante) è molto più difficile nell'AST come con LLVM. Per queste due ragioni, credo che una combinazione di clang AST e strumentazione IR LLVM sia la soluzione migliore per il mio problema.