ports/bash4 --enable-static fails

Craig Rodrigues rodrigc at crodrigues.org
Thu May 10 04:20:13 UTC 2012

On Wed, May 9, 2012 at 2:37 PM, Sean Bruno <seanbru at yahoo-inc.com> wrote:
> I'm assuming that the recent jemalloc updates have broken something
> subtly that is now causing static symbol compilation to fail.
> ports/bash4 isn't the simplest case, but its the most obvious one that
> is in my face.
> http://people.freebsd.org/~sbruno/bash4_jemalloc.txt


The problem is here:
first defined here
/usr/lib/libc.a(jemalloc_jemalloc.o): In function `realloc':
jemalloc_jemalloc.c:(.text+0x2350): multiple definition of `realloc'
first defined here
/usr/lib/libc.a(jemalloc_jemalloc.o): In function `calloc':
jemalloc_jemalloc.c:(.text+0x24d0): multiple definition of `calloc'
first defined here
/usr/lib/libc.a(jemalloc_jemalloc.o): In function `malloc':
jemalloc_jemalloc.c:(.text+0x27a0): multiple definition of `malloc'
first defined here

Bash is trying to override the malloc() functions in libc with its own
implementation in lib/malloc/malloc.c .
I have seen this type of trick before 3rd party code that tries to
override the libc implementation of malloc() / free() with its own.

kan@ explained this to me before, but I don't know if I can explain it
as well as him, because it has to do
with how static linking works. :)

Basically, the malloc.o object from bash, *must* have implementations of
*all* the relevant functions in jemalloc_jemalloc.o in order for
malloc.o to properly override jemalloc_jemalloc.o.

If you have something like:
jemalloc_jemalloc.o  (libc)                   malloc.o (Bash)
===============                           =============
malloc()                                              malloc()
free()                                                   free()

the static linker will not be able to replace jemalloc_jemalloc.o from
libc with malloc.o from Bash,
because calloc() and realloc() symbols in jemalloc_jemalloc.o (libc)
do not exist malloc.o (Bash).

Since the linker can only deal with whole objects (.o files), it will
try to pull in both
jemalloc_jemalloc.o and malloc.o when doing static linking.

I may have got some of the details/explanation wrong, but I have fixed
something similar
to this in 3rd party code, when the layout of malloc() functions in
libc changed between FreeBSD 4 and FreeBSD 6.

What you need to do is:
   (1)  run nm or readelf on jemalloc_jemalloc.o,   then run nm or
readelf on malloc.o
   (2)  Look at the symbols in both
   (3)  Add the missing symbols to malloc.c in Bash

Craig Rodrigues
rodrigc at crodrigues.org

More information about the freebsd-current mailing list