Hi, I have a script that can bootstrap a gcc/glibc/binutils toolchain
with any combination of $HOST and $TARGET. I have tested it with these
combinations:
BUILD: x86_64-unknown-linux-gnu
HOST: i686-unknown-linux-gnu
TARGET: i686-unknown-linux-gnu
BUILD: x86_64-unknown-linux-gnu
HOST: i686-unknown-linux-gnu
TARGET: mips-unknown-linux-gnu
Of course there were a variety of patches that went into fixing issues
in the above combinations, and I had to settle on some conventions that
I expect to work for all combinations, most relevant of which is setting
CFLAGS to "-fPIC -DPIC" when building a static version of glibc to be
used to link gcc against early in the bootstrapping process. This is
necessary because gcc will build libgcc_s.so, linked against libc.a, and
libc.a must have its object files built with -fPIC and -DPIC for those
object files to link into such a shared object library.
The problem I am running into now is when trying this combination:
BUILD: x86_64-unknown-linux-gnu
HOST: x86_64-unknown-linux-gnu
TARGET: mips-unknown-linux-gnu
I get this error:
>
/home/bji/buildtools/output/build/stage2/x86_64-unknown-linux-gnu/gcc/./gcc/xgcc
>
-B/home/bji/buildtools/output/build/stage2/x86_64-unknown-linux-gnu/gcc/./gcc/
>
-B/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/bin/
>
-B/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/lib/
> -isystem
>
/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/include
> -isystem
>
/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/sys-include
> -O2 -g -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall
> -Wwrite-strings -Wcast-qual -Wstrict-prototypes
> -Wmissing-prototypes -Wold-style-definition -isystem ./include
> -fPIC -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2
> -D__GCC_FLOAT_NOT_NEEDED -fno-stack-protector -shared
> -nodefaultlibs -Wl,--soname=libgcc_s.so.1
> -Wl,--version-script=libgcc.map -o ./libgcc_s.so.1.tmp -g -B./
> _muldi3_s.o _negdi2_s.o _lshrdi3_s.o _ashldi3_s.o _ashrdi3_s.o
> _cmpdi2_s.o _ucmpdi2_s.o _clear_cache_s.o
> _enable_execute_stack_s.o _trampoline_s.o __main_s.o _absvsi2_s.o
> _absvdi2_s.o _addvsi3_s.o _addvdi3_s.o _subvsi3_s.o _subvdi3_s.o
> _mulvsi3_s.o _mulvdi3_s.o _negvsi2_s.o _negvdi2_s.o _ctors_s.o
> _ffssi2_s.o _ffsdi2_s.o _clz_s.o _clzsi2_s.o _clzdi2_s.o
> _ctzsi2_s.o _ctzdi2_s.o _popcount_tab_s.o _popcountsi2_s.o
> _popcountdi2_s.o _paritysi2_s.o _paritydi2_s.o _powisf2_s.o
> _powidf2_s.o _powixf2_s.o _mulsc3_s.o _muldc3_s.o _mulxc3_s.o
> _divsc3_s.o _divdc3_s.o _divxc3_s.o _bswapsi2_s.o _bswapdi2_s.o
> _fixunssfsi_s.o _fixunsdfsi_s.o _fixunsxfsi_s.o _fixsfdi_s.o
> _fixdfdi_s.o _fixxfdi_s.o _fixunssfdi_s.o _fixunsdfdi_s.o
> _fixunsxfdi_s.o _floatdisf_s.o _floatdidf_s.o _floatdixf_s.o
> _floatundisf_s.o _floatundidf_s.o _floatundixf_s.o _divdi3_s.o
> _moddi3_s.o _udivdi3_s.o _umoddi3_s.o _udiv_w_sdiv_s.o
> _udivmoddi4_s.o addtf3_s.o divtf3_s.o multf3_s.o negtf2_s.o
> subtf3_s.o unordtf2_s.o fixtfsi_s.o fixunstfsi_s.o floatsitf_s.o
> floatunsitf_s.o fixtfdi_s.o fixunstfdi_s.o floatditf_s.o
> floatunditf_s.o fixtfti_s.o fixunstfti_s.o floattitf_s.o
> floatuntitf_s.o extendsftf2_s.o extenddftf2_s.o extendxftf2_s.o
> trunctfsf2_s.o trunctfdf2_s.o trunctfxf2_s.o getf2_s.o letf2_s.o
> eqtf2_s.o _divtc3_s.o _multc3_s.o _powitf2_s.o unwind-dw2_s.o
> unwind-dw2-fde-glibc_s.o unwind-sjlj_s.o gthr-gnat_s.o
> unwind-c_s.o emutls_s.o -lc && rm -f ./libgcc_s.so && if [ -f
> ./libgcc_s.so.1 ]; then mv -f ./libgcc_s.so.1
> ./libgcc_s.so.1.backup; else true; fi && mv ./libgcc_s.so.1.tmp
> ./libgcc_s.so.1 && ln -s libgcc_s.so.1 ./libgcc_s.so
>
/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/bin/ld:
>
/home/bji/buildtools/output/install/stage1/x86_64-unknown-linux-gnu/usr/lib/libc.a(libc-cancellation.o):
> relocation R_X86_64_PC32 against undefined symbol
> `__pthread_unwind' can not be used when making a shared object;
> recompile with -fPIC
>
/home/bji/buildtools/output/install/stage2/x86_64-unknown-linux-gnu/usr/x86_64-unknown-linux-gnu/bin/ld:
> final link failed: Bad value
The thing is, libc-cancellation.o WAS built with -fPIC and -DPIC, so
this error report is not accurate; here is how it was compiled:
> x86_64-unknown-linux-gnu-gcc
> ../nptl/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S -c
> -I../include
>
-I/home/bji/buildtools/output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl
> -I/home/bji/buildtools/output/build/stage1/x86_64-unknown-linux-gnu/glibc
> -I../sysdeps/x86_64/elf -I../nptl/sysdeps/unix/sysv/linux/x86_64
> -I../sysdeps/unix/sysv/linux/x86_64
> -I../sysdeps/unix/sysv/linux/wordsize-64
> -I../nptl/sysdeps/unix/sysv/linux -I../nptl/sysdeps/pthread
> -I../sysdeps/pthread -I../ports/sysdeps/unix/sysv/linux
> -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu
> -I../sysdeps/unix/common -I../sysdeps/unix/mman
> -I../sysdeps/unix/inet -I../nptl/sysdeps/unix/sysv
> -I../ports/sysdeps/unix/sysv -I../sysdeps/unix/sysv
> -I../sysdeps/unix/x86_64 -I../nptl/sysdeps/unix
> -I../ports/sysdeps/unix -I../sysdeps/unix -I../sysdeps/posix
> -I../sysdeps/x86_64/fpu -I../sysdeps/x86_64/multiarch
> -I../nptl/sysdeps/x86_64 -I../sysdeps/x86_64
> -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-96
> -I../sysdeps/ieee754/dbl-64/wordsize-64
> -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32
> -I../sysdeps/ieee754 -I../sysdeps/generic/elf
> -I../sysdeps/generic -I../nptl -I../ports -I.. -I../libio
> -I. -nostdinc -isystem
>
/home/bji/buildtools/output/install/stage1/x86_64-unknown-linux-gnu/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/include
> -isystem
>
/home/bji/buildtools/output/install/stage1/x86_64-unknown-linux-gnu/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/include-fixed
> -isystem /home/bji/buildtools/output/sources/kernel/x86_64
> -D_LIBC_REENTRANT -include ../include/libc-symbols.h -DASSEMBLER
> -fPIC -DPIC -Wa,--noexecstack -Wa,--noexecstack -o
>
/home/bji/buildtools/output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl/libc-cancellation.o
> -MD -MP -MF
>
/home/bji/buildtools/output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl/libc-cancellation.o.dt
> -MT
>
/home/bji/buildtools/output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl/libc-cancellation.o
However, something is definitely going on and I don't understand it.
Here is an objdump of libc-cancellation.o:
>
./output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl/libc-cancellation.o:
file format elf64-x86-64
>
./output/build/stage1/x86_64-unknown-linux-gnu/glibc/nptl/libc-cancellation.o
> architecture: i386:x86-64, flags 0x00000011:
> HAS_RELOC, HAS_SYMS
> start address 0x0000000000000000
>
> Sections:
> Idx Name Size VMA LMA File
off Algn
> 0 .text 000000bc 0000000000000000 0000000000000000
00000040 2**4
> CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
> 1 .data 00000000 0000000000000000 0000000000000000
000000fc 2**2
> CONTENTS, ALLOC, LOAD, DATA
> 2 .bss 00000000 0000000000000000 0000000000000000
000000fc 2**2
> ALLOC
> 3 .note.GNU-stack 00000000 0000000000000000 0000000000000000
000000fc 2**0
> CONTENTS, READONLY
> 4 .eh_frame 00000040 0000000000000000 0000000000000000
00000100 2**3
> CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
> SYMBOL TABLE:
> 0000000000000000 l d .text 0000000000000000 .text
> 0000000000000000 l d .data 0000000000000000 .data
> 0000000000000000 l d .bss 0000000000000000 .bss
> 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
> 0000000000000000 l d .note.GNU-stack 0000000000000000
.note.GNU-stack
> 0000000000000000 w *UND* 0000000000000000 __pthread_unwind
> 0000000000000000 g F .text 0000000000000052 .hidden
__libc_enable_asynccancel
> 0000000000000060 g F .text 000000000000005c .hidden
__libc_disable_asynccancel
>
>
> RELOCATION RECORDS FOR [.text]:
> OFFSET TYPE VALUE
> 000000000000004d R_X86_64_PC32 __pthread_unwind+0xfffffffffffffffc
>
>
> RELOCATION RECORDS FOR [.eh_frame]:
> OFFSET TYPE VALUE
> 0000000000000020 R_X86_64_PC32 .text
> 0000000000000034 R_X86_64_PC32 .text+0x0000000000000060
Yes, __pthread_unwind has a relocation record of type R_X86_64_PC32.
Why is this unacceptable when linking libgcc_s.so?
Here is the code in glibc that produces this symbol (from
nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S):
#ifdef IS_IN_libpthread
# ifdef SHARED
# define __pthread_unwind __GI___pthread_unwind
# endif
#else
# ifndef SHARED
.weak __pthread_unwind
# endif
#endif
I really don't understand what is going on here. But I do know that
lots of other object files in libc.a also have R_X86_64_PC32 symbols;
will all of these be a similar problem or is there something special
about __pthread_unwind?
Any advice would be greatly appreciated.
Thank you!
Bryan