0
votes

I'm trying to implement nested functions in llvm through the C++ API. After i perform a semantic check (to assure that the program which is going to be compiled has correct nesting references etc) i define all function in the same scope in llvm and set all variables as global. I was expecting this to work but i found myself having huge problem while getting an executable from an .o file with the command:

"llvm-as-3.8 output.ll| llc-3.8 -filetype=obj | clang-3.8 ../library/library.a  -v -o out"

By using either llvm::GlobalValue::WeakAnyLinkage or llvm::GlobalValue::ExternalLinkage linkage for global variables i get:

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 12

...

/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start':

(.text+0x20): undefined reference to `main'

Which seems to have to do with the definition of main, who in the definition of my ir code stands as:

; Function Attrs: nounwind uwtable define void @main() #0 {

The thing is that the same command didn't have any problem when i didn't use global variables except of course the case where a variable was used in a child function, which was the reason i tried to change alloca to global.

Help find a solution to this problem. Thanks in advance. Note1: I use llvm-3.8

UPDATE: when i removed -v from the clang command the result was:

refined_output.o: In function bsort': refined_output.ll:(.text+0x4): undefined reference tox' refined_output.ll:(.text+0xa): undefined reference to n' refined_output.ll:(.text+0x10): undefined reference tochanged' refined_output.ll:(.text+0x22): undefined reference to i' refined_output.ll:(.text+0x2c): undefined reference tochanged' refined_output.ll:(.text+0x42): undefined reference to i' refined_output.ll:(.text+0x48): undefined reference ton' refined_output.ll:(.text+0x50): undefined reference to i' refined_output.ll:(.text+0x59): undefined reference tox' refined_output.ll:(.text+0x60): undefined reference to i' refined_output.ll:(.text+0x75): undefined reference tox' refined_output.ll:(.text+0x7c): undefined reference to i' refined_output.ll:(.text+0x95): undefined reference tochanged' refined_output.ll:(.text+0xa3): undefined reference to changed' refined_output.o: In functionswap': refined_output.ll:(.text+0xc3): undefined reference to x.1' refined_output.ll:(.text+0xca): undefined reference toy' refined_output.ll:(.text+0xd1): undefined reference to x.1' refined_output.ll:(.text+0xd9): undefined reference tot' refined_output.ll:(.text+0xe0): undefined reference to x.1' refined_output.ll:(.text+0xe7): undefined reference toy' refined_output.ll:(.text+0xf2): undefined reference to y' refined_output.ll:(.text+0xf8): undefined reference tot' refined_output.o: In function main': refined_output.ll:(.text+0x102): undefined reference toi.4' refined_output.ll:(.text+0x10c): undefined reference to seed' refined_output.ll:(.text+0x123): undefined reference tox.2' refined_output.ll:(.text+0x12a): undefined reference to i.4' refined_output.ll:(.text+0x130): undefined reference toseed' refined_output.ll:(.text+0x15d): undefined reference to seed' refined_output.ll:(.text+0x166): undefined reference toi.4' refined_output.ll:(.text+0x16c): undefined reference to i.4' refined_output.ll:(.text+0x177): undefined reference tox.2' refined_output.ll:(.text+0x18d): undefined reference to x.2' refined_output.ll:(.text+0x19e): undefined reference tox.2' refined_output.o: In function printArray': refined_output.ll:(.text+0x1c4): undefined reference tomsg' refined_output.ll:(.text+0x1cb): undefined reference to x.2' refined_output.ll:(.text+0x1d1): undefined reference ton.3' refined_output.ll:(.text+0x1d8): undefined reference to msg' refined_output.ll:(.text+0x1e3): undefined reference toi.4' refined_output.ll:(.text+0x1f3): undefined reference to x.2' refined_output.ll:(.text+0x1fa): undefined reference toi.4' refined_output.ll:(.text+0x208): undefined reference to i.4' refined_output.ll:(.text+0x20e): undefined reference toi.4' refined_output.ll:(.text+0x214): undefined reference to n.3' refined_output.ll:(.text+0x21c): undefined reference toi.4'

clang: error: linker command failed with exit code 1 (use -v to see invocation)

Where all this variables were defined at the start of my program in llvm IR as:

@x = external global i32*
@n = external global i32
@i = external global i32
@changed = external global i1
@x.1 = external global i32*
@y = external global i32*
@t = external global i32
@msg = external global i8*
@x.2 = external global i32*
@n.3 = external global i32
@i.4 = external global i32
@const_string_temp = private constant [3 x i8] c", \00", align 1
@const_string_temp.5 = private constant [2 x i8] c"\0A\00", align 1
@i.6 = external global i32
@x.7 = external global i32
@seed = external global i32
@const_string_temp.8 = private constant [16 x i8] c"Initial array: \00", align 1
@const_string_temp.9 = private constant [15 x i8] c"Sorted array: \00", align 1

I hope this helps you help me --- or else find the problem in my IR code generation.

I'm looking forward to it..

1
void main? Are you sure?kfsone
Changing it to int main() doesn't change anything.John Sig

1 Answers

2
votes
@x = external global i32*

and so on are global variable declarations, not definitions. Therefore, the "undefined reference" error is valid and you really need to define them.

See http://llvm.org/docs/LangRef.html#global-variables for more information

Also note that llvm-as / llc part is redundant - clang could compile .ll / .bc files just fine.