<div dir="ltr">Hello,<div><br></div><div>I'm new to LLVM and I'm trying to write a string obfuscation pass which encrypts strings using a simple XOR encryption, however I've faced a strange issue. Consider following code:</div><div><br></div><div><div>#include <stdio.h></div><div><br></div><div>int main() {</div><div>  printf("Hello, World!\n");</div><div>  return 0;</div><div>}</div></div><div><br></div><div>When I try to compile it into executable using:</div><div><br></div><div>clang -o test test.c -mllvm -se</div><div><br></div><div>I get an error:</div><div><br></div><div><div>Global is referenced by parentless instruction!</div><div>[15 x i8]* @.e_954013943</div><div>; ModuleID = 'test.c'</div><div>  <badref> = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i32 0, i32 0</div><div>fatal error: error in backend: Broken module found, compilation aborted!</div><div>clang-3.9: error: clang frontend command failed with exit code 70 (use -v to see invocation)</div><div>clang version 3.9.0 (<a href="https://github.com/llvm-mirror/clang">https://github.com/llvm-mirror/clang</a> f339de408790ba9a321810b9486538e4f04459ed) (<a href="https://github.com/llvm-mirror/llvm.git">https://github.com/llvm-mirror/llvm.git</a> 3e9b31a2093ea41e1a4d42903d115b736ed66d67)</div><div>Target: x86_64-unknown-linux-gnu</div><div>Thread model: posix</div></div><div><br></div><div>When compiled without my obfuscation pass, it produces the following IR:</div><div><br></div><div><div>; ModuleID = 'test.c'</div><div>source_filename = "test.c"</div><div>target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"</div><div>target triple = "x86_64-unknown-linux-gnu"</div><div><br></div><div>@.str = private unnamed_addr constant [15 x i8] c"Hello, World!\0A\00", align 1</div><div><br></div><div>; Function Attrs: nounwind uwtable</div><div>define i32 @main() #0 {</div><div>entry:</div><div>  %retval = alloca i32, align 4</div><div>  store i32 0, i32* %retval, align 4</div><div>  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i32 0, i32 0))</div><div>  ret i32 0</div><div>}</div><div><br></div><div>declare i32 @printf(i8*, ...) #1</div></div><div><br></div><div>When compiled with my obfuscation pass, the following IR is generated.</div><div><br></div><div>Note that all getelementptr instructions are generated with i64, while in the erro report above the instruction is <badref> = getelementptr inbounds [15 x i8], [15 x i8]* @.e_58295325, i32 0, i32 0, which is not present in the output IR bytecode.</div><div><br></div><div>Note that if I manually compile the IR bytecode into executable, then it compiles and works just fine. It only outputs an error if I try to compile and link in one command using clang -o test test.c</div><div><br></div><div>The full execution command line is:</div><div><div>clang-3.9 "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "test.c" "-mrelocation-model" "static" "-mthread-model" "posix" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-ferror-limit" "19" "-fmessage-length" "271" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-fcolor-diagnostics" "-mllvm" "-se" "-x" "c" "test-42d5b1.c"</div></div><div><br></div><div>Could someone please advice where I should search for mistake?</div><div><br></div><div>Thanks!</div><div>Sergey</div><div><br></div><div><br></div><div><div>; ModuleID = 'test.c'</div><div>source_filename = "test.c"</div><div>target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"</div><div>target triple = "x86_64-unknown-linux-gnu"</div><div><br></div><div>@.e_954013943 = private constant [15 x i8] c"{2\0B\07*^J \0D\1B\09R\0ChP"</div><div><br></div><div>; Function Attrs: nounwind uwtable</div><div>define i32 @main() #0 {</div><div>entry:</div><div>  %retval = alloca i32, align 4</div><div>  store i32 0, i32* %retval, align 4</div><div>  %0 = alloca i8, i64 15</div><div>  %1 = getelementptr inbounds i8, i8* %0, i64 0</div><div>  %2 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 0</div><div>  %3 = load i8, i8* %2, align 8</div><div>  %4 = xor i8 %3, 51</div><div>  store i8 %4, i8* %1, align 8</div><div>  %5 = getelementptr inbounds i8, i8* %0, i64 1</div><div>  %6 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 1</div><div>  %7 = load i8, i8* %6, align 8</div><div>  %8 = xor i8 %7, 87</div><div>  store i8 %8, i8* %5, align 8</div><div>  %9 = getelementptr inbounds i8, i8* %0, i64 2</div><div>  %10 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 2</div><div>  %11 = load i8, i8* %10, align 8</div><div>  %12 = xor i8 %11, 103</div><div>  store i8 %12, i8* %9, align 8</div><div>  %13 = getelementptr inbounds i8, i8* %0, i64 3</div><div>  %14 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 3</div><div>  %15 = load i8, i8* %14, align 8</div><div>  %16 = xor i8 %15, 107</div><div>  store i8 %16, i8* %13, align 8</div><div>  %17 = getelementptr inbounds i8, i8* %0, i64 4</div><div>  %18 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 4</div><div>  %19 = load i8, i8* %18, align 8</div><div>  %20 = xor i8 %19, 69</div><div>  store i8 %20, i8* %17, align 8</div><div>  %21 = getelementptr inbounds i8, i8* %0, i64 5</div><div>  %22 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 5</div><div>  %23 = load i8, i8* %22, align 8</div><div>  %24 = xor i8 %23, 114</div><div>  store i8 %24, i8* %21, align 8</div><div>  %25 = getelementptr inbounds i8, i8* %0, i64 6</div><div>  %26 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 6</div><div>  %27 = load i8, i8* %26, align 8</div><div>  %28 = xor i8 %27, 106</div><div>  store i8 %28, i8* %25, align 8</div><div>  %29 = getelementptr inbounds i8, i8* %0, i64 7</div><div>  %30 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 7</div><div>  %31 = load i8, i8* %30, align 8</div><div>  %32 = xor i8 %31, 119</div><div>  store i8 %32, i8* %29, align 8</div><div>  %33 = getelementptr inbounds i8, i8* %0, i64 8</div><div>  %34 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 8</div><div>  %35 = load i8, i8* %34, align 8</div><div>  %36 = xor i8 %35, 98</div><div>  store i8 %36, i8* %33, align 8</div><div>  %37 = getelementptr inbounds i8, i8* %0, i64 9</div><div>  %38 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 9</div><div>  %39 = load i8, i8* %38, align 8</div><div>  %40 = xor i8 %39, 105</div><div>  store i8 %40, i8* %37, align 8</div><div>  %41 = getelementptr inbounds i8, i8* %0, i64 10</div><div>  %42 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 10</div><div>  %43 = load i8, i8* %42, align 8</div><div>  %44 = xor i8 %43, 101</div><div>  store i8 %44, i8* %41, align 8</div><div>  %45 = getelementptr inbounds i8, i8* %0, i64 11</div><div>  %46 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 11</div><div>  %47 = load i8, i8* %46, align 8</div><div>  %48 = xor i8 %47, 54</div><div>  store i8 %48, i8* %45, align 8</div><div>  %49 = getelementptr inbounds i8, i8* %0, i64 12</div><div>  %50 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 12</div><div>  %51 = load i8, i8* %50, align 8</div><div>  %52 = xor i8 %51, 45</div><div>  store i8 %52, i8* %49, align 8</div><div>  %53 = getelementptr inbounds i8, i8* %0, i64 13</div><div>  %54 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 13</div><div>  %55 = load i8, i8* %54, align 8</div><div>  %56 = xor i8 %55, 98</div><div>  store i8 %56, i8* %53, align 8</div><div>  %57 = getelementptr inbounds i8, i8* %0, i64 14</div><div>  %58 = getelementptr inbounds [15 x i8], [15 x i8]* @.e_954013943, i64 0, i64 14</div><div>  %59 = load i8, i8* %58, align 8</div><div>  %60 = xor i8 %59, 80</div><div>  store i8 %60, i8* %57, align 8</div><div>  %call = call i32 (i8*, ...) @printf(i8* %0)</div><div>  ret i32 0</div><div>}</div><div><br></div><div>declare i32 @printf(i8*, ...) #1</div></div><div><br></div></div>