[Asan] undefined reference to runtime function

1,105 views
Skip to first unread message

Pierre Gagelin

unread,
May 27, 2016, 10:51:08 AM5/27/16
to address-...@googlegroups.com
Hi,

I am trying to implement a runtime to an existant LLVM FunctionPass. I followed your design and instrumented the code with call to a runtime function but this function seems to be undefined. Let me be more specific:

- I added a function in asan_rtl.cc with quite nothing in it (I am not even sure what Report does but I though it might print something... the point is to call this function with instrumentation):

  void __bounds_init() {
    Report("Runtime Library accessed!");
  }

- I added an doInitialization function to my FunctionPass in order to retrieve a pointer to the __bounds_init function:

  bool BoundsChecking::doInitialization(Module &M) {
    if (runTimeEnabled) return false;
    runTimeEnabled = true;
    errs() << "Initialization of the FunctionPass...\n";
    std::tie(ctor_func, init_func) =
          createSanitizerCtorAndInitFunctions(
              M, "", "__bounds_init",
              /*InitArgTypes=*/{}, /*InitArgs=*/{}, "check_v1");
    if(init_func) errs() << "Initialization succeded!\n";
    return true;
  }
Maybe the call to createSanitizerCtorAndInitFunctions isn't correctly done? It seems that the function only needs a init name. As I don't need a constructor I let the name empty... I didn't know what to put into the check version argument so I put a random name "check_v1"

- Then I made the call generation with the following for each function just to try:

    IRBuilder<> IRB(&F.front(), F.front().begin());
    IRB.CreateCall(init_func, {});

I got no errors when building LLVM with thoses changes but when I generate the executable with clang -fsanitize=bounds (this is the way to call BoundsChecking) the linker (so, after optimizations) fails and gives several " undefined reference to `__bounds_init' ".

I suppose I missed something but I dont know what. I looked at the IR generated with -S -emit-llvm, and there are several calls to __bounds_init and a declaration but no define:

  call void @__bounds_init() #3
  declare void @__bounds_init()

Anyone knows how I should do to be able to link the function created in asan_rtl.cc to the code being created? Or where to look in asan sources to find an answer? Feel free to ask me details, it's possible I am not being clear in what I exposed to you?

Thanks a lot for you time,
Pierre

Yuri Gribov

unread,
May 27, 2016, 11:29:37 AM5/27/16
to address-...@googlegroups.com
Pierre,

In this case it seems that you need to do some additional actions to
export your new symbol from runtime library. I remember that it hides
(i.e. does not export) most of it's symbols by default so you need to
whitelist your new function somewhere.
> --
> You received this message because you are subscribed to the Google Groups
> "address-sanitizer" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to address-saniti...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Konstantin Serebryany

unread,
May 27, 2016, 12:05:48 PM5/27/16
to address-sanitizer
llvm...@lists.llvm.org might be a better place for such questions, but let me try here. 

1. check that you have a proper symbol in the run-time library (*.a) using nm. 
From your code snippet I suspect that you may have forgotten to add extern "C"

2. Run the compilation command line wit -v to verify that the linker flags and *.a files are passed as you would expect 

3. again, using nm, check what functions are expected by the instrumented .o file. 

hth. 

--kcc 

Pierre Gagelin

unread,
Jun 1, 2016, 6:59:31 AM6/1/16
to address-...@googlegroups.com
Hi everyone,

I sincerely apologize I couldn't reply earlier. I had some troubles getting access to the computing lab recently but that's all right now. Thank you for your leads. My answer is long but once you cut the copy/paste so it shouldn't be too hard to understand.

I shall tell you I am not at ease with the nm tool and .a files so I can't interpret a lot the results I get. The first one that feels strange to me is the following. As I can't get an executable file with -fsanitize=bounds (because the linker fails to do the __bounds_init call) I did it with -fsanitize=address thinking my function would be listed. It seems to be the case but not with the right name, here's what I did:

- clang -fsanitize=address overflow.c -o overflow_asan
- nm overflow_asan | grep __bounds:
00000000004d0140 T _Z13__bounds_initv

The name has a "_Z13" prefix and a "v" suffix. I remember seeing those prefix and suffix adds somewhere in the runtime code. Maybe I shall modify BoundsChecking pass to try to call this function name instead of __bounds_init? I'll try it and maybe send you what it did.


On 27 May 2016 at 17:05, Konstantin Serebryany <konstantin....@gmail.com> wrote:
llvm...@lists.llvm.org might be a better place for such questions, but let me try here. 

1. check that you have a proper symbol in the run-time library (*.a) using nm. 
From your code snippet I suspect that you may have forgotten to add extern "C"

I looked at the .a files present in my llvm build. There's a lot of these but after looking at two specifics ones (the names where significant to me) I found something relevant I guess:

- nm ./projects/compiler-rt/lib/asan/tests/libRTAsanTest.x86_64-with-calls.a | grep __bounds:
0000000000002720 T _Z13__bounds_initv

This is close to the one found in overflow_asan executable (only the address changes). Is this what I was supposed to look for?

Where should I add an extern "C"? I haven't wrote any in my code.
 

2. Run the compilation command line wit -v to verify that the linker flags and *.a files are passed as you would expect 

I ran the compilation with -fsanitize=bounds and here is the output concerning the linker part:
"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o overflow_bounds /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. -L/home/pierre/Desktop/build/bin/../lib -L/lib -L/usr/lib -whole-archive /home/pierre/Desktop/build/bin/../lib/clang/3.9.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a -no-whole-archive --dynamic-list=/home/pierre/Desktop/build/bin/../lib/clang/3.9.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a.syms /tmp/overflow-20c442.o --no-as-needed -lpthread -lrt -lm -ldl -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o

That's not pretty but this one, /home/pierre/Desktop/build/bin/../lib/clang/3.9.0/lib/linux/libclang_rt.ubsan_standalone-x86_64.a, is one of the .a files present in the llvm build. However inspecting this particular file with nm show it has no references to __bounds_init or similar. The problem might comes from here. Should I manually try to link the file with adding ./projects/compiler-rt/lib/asan/tests/libRTAsanTest.x86_64-with-calls.a found earlier?

 

3. again, using nm, check what functions are expected by the instrumented .o file. 

I ran "clang -c overflow.c" for -fsanitize=address and -fsanitize=bounds and outputed it in overflow_asan.o and overflow_bounds.o. Here are the results given by nm command:

- nm overflow_asan.o:
                                     U __asan_init
                                     U __asan_memset
0000000000000710 t asan.module_ctor
0000000000000740 t asan.module_dtor
                                     U __asan_option_detect_stack_use_after_return
                                     U __asan_register_globals
                                     U __asan_report_load4
                                     U __asan_report_store4
                                     U __asan_stack_malloc_0
                                     U __asan_stack_malloc_1
                                     U __asan_unregister_globals
                                     U __asan_version_mismatch_check_v8
                                     U free
0000000000000000 T heapOutOfBounds
                                     U __isoc99_scanf
00000000000004e0 T main
                                     U malloc
                                     U printf
0000000000000270 T stackOutOfBounds
0000000000000000 r .str
0000000000000040 r .str.1
0000000000000080 r .str.2
0000000000000000 d __unnamed_1

- nm overflow_bounds.o:
                                     U __bounds_init
                                     U check_v1
                                     U free
0000000000000000 T heapOutOfBounds
                                     U __isoc99_scanf
0000000000000190 T main
                                     U malloc
                                     U memset
                                     U printf
0000000000000080 T stackOutOfBounds
                                     U __ubsan_handle_out_of_bounds
0000000000000220 t __unnamed_3

So it seems the object file is waiting for __bounds_init to be linked?


 

hth. 

--kcc 


Thanks a lot again,
Pierre

Reply all
Reply to author
Forward
0 new messages