opt -load error on Darwin

Hi,

I am following the instructions on Writing an LLVM Pass on Darwin(8.7.0) powerpc. The loadable library is built. But "opt -load " gives error saying “Symbol not found”. I am using LLVM 1.8. Could someone tell me how to fix it? I have tried the same procedure on Pentium4 Redhat9. Everything is ok there. So I think there must be some specific problem on Darwin that I should pay attention to. But what is it?

Here is how I got this error.

After installing cfrontend3.4 and LLVM, I included cfrontend-bin and LLVM-installed-bin in PATH. I also set LLVM_LIB_SEARCH_PATH to be cfrontend-lib.

I copied Hello.cpp and Makefile to ~/tools/build-ppc/lib/Transforms/Hello and built the library.

pollux:~/tools/build-ppc/lib/Transforms/Hello $ make
llvm[0]: Compiling Hello.cpp for Release build (PIC)
llvm[0]: Linking Release Shared Library LLVMHello.so
llvm[0]: Linking Release Object Library LLVMHello.o

The loadable library was found on ~/tools/build-pcc/Release/lib.

pollux:~/tools/build-ppc/Release/lib $ file LLVMHello*
LLVMHello.0.0.0.so: Mach-O bundle ppc
LLVMHello.0.so: symbolic link to LLVMHello.0.0.0.so' LLVMHello.a: current ar archive LLVMHello.la: ASCII English text LLVMHello.o: Mach-O object ppc LLVMHello.so: symbolic link to LLVMHello.0.0.0.so’

But when I ran opt -load, it said “symbol not found”.

pollux:~/test $ opt -load /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so -help
Error opening ‘/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so’: Can’t open :/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so: dlopen(/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so, 9): Symbol not found: __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
Referenced from: /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so
Expected in: flat namespace

I guess the problem is that the library who implements the symbol was not found at run time, or the lib path information was not given to LLVMHello correctly at link time. I am new to Darwin. I have tried to set LD_LIBRARY_PATH to be llvm-installed-lib, and rebuilt LLVMHello. No difference was found. What shall I do to fix it? Any information is appreciated.

Thanks,

Jing

Hi,

Hi Jing,

I am following the instructions on Writing an LLVM Pass on
Darwin(8.7.0) powerpc. The loadable library is built. But "opt -load
" gives error saying "Symbol not found". I am using LLVM 1.8. Could
someone tell me how to fix it? I have tried the same procedure on
Pentium4 Redhat9. Everything is ok there. So I think there must be
some specific problem on Darwin that I should pay attention to. But
what is it?

Here is how I got this error.

After installing cfrontend3.4 and LLVM, I included cfrontend-bin and
LLVM-installed-bin in PATH. I also set LLVM_LIB_SEARCH_PATH to be
cfrontend-lib.

I copied Hello.cpp and Makefile to
~/tools/build-ppc/lib/Transforms/Hello and built the library.

pollux:~/tools/build-ppc/lib/Transforms/Hello $ make
llvm[0]: Compiling Hello.cpp for Release build (PIC)
llvm[0]: Linking Release Shared Library LLVMHello.so
llvm[0]: Linking Release Object Library LLVMHello.o

The loadable library was found on ~/tools/build-pcc/Release/lib.

pollux:~/tools/build-ppc/Release/lib $ file LLVMHello*
LLVMHello.0.0.0.so: Mach-O bundle ppc
LLVMHello.0.so: symbolic link to `LLVMHello.0.0.0.so'
LLVMHello.a: current ar archive
LLVMHello.la: ASCII English text
LLVMHello.o: Mach-O object ppc
LLVMHello.so: symbolic link to `LLVMHello.0.0.0.so'

But when I ran opt -load, it said "symbol not found".

pollux:~/test $ opt
-load /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so -help
Error opening
'/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so': Can't
open :/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so:
dlopen(/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so, 9):
Symbol not found:
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
  Referenced
from: /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so
  Expected in: flat namespace

This corresponds to:
FunctionPass::addToPassManager(llvm::FunctionPassManagerT*,
llvm::AnalysisUsage&)
which should be linked into "opt". It is part of libLLVMCore.a

I guess the problem is that the library who implements the symbol was
not found at run time, or the lib path information was not given to
LLVMHello correctly at link time.

I don't know. It works fine on Linux. This could be a darwin linking
issue. Please note that we upgraded the ltdl library used to load
Darwin shared objects after release 1.8. There were libtool release
notes that indicated better support for Darwin so we upgraded to
1.5.22.

You may want to apply the same patches to your 1.8 sources and rebuild.
That *might* help. The diffs are attached for lib/System/ltdl.h and
lib/System/ltdl.c

I am new to Darwin. I have tried to set LD_LIBRARY_PATH to be
llvm-installed-lib, and rebuilt LLVMHello. No difference was found.

Yeah, I don't think its so much a problem with building LLVM or
LLVMHello. Rather, its the way shared libraries work on Darwin.

What shall I do to fix it? Any information is appreciated.

My idea is above. Others (who know Darwin much better) might have other
ideas.

Thanks,

Jing

Sure.

Reid.

diffs (19.1 KB)

Thank you, Reid.

I have applied tha patch to ltdl.c ltdl.h. The problem still exists. I looked up the symbol on libLLVMCore.a, and found three U-entries and one T-entry. However, the Darwin linker is not able to find the T-entry. Any idea?

pollux:~/test jingyu$ opt -load /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so -help
Error opening ‘/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so’: Can’t open :/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so: dlopen(/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so, 9): Symbol not found:__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
Referenced from: /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so
Expected in: flat namespace

pollux:~/tools/build-ppc/Release/lib jingyu$ nm libLLVMCore.a | grep __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
U __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
U __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
00004100 T __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
000197d8 S __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE.eh
U __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

Jing

Thank you, Reid.

I have applied tha patch to ltdl.c ltdl.h. The problem still exists.

Okay, I guess that wasn't it.

I looked up the symbol on libLLVMCore.a, and found three U-entries and
one T-entry. However, the Darwin linker is not able to find the
T-entry. Any idea?

Nope. I think you're going to have to get some Darwin specific help on
this one. I don't have a Mac so I can't replicate your situation. The
Apple guys will be working tomorrow, so hopefully they can take a look
at it.

pollux:~/test jingyu$ opt
-load /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so -help
Error opening
'/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so': Can't
open :/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so:
dlopen(/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so, 9):
Symbol not
found:__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
  Referenced
from: /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so
  Expected in: flat namespace

Oh, one other thing you could try. Add LLVMCore.a to the USED_LIBS line
in the lib/Transforms/Hello/Makefile file. This should link the
addToPassManager method into the shared object, which might allow the
pass to register.

pollux:~/tools/build-ppc/Release/lib jingyu$ nm libLLVMCore.a | grep
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
         U
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
         U
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
00004100 T
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

Yes, this is the definition of the symbol. Not sure why the linker can't
find it. I think on Darwin the runtime loader can't open the executable.
But, I thought that problem was resolved with the ltdl.{c,h} change that
you already implemented. As I said before, you're going to need some
help from someone that knows Darwin better than I do.

000197d8 S
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE.eh
         U
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

Jing

Reid.

I don't really have any ideas beyond what Reid has already said, but:

pollux:~/test jingyu$ opt -load
/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so -help
Error opening '/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so':
Can't open :/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so:
dlopen(/Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so, 9): Symbol
not
found:__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE
  Referenced from: /Users/jingyu/tools/build-ppc/Release/lib/LLVMHello.so
  Expected in: flat namespace

pollux:~/tools/build-ppc/Release/lib jingyu$ nm libLLVMCore.a | grep

Try using 'nm -m' on the 'opt' executable itself. Using plain nm on my local one yields:
00121a4e T __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

and nm -m shows:
00121a4e (__TEXT,__text) external __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

Is this what you're seeing? Are you using llvm 1.8 or CVS? You might try CVS if 1.8 doesn't work for you.

-Chris

I am using llvm 1.8 and have patched ltdl.c and ltdl.h to the latest version.

My Makefile has LLVMLIBS = LLVMCore.a LLVMSupport.a LLVMSystem.a included.

Try using ‘nm -m’ on the ‘opt’ executable itself. Using plain nm on my
local one yields:
00121a4e T __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

and nm -m shows:
00121a4e (__TEXT,__text) external
__ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13AnalysisUsageE

Is this what you’re seeing? Are you using llvm 1.8 or CVS? You might try
CVS if 1.8 doesn’t work for you.

Here is what I am seeing with nm. Is it normal to have a .eh entry that I did not see on Pentium4?

$nm opt | grep __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPass
001b8d90 T __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13Analys
isUsageE
00380b64 S __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPassManagerTERNS_13Analys
isUsageE.eh

$ nm -m opt | grep __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPass
001b8d90 (__TEXT,__text) external __ZN4llvm12FunctionPass16addToPassManagerEPNS_20FunctionPa
ssManagerTERNS_13AnalysisUsageE
00380b64 (__TEXT,__eh_frame) external __ZN4llvm12FunctionPass16addToPassManagerEPNS_20Functi
onPassManagerTERNS_13AnalysisUsageE.eh

I will try the CVS version.

Thanks,

Jing

The CVS version solves the linking problem.

Thanks,

Jing