[LLVMdev] Weird behavior of llvm-ld

Reid Spencer rspencer at reidspencer.com
Wed Aug 16 09:59:31 PDT 2006


Hi Bram,

Comments inline ..

On Wed, 2006-08-16 at 18:01 +0200, Bram Adams wrote:
> Hi,
> 
> I'm using LLVM 1.8 with the GCC4-frontend on a Slackware 10.2 box (GCC
> 3.3.6). When issuing the following command (line 14 in a script called
> manual.sh):
> 
> llvm-ld -O1 *.trans -L${SOME_LIB_DIR} -L${SOME_OTHER_LIB_DIR} -L
> ${LLVM_FRONT}/lib -lSOME_LIB -lSOME_OTHER_LIB -load=
> ${MY_LIB_DIR}/opt1.so -load=${MY_LIB_DIR}/opt2.so -debug-pass=Details
> -debug -o test
> 
> ... I get the following messages:
> 
> llvm-ld: warning: Supposed library 'SOME_OTHER_LIB' isn't a library.

The -l option is used to link libraries into the resulting executable.
I'm hoping "SOME_OTHER_LIB" is not the actual name and you're just
paraphrasing the actual command line. Note that native libraries are not
supported by llvm-ld at this time. It is expecting a bytecode library
that it can link into the program, hence the warning.

> ./manual.sh: line 14: 25492 Segmentation fault

Not sure what that is about.

> 
> When I invoke the same from within gdb, I get:
> 
> [Thread debugging using libthread_db enabled]
> [New Thread -1210504992 (LWP 25520)]
> llvm-ld: warning: Supposed library 'SOME_OTHER_LIB' isn't a library.
> 
> Program received signal SIGABRT, Aborted.
> [Switching to Thread -1210504992 (LWP 25520)]
> 0xb7dbb027 in raise () from /lib/tls/libc.so.6
> 
> ... with the following backtrace:
> 
> #0  0xb7dbb027 in raise () from /lib/tls/libc.so.6
> #1  0xb7dbc747 in abort () from /lib/tls/libc.so.6
> #2  0xb7eb6721 in uw_init_context_1 () from
> ${LLVM_FRONT}/lib/libgcc_s.so.1
> #3  0xbf9fd140 in ?? ()
> #4  0xbf9fcf20 in ?? ()
> #5  0x00000064 in ?? ()
> #6  0x082a02cd in llvm::Optimize (M=0x85bf330) at
> ${LLVM_SRC}/tools/llvm-ld/Optimize.cpp:180
> #7  0x082a7161 in main (argc=17, argv=0xbf9fd454, envp=0xbf9fd49c) at
> ${LLVM_SRC}/tools/llvm-ld/llvm-ld.cpp:467
> 
> The exception raised apparently was not caused by the first warning
> message, but resulted from the following snippet of
> ${LLVM_SRC}/tools/llvm-ld/Optimize.cpp (near line 180):
> std::vector<std::string> plugins = LoadableModules;
> for (std::vector<std::string>::iterator I = plugins.begin(), E =
> plugins.end(); I != E; ++I) {
>     sys::DynamicLibrary dll(I->c_str());
>     typedef void (*OptimizeFunc)(PassManager&,int);
>     OptimizeFunc OF = OptimizeFunc(
>         (intptr_t)dll.GetAddressOfSymbol("RunOptimizations"));
>     if (OF == 0) {
>       throw std::string("Optimization Module '") + *I +
>         "' is missing the RunOptimizations symbol";
>     }
>     (*OF)(Passes,OptLevel);
> }
> 
> The RunOptimizations-symbol is only mentioned briefly in the manual of
> llvm-ld:
> 
> -load module
> 
>         Load an optimization module, module, which is expected to be a
>         dynamic library that provides the function name
>         RunOptimizations. This function will be passed the
>         PassManager, and the optimization level (values 0-5 based on
>         the -On option). This function may add passes to the
>         PassManager that should be run. This feature allows the
>         optimization passes of llvm-ld to be extended.

Okay.

> Now, here are my two questions (finally ;-)) :
>       * Why is SOME_OTHER_LIB not a library from llvm-ld's point of
>         view? It's supposed to be a shared library needed by opt1.so
>         (my first optimization pass), and NOT by the source files
>         which are processed. Should I pass it in some other way than
>         by -lSOME_OTHER_LIB? Should/Can I pass it in the first place?

The -l option is used to specify a library to be linked with, not for
dependent symbols your loadable module requires. The loaded module must
be fully linked with all libraries it depends on.  So, no, your usage
isn't correct here.

>       * What's the meaning of RunOptimizations? This name is only
>         mentioned in the code snippet above and in the llvm-ld docs,
>         but nowhere else. Both opt1.so and opt2.so do show up using
>         opt, so it seems there is some incompatibility between opt and
>         llvm-ld. llvm-link apparently offers no alternative.

Yes, there is. The opt tool can run into symbol redefinition and
undefined references using its current mechanism of simply using static
constructors to define the passes to be run. llvm-ld takes a different
approach: it defines an interface function (RunOptimizations) that is
called by llvm-ld to transform the module. This gives the implementer of
the loaded module much more latitude in how the module is transformed.
Since the PassManager is passed to the RunOptimizations function as the
first argument, that function can alter the PassManager in any way it
pleases. Generally, it will add its own passes to the PassManager which
will then be run (later) by llvm-ld. 

Please note that llvm-ld is an unfinished tool and you are working at
the edge of its functionality.  I plan to complete this tool sometime
this year, but I have other higher priority things to work on. Also, the
LTO work may factor into a future redesign of this tool.

Hope this helps.

Reid.




More information about the llvm-dev mailing list