0

I am using llvmpy to (attempt to) generate IR code. However, I am stuck using printf and an array of int8.

The following is an excerpt of what is giving me issues:

# Defining the print function.
# -----
fntype = Type.function(Type.void(), [Type.pointer(Type.int(8))])
myprint = module.add_function(fntype, 'print')
cb = CBuilder(myprint)
x = cb.printf("%s\n", cb.args[0])
cb.ret()
cb.close()

# Creating the string.
# -----
chartype = Type.int(8)
chars = [Constant.int(chartype, ord(c)) for c in "Hello World!"]
string = Constant.array(chartype, chars)
ptr = string.gep([Constant.int(Type.int(8)), 0])

# Calling the print function.
# -----
cfn = exe.get_ctype_function(module.get_function_named('print'), 
                             None, ct.c_char_p)
cfn(ptr)

When I run this code I receive

ctypes.ArgumentError: argument 1: : wrong type

What am I doing wrong? I feel that my usage of .gep() is at fault, but I'm not sure in what way. Or is there something else that I don't understand?

Also, is there a way to get the expected type from the function?

sdasdadas
  • 23,917
  • 20
  • 63
  • 148

1 Answers1

2

Yes, your usage of gep is incorrect:

  1. The gep method receives a collection of indices, so not sure what a type is doing there.
  2. The receiver of the gep method needs to be a pointer (or a pointer vector), while your receiver is an array.

But the fundamental problem here is that you are trying to get the address of a compile-time constant - i.e., the address of something which is never allocated any memory.

The proper way to do what you're trying to do is to create a global variable which is

  1. Initialized to your "hello world" and
  2. Marked as constant

Such a variable is allocated an address (of type pointer to i8 array) - and then you can use gep or bitcast constant-expressions to get i8* and send it to your print function.

For an example, try to compile a c program with a string literal into LLVM IR and you'll see the string literal was placed in such a global variable.

Community
  • 1
  • 1
Oak
  • 26,231
  • 8
  • 93
  • 152