Hi all, I've encountered a couple of minor build issues on Solaris that have crept in since 2.5, fixes below: 1. In lib/Target/X86/X86JITInfo.cpp, there is: // Check if building with -fPIC #if defined(__PIC__) && __PIC__ && defined(__linux__) #define ASMCALLSUFFIX "@PLT" #else #define ASMCALLSUFFIX #endif Which causes a link failure due to the non-PLT relocation that results. I'm not sure if this should be #if defined(__PIC__) && __PIC__ && (defined(__linux__) || defined(__sun__)) or #if defined(__PIC__) && __PIC__ && !defined(__APPLE__) or if it should be a configure test, which might be safer. Are there any x86 platforms (other than apple) that don't need PLT-indirect calls? 2. GenLibDeps.pl was changed in r73228 to remove the -g option from nm - this breaks with Sun nm, which needs the -g to emit output compatible with the regexps used in GenLibDeps.pl. Reverting this change works correctly (although it does print some warnings). The patch had the comment: Fix the SUS usage of `nm` on Unix platforms such as Solaris or AuroraUX; -u is undefined symbols, and says "those external to each object file" so using -g would seem redundant, The error message was as follows: "/usr/xpg4/bin/nm: -e or -g set, -u ignored". Actually it was the -u that's redundant - the -g was necessary for GenLibDeps.pl: $ nm -p -u libLLVMCore.a libLLVMCore.a[AsmWriter.o]: __asert atof _GLOBAL_OFFSET_TABLE_ isalnum ... etc ... $ nm -p -g libLLVMCore.a libLLVMCore.a[AsmWriter.o]: 0000000000 U __assert 0000000000 U atof 0000000000 U _GLOBAL_OFFSET_TABLE_ 0000000000 U isalnum The latter being what GenLibDeps.pl expects to see. All else being equal though, it might be better to change GenLibDeps.pl to recognize the first version: --- GenLibDeps.pl (revision 78653) +++ GenLibDeps.pl (working copy) @@ -100,7 +100,7 @@ print " <dt><b>$lib</b</dt><dd><ul>\n"; } open UNDEFS, - "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |"; + "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' -e 's/^ *//' | sort | uniq |"; my %DepLibs; while (<UNDEFS>) { chomp; Cheers, Nathan
Good day Nathan, If your using the stock GCC with Solaris, I am sorry to inform you its broken, Please see: http://llvm.org/docs/GettingStarted.html#brokengcc Please be warned as your get miss compiles and things will do strange `stuff`. As can be seen here, the reverse is true for both the GNU binutils and XPG4 versions of `nm' : -bash-3.2$ /usr/xpg4/bin/nm -p -u `find . -name libLLVMCore.a` | head ./Debug/lib/libLLVMCore.a[AsmWriter.o]: 0000000000 U __assert 0000000000 U __clzdi2 0000000000 U __udivdi3 0000000000 U __umoddi3 0000000000 U _GLOBAL_OFFSET_TABLE_ 0000000000 U _ZdaPv 0000000000 U _ZdlPv -bash-3.2$ /usr/bin/nm -p -u `find . -name libLLVMCore.a` | head ./Debug/lib/libLLVMCore.a[AsmWriter.o]: __assert __clzdi2 __udivdi3 __umoddi3 _GLOBAL_OFFSET_TABLE_ _ZdaPv _ZdlPv -bash-3.2$ /usr/bin/nm -p -g `find . -name libLLVMCore.a` | head ./Debug/lib/libLLVMCore.a[AsmWriter.o]: 0000000000 U __assert 0000000000 U __clzdi2 0000000000 T __i686.get_pc_thunk.bx 0000000000 T __i686.get_pc_thunk.cx 0000000000 U __udivdi3 0000000000 U __umoddi3 0000000000 U _GLOBAL_OFFSET_TABLE_ -bash-3.2$ /opt/gcc4/bin/nm -p -g `find . -name libLLVMCore.a` | head AsmWriter.o: 00000000 T __i686.get_pc_thunk.cx U _GLOBAL_OFFSET_TABLE_ 00000000 W _ZnwjPv 00000000 W _ZN4llvm24AssemblyAnnotationWriter17emitFunctionAnnotEPKNS_8FunctionERNS_11raw_ostreamE 00000000 W _ZN4llvm24AssemblyAnnotationWriter24emitBasicBlockStartAnnotEPKNS_10BasicBlockERNS_11raw_ostreamE 00000000 W _ZN4llvm24AssemblyAnnotationWriter22emitBasicBlockEndAnnotEPKNS_10BasicBlockERNS_11raw_ostreamE 00000000 W _ZN4llvm24AssemblyAnnotationWriter20emitInstructionAnnotEPKNS_11InstructionERNS_11raw_ostreamE 00000000 W _ZNK4llvm12PATypeHandlecvPNS_4TypeEEv -bash-3.2$ -bash-3.2$ -bash-3.2$ -bash-3.2$ /usr/bin/nm -p -u `find . -name libLLVMCore.a` | head ./Debug/lib/libLLVMCore.a[AsmWriter.o]: __assert __clzdi2 __udivdi3 __umoddi3 _GLOBAL_OFFSET_TABLE_ _ZdaPv _ZdlPv -bash-3.2$ /opt/gcc4/bin/nm -p -u `find . -name libLLVMCore.a` | head AsmWriter.o: U _GLOBAL_OFFSET_TABLE_ U _ZTVN4llvm11raw_ostreamE U _ZTVN4llvm14raw_os_ostreamE U _ZTVN4llvm18raw_string_ostreamE U _ZNKSs4sizeEv U _ZNKSsixEj U _ZNKSs5c_strEv U _ZNKSs6lengthEv I believe this is a bug in the version of `nm` your using, prob /usr/bin/nm . I recommend configuring your PATH differently and using the GCC from: http://pkg.auroraux.org/GCC/ ( Installs to /opt/gcc4 ) Cheers, Edward O'Callaghan. 2009/8/11 Nathan Keynes <Nathan.Keynes at sun.com>:> Hi all, > > I've encountered a couple of minor build issues on Solaris that > have crept in since 2.5, fixes below: > > 1. In lib/Target/X86/X86JITInfo.cpp, there is: > > // Check if building with -fPIC > #if defined(__PIC__) && __PIC__ && defined(__linux__) > #define ASMCALLSUFFIX "@PLT" > #else > #define ASMCALLSUFFIX > #endif > > Which causes a link failure due to the non-PLT relocation that > results. I'm not sure if this should be > #if defined(__PIC__) && __PIC__ && (defined(__linux__) || > defined(__sun__)) > > or > > #if defined(__PIC__) && __PIC__ && !defined(__APPLE__) > > or if it should be a configure test, which might be safer. Are there > any x86 platforms (other than apple) that don't need PLT-indirect calls? > > 2. GenLibDeps.pl was changed in r73228 to remove the -g option from nm > - this breaks with Sun nm, which needs the -g to emit output > compatible with the regexps used in GenLibDeps.pl. Reverting this > change works correctly (although it does print some warnings). > > The patch had the comment: > Fix the SUS usage of `nm` on Unix platforms such as Solaris or > AuroraUX; -u is undefined symbols, and says "those external to each > object file" so using -g would seem redundant, The error message > was > as follows: "/usr/xpg4/bin/nm: -e or -g set, -u ignored". > > Actually it was the -u that's redundant - the -g was necessary for > GenLibDeps.pl: > > $ nm -p -u libLLVMCore.a > libLLVMCore.a[AsmWriter.o]: > __asert > atof > _GLOBAL_OFFSET_TABLE_ > isalnum > ... etc ... > > $ nm -p -g libLLVMCore.a > libLLVMCore.a[AsmWriter.o]: > 0000000000 U __assert > 0000000000 U atof > 0000000000 U _GLOBAL_OFFSET_TABLE_ > 0000000000 U isalnum > > The latter being what GenLibDeps.pl expects to see. All else being > equal though, it might be better to change GenLibDeps.pl to recognize > the first version: > --- GenLibDeps.pl (revision 78653) > +++ GenLibDeps.pl (working copy) > @@ -100,7 +100,7 @@ > print " <dt><b>$lib</b</dt><dd><ul>\n"; > } > open UNDEFS, > - "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | > uniq |"; > + "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' -e 's/^ *//' > | sort | uniq |"; > my %DepLibs; > while (<UNDEFS>) { > chomp; > > Cheers, > Nathan > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- -- Edward O'Callaghan http://www.auroraux.org/ eocallaghan at auroraux dot org
Hello, Nathan> or if it should be a configure test, which might be safer. Are there > any x86 platforms (other than apple) that don't need PLT-indirect calls?Yes, mingw. However just tweaking the define is not enough - we're not loading address of GOT into ebx before the call (on 32 bit ABIs) thus the call will be to nowhere. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
On 19/08/2009, at 2:55 AM, Edward O'Callaghan wrote:> Good day Nathan, > > If your using the stock GCC with Solaris, I am sorry to inform you its > broken, Please see: > http://llvm.org/docs/GettingStarted.html#brokengcc > Please be warned as your get miss compiles and things will do > strange `stuff`.Hi Edward, Good to know - I think I've only built 32-bit versions with 3.4.3, so I haven't run into this particular bug there. I usually do the optimized and 64-bit builds with gcc 4.2 or 4.3.> As can be seen here, the reverse is true for both the GNU binutils and > XPG4 versions of `nm' :<snip nm examples>> I believe this is a bug in the version of `nm` your using, prob /usr/ > bin/nm .Yes, Sun nm (/usr/bin/nm) produces different output to GNU nm (and the XPG4 version is different again, yes), and always has as far as I know - this isn't a bug in nm per se. In any case LLVM 2.4 and 2.5 built correctly with /usr/bin/nm, so this seems like a regression to me. As I said, the best fix is probably to adjust the sed expression so that it can handle the output from /usr/bin/nm -p -u (or any other nm we know about). Cheers, Nathan
Hi Nathan,> The latter being what GenLibDeps.pl expects to see. All else being > equal though, it might be better to change GenLibDeps.pl to recognize > the first version: > --- GenLibDeps.pl (revision 78653) > +++ GenLibDeps.pl (working copy) > @@ -100,7 +100,7 @@ > print " <dt><b>$lib</b</dt><dd><ul>\n"; > } > open UNDEFS, > - "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | > uniq |"; > + "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' -e 's/^ *//' > | sort | uniq |"; > my %DepLibs; > while (<UNDEFS>) { > chomp;starting at line 123 there seems to be a by-hand version of the sed command. I guess this needs to be adjusted too. Probably sed can be used nowadays. Ciao, Duncan.
Duncan Sands wrote:> Hi Nathan, > > >> The latter being what GenLibDeps.pl expects to see. All else being >> equal though, it might be better to change GenLibDeps.pl to recognize >> the first version: >> --- GenLibDeps.pl (revision 78653) >> +++ GenLibDeps.pl (working copy) >> @@ -100,7 +100,7 @@ >> print " <dt><b>$lib</b</dt><dd><ul>\n"; >> } >> open UNDEFS, >> - "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | >> uniq |"; >> + "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' -e 's/^ *//' >> | sort | uniq |"; >> my %DepLibs; >> while (<UNDEFS>) { >> chomp; >> > > starting at line 123 there seems to be a by-hand version of the > sed command. I guess this needs to be adjusted too. Probably > sed can be used nowadays. >I'd adjust it to be able to run in the first place (attaching patch). It's intended to run exactly when nm fails to find dependencies, so die'ing out is pointless before it runs. If allowed to run, this supports Perls whose native C system command shell is cmd.exe: Strawberry Perl, ActivePerl, and any Perl built for Windows *other* than the MingW32 pre-built binaries. (cmd.exe chokes on the pipe into sed, causing the whole construct to fail.) If the first nm finds any dependencies at all, the by-hand version won't run. It's currently optimized for MingW32 nm. Kenneth -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: GenLibDeps.pl.patch URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090819/28dca16b/attachment.ksh>
On 19/08/2009, at 4:00 AM, Anton Korobeynikov wrote:> Hello, Nathan > >> or if it should be a configure test, which might be safer. Are there >> any x86 platforms (other than apple) that don't need PLT-indirect >> calls? > Yes, mingw. However just tweaking the define is not enough - we're notOk, so configure might be the way to go then, maybe something like the following? I haven't tested this on mingw, but it looks to do the right thing on Solaris, Linux + OS X. Index: lib/Target/X86/X86JITInfo.cpp ==================================================================--- X86/X86JITInfo.cpp (revision 79974) +++ X86/X86JITInfo.cpp (working copy) @@ -18,6 +18,7 @@ #include "llvm/Function.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Config/config.h" #include <cstdlib> #include <cstring> using namespace llvm; @@ -52,7 +53,7 @@ #define ASMPREFIX GETASMPREFIX(__USER_LABEL_PREFIX__) // Check if building with -fPIC -#if defined(__PIC__) && __PIC__ && defined(__linux__) +#if defined(__PIC__) && __PIC__ && defined(NEED_PLT_CALL) #define ASMCALLSUFFIX "@PLT" #else #define ASMCALLSUFFIX Index: autoconf/configure.ac ==================================================================--- autoconf/configure.ac (revision 79390) +++ autoconf/configure.ac (working copy) @@ -1150,6 +1150,11 @@ dnl Check, whether __dso_handle is present AC_CHECK_FUNCS([__dso_handle]) +AC_MSG_CHECKING([If your platform uses PLT-indirect calls]) +AC_COMPILE_IFELSE([[ __asm__ ("call dummy at PLT"); ]], [ + AC_DEFINE(NEED_PLT_CALL,[1], [PIC code requires PLT indirect calls]) + AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) + dnl See if the llvm-gcc executable can compile to LLVM assembly AC_CACHE_CHECK([whether llvm-gcc is sane],[llvm_cv_llvmgcc_sanity], [llvm_cv_llvmgcc_sanity="no"> loading address of GOT into ebx before the call (on 32 bit ABIs) thus > the call will be to nowhere.Good point, I didn't look closely enough at the calling sequence. I assume this has to be broken on Linux/x86 at the moment too? I've done up a quick and dirty implementation below for the sake of discussion, which compiles (and doesn't break lli), but hasn't been tested beyond that point as yet. Admittedly this adds even more versions of X86CompilationCallback, but the mixed version with #ifs seemed to be pretty hard to follow. Cheers, Nathan Index: X86/X86JITInfo.cpp ==================================================================--- X86/X86JITInfo.cpp (revision 79974) +++ X86/X86JITInfo.cpp (working copy) @@ -180,15 +181,148 @@ # endif #elif defined (X86_32_JIT) # ifndef _MSC_VER + +#if defined(__PIC__) && __PIC__ && defined(NEED_PLT_CALL) void X86CompilationCallback(void); asm( ".text\n" ".align 8\n" ".globl " ASMPREFIX "X86CompilationCallback\n" + ".local .local_got_stub\n" TYPE_FUNCTION(X86CompilationCallback) ASMPREFIX "X86CompilationCallback:\n" CFI(".cfi_startproc\n") "pushl %ebp\n" + CFI(".cfi_def_cfa_offset 12\n") + CFI(".cfi_offset %ebp, -12\n") + "movl %esp, %ebp\n" // Standard prologue + CFI(".cfi_def_cfa_register %ebp\n") + "pushl %eax\n" + CFI(".cfi_rel_offset %eax, 0\n") + "pushl %edx\n" // Save EAX/EDX/ECX + CFI(".cfi_rel_offset %edx, 4\n") + "pushl %ecx\n" + CFI(".cfi_rel_offset %ecx, 8\n") + "pushl %ebx\n" + CFI(".cfi_rel_offset %ebx, 12\n") + "subl $16, %esp\n" + "movl 4(%ebp), %eax\n" // Pass prev frame and return address + "movl %eax, 4(%esp)\n" + "movl %ebp, (%esp)\n" + "call .local_got_stub\n" + ".local_got_stub: \n" + "popl %ebx\n" + "addl $_GLOBAL_OFFSET_TABLE_+[.-.local_got_stub], %ebx\n" + "call " ASMPREFIX "X86CompilationCallback2" ASMCALLSUFFIX "\n" + "movl %ebp, %esp\n" // Restore ESP + CFI(".cfi_def_cfa_register %esp\n") + "subl $16, %esp\n" + CFI(".cfi_adjust_cfa_offset 16\n") + "popl %ebx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ebx\n") + "popl %ecx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ecx\n") + "popl %edx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %edx\n") + "popl %eax\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %eax\n") + "popl %ebp\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ebp\n") + "ret\n" + CFI(".cfi_endproc\n") + SIZE(X86CompilationCallback) + ); + + // Same as X86CompilationCallback but also saves XMM argument registers. + void X86CompilationCallback_SSE(void); + asm( + ".text\n" + ".align 8\n" + ".globl " ASMPREFIX "X86CompilationCallback_SSE\n" + ".local .local_got_stub_SSE\n" + TYPE_FUNCTION(X86CompilationCallback_SSE) + ASMPREFIX "X86CompilationCallback_SSE:\n" + CFI(".cfi_startproc\n") + "pushl %ebp\n" + CFI(".cfi_def_cfa_offset 12\n") + CFI(".cfi_offset %ebp, -12\n") + "movl %esp, %ebp\n" // Standard prologue + CFI(".cfi_def_cfa_register %ebp\n") + "pushl %eax\n" + CFI(".cfi_rel_offset %eax, 0\n") + "pushl %edx\n" // Save EAX/EDX/ECX + CFI(".cfi_rel_offset %edx, 4\n") + "pushl %ecx\n" + CFI(".cfi_rel_offset %ecx, 8\n") + "pushl %ebx\n" + CFI(".cfi_rel_offset %ebx, 12\n") + "andl $-16, %esp\n" // Align ESP on 16-byte boundary + // Save all XMM arg registers + "subl $64, %esp\n" + // FIXME: provide frame move information for xmm registers. + // This can be tricky, because CFA register is ebp (unaligned) + // and we need to produce offsets relative to it. + "movaps %xmm0, (%esp)\n" + "movaps %xmm1, 16(%esp)\n" + "movaps %xmm2, 32(%esp)\n" + "movaps %xmm3, 48(%esp)\n" + "subl $16, %esp\n" + "movl 4(%ebp), %eax\n" // Pass prev frame and return address + "movl %eax, 4(%esp)\n" + "movl %ebp, (%esp)\n" + "call .local_got_stub_SSE\n" + ".local_got_stub_SSE: \n" + "popl %ebx\n" + "addl $_GLOBAL_OFFSET_TABLE_+[.-.local_got_stub], %ebx\n" + "call " ASMPREFIX "X86CompilationCallback2" ASMCALLSUFFIX "\n" + "addl $16, %esp\n" + "movaps 48(%esp), %xmm3\n" + CFI(".cfi_restore %xmm3\n") + "movaps 32(%esp), %xmm2\n" + CFI(".cfi_restore %xmm2\n") + "movaps 16(%esp), %xmm1\n" + CFI(".cfi_restore %xmm1\n") + "movaps (%esp), %xmm0\n" + CFI(".cfi_restore %xmm0\n") + "movl %ebp, %esp\n" // Restore ESP + CFI(".cfi_def_cfa_register esp\n") + "subl $16, %esp\n" + CFI(".cfi_adjust_cfa_offset 16\n") + "popl %ebx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ebx\n") + "popl %ecx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ecx\n") + "popl %edx\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %edx\n") + "popl %eax\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %eax\n") + "popl %ebp\n" + CFI(".cfi_adjust_cfa_offset -4\n") + CFI(".cfi_restore %ebp\n") + "ret\n" + CFI(".cfi_endproc\n") + SIZE(X86CompilationCallback_SSE) + ); + +#else /* __PIC__ && NEED_PLT_CALL */ + void X86CompilationCallback(void); + asm( + ".text\n" + ".align 8\n" + ".globl " ASMPREFIX "X86CompilationCallback\n" + TYPE_FUNCTION(X86CompilationCallback) + ASMPREFIX "X86CompilationCallback:\n" + CFI(".cfi_startproc\n") + "pushl %ebp\n" CFI(".cfi_def_cfa_offset 8\n") CFI(".cfi_offset %ebp, -8\n") "movl %esp, %ebp\n" // Standard prologue @@ -292,6 +426,8 @@ CFI(".cfi_endproc\n") SIZE(X86CompilationCallback_SSE) ); +#endif /* !(__PIC__ && NEED_PLT_CALL) */ + # else void X86CompilationCallback2(intptr_t *StackPtr, intptr_t RetAddr);