Problems accessing structs

Hello!

I get some odd behaviour using my structs:

"myKernelMap" = type {int (sbyte*)*, int ()*}
"Kernel" = type {"myKernelMap"*}

The second member ( int()* ) is a pointer to the %getchar() function.

I want to call getchar using this function:

int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
{
        "PTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"MAP" = load "myKernelMap"** "PTRMAP"
"getchar_kernelPTR" = getelementptr "myKernelMap"* "MAP", long 0, ubyte 1
%tmp = load int ()** "getchar_kernelPTR"
"tmp_result" = call int ()* %tmp()
ret int "tmp_result"
}

I call it from main():

int %main() {
;Malloc's a Kernel and returns a pointer to it
"myKernel" = call "Kernel"* "createKernel"()

call int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
ret int 0
}

I get this output error message:

Hello Kernel
lli[0x844dd24]
lli[0x844df30]
/lib/tls/libc.so.6[0x420275c8]
lli(llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, char const* const*)+0x25b)[0x8305ca5]
lli(main+0x23c)[0x82aa058]
/lib/tls/libc.so.6(__libc_start_main+0xe4)[0x42015574]
lli(dlopen+0x41)[0x82a9d8d]
Segmentation fault

I have tried to have different function pointers, but ONLY pointers in position 0 in the map-struct works. If I try to access any other posistion, e.g. long 0, ubyte 1, this error comes.

What is wrong? Getelementptr again? :slight_smile:

The detailed complete source code is below.

Regards
Anders

Anders Alexandersson wrote:

Hello!

I get some odd behaviour using my structs:

"myKernelMap" = type {int (sbyte*)*, int ()*}
"Kernel" = type {"myKernelMap"*}

The second member ( int()* ) is a pointer to the %getchar() function.

I want to call getchar using this function:

int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
{
        "PTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"MAP" = load "myKernelMap"** "PTRMAP"
"getchar_kernelPTR" = getelementptr "myKernelMap"* "MAP", long 0, ubyte 1
%tmp = load int ()** "getchar_kernelPTR"
"tmp_result" = call int ()* %tmp()
ret int "tmp_result"
}

I call it from main():

int %main() {
;Malloc's a Kernel and returns a pointer to it
"myKernel" = call "Kernel"* "createKernel"()

call int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
ret int 0
}

I get this output error message:

Hello Kernel
lli[0x844dd24]
lli[0x844df30]
/lib/tls/libc.so.6[0x420275c8]
lli(llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, char const* const*)+0x25b)[0x8305ca5]
lli(main+0x23c)[0x82aa058]
/lib/tls/libc.so.6(__libc_start_main+0xe4)[0x42015574]
lli(dlopen+0x41)[0x82a9d8d]
Segmentation fault

I have tried to have different function pointers, but ONLY pointers in position 0 in the map-struct works. If I try to access any other posistion, e.g. long 0, ubyte 1, this error comes.

What is wrong? Getelementptr again? :slight_smile:

The detailed complete source code is below.

Regards
Anders

-----

"Hello KernelConst" = internal constant [14 x sbyte ] c"Hello Kernel\0A\00"

"myKernelMap" = type {int (sbyte*)*, int ()*}
"Kernel" = type {"myKernelMap"*}

declare int %printf(sbyte*, ...)
declare int %getchar(...)

int %puts_kernel(sbyte* %string)
{
%tmp0 = call int (sbyte*, ...)* %printf(sbyte* %string)
ret int 0
}

int %getchar_kernel()
{
%tmp0 = call int (...)* %getchar()
ret int 0
}

"Kernel"* "createKernel"()
{
"myKernelMapInstance" = malloc "myKernelMap"
"myKernel" = malloc "Kernel"
"myKernelMapPTR" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
store "myKernelMap"* "myKernelMapInstance", "myKernelMap"** "myKernelMapPTR"
"puts_kernelPTRPTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"puts_kernelPTRMAP" = load "myKernelMap"** "puts_kernelPTRPTRMAP"
"puts_kernelPTR" = getelementptr "myKernelMap"* "puts_kernelPTRMAP", long 0, ubyte 0
store int (sbyte*)* %puts_kernel, int (sbyte*)** "puts_kernelPTR"
ret "Kernel"* "myKernel"

    ^---------------
    + I'm guessing this line might be the problem.
    :)

The initialization code below is never getting reached, so the getchar() function pointer is never initialized.

"getchar_kernelPTRPTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"getchar_kernelPTRMAP" = load "myKernelMap"** "getchar_kernelPTRPTRMAP"
"getchar_kernelPTR" = getelementptr "myKernelMap"* "getchar_kernelPTRMAP", long 0, ubyte 1
store int ()* %getchar_kernel, int ()** "getchar_kernelPTR"
ret "Kernel"* "myKernel"
}

int "callmyKernelputs_kernel"("Kernel"* "myKernel")
{
        "PTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"MAP" = load "myKernelMap"** "PTRMAP"
"puts_kernelPTR" = getelementptr "myKernelMap"* "MAP", long 0, ubyte 0
%tmp = load int (sbyte*)** "puts_kernelPTR"
"Hello Kernel" = getelementptr [14 x sbyte]* "Hello KernelConst", long 0, long 0
"tmp_result" = call int (sbyte*)* %tmp(sbyte* "Hello Kernel")
ret int "tmp_result"
}

int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
{
        "PTRMAP" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"MAP" = load "myKernelMap"** "PTRMAP"
"getchar_kernelPTR" = getelementptr "myKernelMap"* "MAP", long 0, ubyte 1
%tmp = load int ()** "getchar_kernelPTR"
"tmp_result" = call int ()* %tmp()
ret int "tmp_result"
}

int %main() {
"myKernel" = call "Kernel"* "createKernel"()
call int "callmyKernelputs_kernel"("Kernel"* "myKernel")
call int "callmyKernelgetchar_kernel"("Kernel"* "myKernel")
"myKernel_MapPTRPTR" = getelementptr "Kernel"* "myKernel", long 0, ubyte 0
"myKernel_MapPTR" = load "myKernelMap"** "myKernel_MapPTRPTR"
free "myKernelMap"* "myKernel_MapPTR"
free "Kernel"* "myKernel"
ret int 0
}

----------------------------------------------------------------
Anders Alexandersson
Masters student at the special year of Software Engineering, HTU Trollhättan
E-mail: anders.alexandersson@student.htu.se

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev

-- John T.

I agree with John. If you run your code through the optimizers:

$ llvm-as < t.ll | opt -inline -load-vn -gcse -simplifycfg | llvm-dis

You get the following function:

int %main() {
createKernel.entry:
        %myKernelMapInstance.i = malloc %myKernelMap ; <%myKernelMap*> [#uses=2]
        %myKernel.i = malloc %Kernel ; <%Kernel*> [#uses=3]
        %myKernelMapPTR.i = getelementptr %Kernel* %myKernel.i, long 0, uint 0 ; <%myKernelMap**> [#uses=1]
        store %myKernelMap* %myKernelMapInstance.i, %myKernelMap** %myKernelMapPTR.i
        %puts_kernelPTR.i = getelementptr %myKernelMap* %myKernelMapInstance.i, long 0, uint 0 ; <int (sbyte*)**> [#uses=1]
        store int (sbyte*)* %puts_kernel, int (sbyte*)** %puts_kernelPTR.i
        %PTRMAP.i = getelementptr %Kernel* %myKernel.i, long 0, uint 0 ; <%myKernelMap**> [#uses=3]
        %MAP.i = load %myKernelMap** %PTRMAP.i ; <%myKernelMap*> [#uses=1]
        %puts_kernelPTR.i2 = getelementptr %myKernelMap* %MAP.i, long 0, uint 0 ; <int (sbyte*)**> [#uses=1]
        %tmp.i = load int (sbyte*)** %puts_kernelPTR.i2 ; <int (sbyte*)*> [#uses=1]
        "Hello Kernel.i" = getelementptr [14 x sbyte]* "Hello KernelConst", long 0, long 0 ; <sbyte*> [#uses=1]
        %tmp_result.i = call int %tmp.i( sbyte* "Hello Kernel.i" ) ; <int> [#uses=0]
        %MAP.i4 = load %myKernelMap** %PTRMAP.i ; <%myKernelMap*> [#uses=1]
        %getchar_kernelPTR.i5 = getelementptr %myKernelMap* %MAP.i4, long 0, uint 1 ; <int ()**> [#uses=1]
        %tmp.i = load int ()** %getchar_kernelPTR.i5 ; <int ()*> [#uses=1]
        %tmp_result.i6 = call int %tmp.i( ) ; <int> [#uses=0]
        %myKernel_MapPTR = load %myKernelMap** %PTRMAP.i ; <%myKernelMap*> [#uses=1]
        free %myKernelMap* %myKernel_MapPTR
        free %Kernel* %myKernel.i
        ret int 0
}

-Chris