[LLVMdev] Function pointers

Chris Lattner sabre at nondot.org
Fri Apr 2 10:26:47 PST 2004


On Fri, 2 Apr 2004, Anders Alexandersson wrote:

> OK, I solved it all ( so far :) ), mixing in some load-instructions and
> called on the result of that, which worked.
>
> Here is the skeleton-code:
>
> %kernel = type {  int ()*  }
>
> int puts_kernel(){...}
>
> ; main()
>
> %theKernel = malloc %kernel
> %puts_kernelPTR = getelementptr %kernel* %theKernel, long 1, ubyte 0
>
> store int ()* %puts_kernel, int ()** %puts_kernelPTR
> %tmp.11 = load int ()** %puts_kernelPTR
>
> %tmp.2 = call int %tmp.11()
>
> free %kernel* %theKernel

Yup, that's close.  You should be able to use an alloca instruction.  The
difference between alloca and malloc is that alloca is typically
substantially faster than malloc, but the memory allocated by it is
automatically freed when the function it is in returns.  In this case, it
shouldn't matter.

The bigger problem is that you are accessing a piece of memory that has
not been allocated:

   %theKernel = malloc %kernel
   %puts_kernelPTR = getelementptr %kernel* %theKernel, long 1, ubyte 0

The 'long 1' operand of the getelementptr instruction tells it to step to
the 1th kernel element.  In terms of C, we have something like this:

  kernel *K = malloc (...)
  K[1].field =

If you use 'long 0' things should work fine.

-Chris



> -----Original Message-----
> From: Anders Alexandersson <anders.alexandersson at student.htu.se>
> To: llvmdev at cs.uiuc.edu
> Date: Fri, 02 Apr 2004 13:38:30 +0200
> Subject: Re: Re: Re: [LLVMdev] Function pointers
>
> I solved that one by substituting alloca into malloc, and forwarded the problem to actually calling the %puts_kernel function via my newly created function pointer.
>
> This works:
>  %tmp.1 = call int %puts_kernel()
>
> This:
>  %tmp.2 = call int %puts_kernelPTR()
>
> issues error:
> "Reference to an invalid definition: 'puts_kernelPTR' of type 'int () *'"
>
> How do I call the function using the function pointer?
>
> Anders
>
> -----Original Message-----
> From: Anders Alexandersson <anders.alexandersson at student.htu.se>
> To: llvmdev at cs.uiuc.edu
> Date: Fri, 02 Apr 2004 10:07:50 +0200
> Subject: Re: Re: [LLVMdev] Function pointers
>
> So, here comes the next question:)
>
> Now the program compiles, but crashes when run, "Segmentation fault".
>
>
> %kernel = type {  int ()*  }
>
> int %puts_kernel()
> {
>    ret int 0
> }
>
>
> int %main() {
>
>    %theKernel = alloca %kernel
>
>    %puts_kernelPTR = getelementptr %kernel* %theKernel, long 1, ubyte 0
>    store int ()* %puts_kernel, int ()** %puts_kernelPTR
>
>    ret int 0
> }
>
> I want to learn how to achieve the mechanisms in this C code:
>
> #include <stdio.h>
>
> int DoIt(void);
> int DoIt(void){
>  return 0;
> }
>
> int main()
> {
>         int (*pt2Function) ();
>
>         int a = DoIt();
>         printf("a is: %i\n", a);
>
>         pt2Function = DoIt;
>
>         int b = pt2Function();
>         printf("b is: %i\n", b);
> }
>
> Grateful for hints!
>
> Anders
>
>
>
> -----Original Message-----
> From: Chris Lattner <sabre at nondot.org>
> To: llvmdev at cs.uiuc.edu
> Date: Thu, 1 Apr 2004 09:51:48 -0600 (CST)
> Subject: Re: [LLVMdev] Function pointers
>
> On Thu, 1 Apr 2004 anders.alexandersson at student.htu.se wrote:
>
> > Yes! :-)
> > What would I do without you folks?!
>
> :)
>
> > I am the one trying to build a Ruby compiler prototype, so be prepared for
> > more questions...:)
>
> Sounds great!
>
> -Chris
>
> > ----- Original Message -----
> > From: "Chris Lattner" <sabre at nondot.org>
> > To: <llvmdev at cs.uiuc.edu>
> > Sent: Wednesday, March 31, 2004 5:49 PM
> > Subject: Re: [LLVMdev] Function pointers
> >
> >
> > On Wed, 31 Mar 2004, Anders Alexandersson wrote:
> >
> > > Hello out there!
> > >
> > > I am trying to build a table of 2 function poiters by using an array:
> > >
> > > %kernel = alloca [ 2 x int ()* ]
> > >
> > > I try to access the first pointer to be able to store location of my first
> > function like this:
> > >
> > > %function_pointer_1 = getelementptr [2 x int ()* ]* %kernel, long 0, long
> > 0
> > >
> > > store int ()* %function_1, int ()* %function_pointer_1
> >
> > You just need an extra * here:      ^
> >
> > You're storing a pointer through a pointer to pointers... :)
> >
> > -Chris
> >
> > >
> > > But, I get the error message from llvm-asm:
> > > llvm-as: 1.ll:40: Can't store 'int () *' into space of type 'int ()'!
> > >
> > > What is my mistake?
> > >
> > > Grateful for hints
> > > Anders
> > >
> > > ----------------------------------------------------------------
> > > Anders Alexandersson
> > > Masters student at the special year of Software Engineering, HTU
> > Trollh4an
> > > E-mail: anders.alexandersson at student.htu.se
> > >
> > > _______________________________________________
> > > LLVM Developers mailing list
> > > LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> > >
> >
> > -Chris
> >
> >
>
> -Chris
>
>

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/





More information about the llvm-dev mailing list