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);