Description of problem: The grub file compiled when the src.rpm is built on a x86_64 system cannot execute since it is being dynamically linked incorrectly. When grub is run the error: [paris@paris x86_64]$ grub bash: /sbin/grub: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory is seen. Readelf -a shows a dynamic section (which is wrong since we want static linking) and also shows in the program header section: Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 [Requesting program interpreter: /usr/lib/libc.so.1] LOAD 0x000000 0x08048000 0x08048000 0x2afec 0x2afec R E 0x1000 LOAD 0x02b000 0x08073000 0x08073000 0x06ff8 0x12d20 RW 0x1000 DYNAMIC 0x02b014 0x08073014 0x08073014 0x000c8 0x000c8 RW 0x4 NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4 Where it is trying to use libc.so.1. If this were properly dynamically linked it would use ld-linux-x86-64.so.2. But shouldn't be doing this at all.... The problem seems to stem from the line where we actually create the grub binary which reads: gcc -fwritable-strings -m32 -Os -g -static -o grub main.o asmstub.o ../stage2/libgrub.a ../lib/libcommon.a -Wl,-Bstatic -lncurses -Wl,-Bdynamic Notice that we throw the -Wl,-Bdynamic on the end of the line. This little bit of code comes from the grub-0.95-staticcurses.patch which changes the autoconf to include this. The patch has: - AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -lncurses" + AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -Wl,-Bstatic -lncurses -Wl,-Bdynamic" All of the .o files were created correctly and statically, but the last binary is allowed this bit of dynamic linking. I hacked both the spec file and the patch to get this to work. My hack made the spec file have: %ifarch x86_64 CFLAGS="$CFLAGS -static" ; export CFLAGS DYNAMIC=static; export DYNAMIC %else DYNAMIC=dynamic; export DYNAMIC %endif And the patch to have (in both places): - AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -lncurses" + AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -Wl,-Bstatic -lncurses -Wl,-B$DYNAMIC" This way autoconf will let make decide on the fly what to put after the static ncurses linking. How reproducible: Always for me Steps to Reproduce: 1. Download src rpm 2. Run rpmbuild --rebuild src.rpm (or some varient) 3. Install the rpm 4. Try to run /sbin/grub Actual results: [paris@paris x86_64]$ grub bash: /sbin/grub: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory Expected results: Grub Starts
Okay, here's the deal: - We build grub in a build root with only ncurses-devel.x86_64 installed - Since we're building a 32 bit binary, the configure script doesn't find the ncurses library: checking for wgetch in -lncurses... no checking for wgetch in -lcurses... no - To verify that it's not built with ncurses, try running the "clear" command in /sbin/grub ... compare to i386 - If you try and re-build grub with ncurses-devel.i386 installed, then it creates a borked dynamically linked /sbin/grub due to the -Wl,-Bdynamic