0

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

sha
  • 614
  • 6
  • 16

1 Answers1

1

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.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thank you. That was a very clear explanation. So there's no easy way to hack up a malloc.so ? Also for curiosity, how did you trace down the reference to `__libc_multiple_threads` that you posted in the answer? – sha Apr 14 '17 at 06:53
  • @sha You certainly can build `malloc.so` using tcmalloc or jemalloc. But splitting out parts of glibc is not likely to work. – Employed Russian Apr 14 '17 at 14:18