2015-02-12 110 views
-2

使用encryptedString替換GlobalVariable但類型不匹配。llvm pass replaceAllUsesWith類型不匹配

GlobalVariable a const char *字符串。 代碼這樣的:

GlobalVariable* GV = *it; 
    //get clear text string 
    std::string clearstr = getGlobalStringValue(GV); 
    GlobalVariable::LinkageTypes lt = GV->getLinkage(); 
    //encrypt current string 
    std::string encryptedString = stringEncryption(clearstr);  
    //create new global string with the encrypted string 
    std::ostringstream oss; 
    oss << ".encstr" << encryptedStringCounter << "_" << sys::Process::GetRandomNumber(); 
    Constant *cryptedStr = ConstantDataArray::getString(M.getContext(), encryptedString, true); 
    GlobalVariable* gCryptedStr = new GlobalVariable(M, cryptedStr->getType(), true, GV->getLinkage(), cryptedStr, oss.str()); 
    StringMapGlobalVars[oss.str()] = gCryptedStr; 
    //replace use of clear string with encrypted string 
    GV->replaceAllUsesWith(gCryptedStr); 

但失敗:

斷言失敗:(新建 - >的getType()==的getType() 值與不同類型的新值的& &「replaceAllUses !「),

回答

1

起初:我建議在LLVM IR中用正確的類型替換所有的東西,這就是爲什麼這個斷言在那裏。

但是:

您得到這個斷言是因爲你的字符串長度不匹配。全局字符串表示爲一個字符數組(即i8值)。所以你的字符串的類型是[len x i8],其中len是你的字符串的長度。

@.str = private unnamed_addr constant [12 x i8] c"hello world\00", align 1 

你可以做的是寫自己的替換函數是這樣的:

template<typename T> 
void ReplaceUnsafe(T *from, T *to) { 

    while (!from->use_empty()) { 
    auto &U = *from->use_begin(); 
    U.set(to); 
    } 
    from->eraseFromParent(); 
} 

然而,這是(作爲函數名指示)不安全的,這是爲什麼:

考慮以下C/C++代碼:

int main() { 
    return "hello world"[9]; 
} 

這將只返回的int表示。

編譯於紅外線它看起來像這樣:

@.str = private unnamed_addr constant [12 x i8] c"hello world\00", align 1 

; Function Attrs: nounwind 
define i32 @main() #0 { 
entry: 
    %retval = alloca i32, align 4 
    store i32 0, i32* %retval 
    %0 = load i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i64 9), align 1 
    %conv = sext i8 %0 to i32 
    ret i32 %conv 
} 

如果字符串現在不等型somiting取代(例如,[7 x i8]類型的東西),那麼你可能會因爲你的GEP問題結束指令具有9作爲內容索引。這將導致出界限制訪問。我不知道當看到GEP指令(如果你運行它)時,llvm驗證通過是否會捕獲這個問題。

+0

如果替換類型[7×6-18],和 「getelementptr界外球([12×6-18] * @名爲.str,I32 0,I64 9)」 將變爲「getelementptr inbounds([7 x i8] * @ .str,i32 0,i64 9)」? – AloneMonkey 2015-02-12 08:48:55

+0

是的,如果你看看Value類的'replaceAllUsesWith'函數,你會看到'ReplaceUnsafe'函數基本上是一樣的。 'replaceAllUsesWith'函數後面沒有語義檢查。你所擁有的只是檢查(一些)可以在IR中完成的錯誤的驗證通行證,並且我認爲它會告訴你GEP指令有問題,但我不確定。 – 2015-02-12 09:17:57

+0

謝謝你的回答! – AloneMonkey 2015-02-13 01:32:32

0
Constant *cryptedStr = ConstantDataArray::getString(M.getContext(), encryptedString, true); 

變化到

 
Constant *cryptedStr = ConstantDataArray::getString(M.getContext(), encryptedString, false);