I want to build glibc malloc as a shared library instead of it being part of libc.so
I'm not using any chroot but directly trying to build it.
When I make glibc as a normal build, it outputs the command that is being used to build malloc namely:
gcc malloc.c -c -std=gnu99 -fgnu89-inline -O2 -Wall -Winline -Wundef -Wwrite-strings -fmerge-all-constants -frounding-math -g -Wstrict-prototypes -fPIC -DMORECORE_CLEARS=2 -I../include -I/home/sharath.g/glibc-2.20/build/malloc -I/home/sharath.g/glibc-2.20/build -I../sysdeps/unix/sysv/linux/x86_64/64 -I../sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/x86 -I../sysdeps/unix/sysv/linux/wordsize-64 -I../sysdeps/x86_64/nptl -I../sysdeps/unix/sysv/linux -I../sysdeps/nptl -I../sysdeps/pthread -I../sysdeps/gnu -I../sysdeps/unix/inet -I../sysdeps/unix/sysv -I../sysdeps/unix/x86_64 -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/x86_64/64 -I../sysdeps/x86_64/fpu/multiarch -I../sysdeps/x86_64/fpu -I../sysdeps/x86/fpu -I../sysdeps/x86_64/multiarch -I../sysdeps/x86_64 -I../sysdeps/x86 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64/wordsize-64 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754 -I../sysdeps/generic -I.. -I../libio -I. -D_LIBC_REENTRANT -include ../include/libc-symbols.h -DPIC -DSHARED -o /home/sharath.g/glibc-2.20/build/malloc/malloc.o -MD -MP -MF /home/sharath.g/glibc-2.20/build/malloc/malloc.os.dt -MT /home/sharath.g/glibc-2.20/build/malloc/malloc.os
As you can see, malloc is built using -fPIC
so I should be able to simply link it as a shared library.
However when I run this command
gcc -shared -Wl,-soname,libmalloc.so -shared -lpthread -lm -lrt -o /home/sharath.g/glibc-2.20/build/malloc/libmalloc.so /home/sharath.g/glibc-2.20/build/malloc/malloc.o
I get an error
relocation R_X86_64_PC32 against undefined symbol `__libc_multiple_threads' can not be used when making a shared object; recompile with -fPIC
I don't understand why this error shows up? clearly I've compiled malloc.c with -fPIC
I don't understand why this error shows up?
The symbol is referenced by malloc.o
via inline assembly, like so:
# 69 "../sysdeps/unix/sysv/linux/x86_64/lowlevellock.h"
#define __lll_trylock_asm "cmpl $0, __libc_multiple_threads(%%rip)\n\t" "je 0f\n\t" "lock; cmpxchgl %2, %1\n\t" "jmp 1f\n\t" "0:\tcmpxchgl %2, %1\n\t" "1:"
As such, it generates R_X86_64_PC32
relocation (normal calls to external routines generate R_X86_64_PLT32
relocations when compiled with -fPIC
). This form of assembly assumes that the symbol will be defined in the same ELF
image.
In the normal build, this symbol is defined as a hidden symbol (meaning it's defined inside libc.so.6
and is not exported from it) in nptl/libc_multiple_threads.c
.
Since you are not linking in libc_multiple_threads.o
into your libmalloc.so
, the symbol remains undefined, and the linker correctly complains: this symbol can't come from outside (wrong relocation for that) and isn't defined inside your libmalloc.so
.
You might think that simply linking in libc_mutiple_threads.os
would solve this, but you'll be wrong: your libmalloc.so
would behave as if your process is single-threaded, regardless of whether it actually is or not.
TL;DR: what you are trying to do is unlikely to work, except by accident. It is very likely to be broken in multiple ways, some of which could be quite subtle.