This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 4/4] ld.so: Do not export free/calloc/malloc/realloc functions [BZ #25486]
* Florian Weimer:
> Exporting functions and relying on symbol interposition from libc.so
> makes the choice of implementation dependent on DT_NEEDED order, which
> is not what some compiler drivers expect.
>
> This commit replaces one magic mechanism (symbol interposition) with
> another one (preprocessor-/compiler-based redirection). This makes
> the hand-over from the minimal malloc to the full malloc more
> explicit.
>
> Removing the ABI symbols is backwards-compatible because libc.so is
> always in scope, and the dynamic loader will find the malloc-related
> symbols there since commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c
> ("ld.so: Support moving versioned symbols between sonames
> [BZ #24741]").
>
> Tested on aarch64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu,
> s390x-linux-gnu without the stack protector, and on x86_64-linux-gnu
> with stack-protector-strong. Also built with build-many-glibcs.py.
This commit breaks valgrind because it can no longer interpose the early
malloc, leading to tons of errors on at least aarch64:
==801990== Command: /root/build/elf/ld-linux-aarch64.so.1 --library-path /root/build:/root/build/math:/root/build/elf:/root/build/dlfcn:/root/build/nss:/root/build/nis:/root/build/rt:/root/build/resolv:/root/build/mathvec:/root/build/support:/root/build/crypt:/root/build/nptl /bin/true --help
==801990==
==801990== Conditional jump or move depends on uninitialised value(s)
==801990== at 0x197EA8: ??? (in /root/build/elf/ld.so)
==801990==
And this goes on and on. There's no stack trace here, so it's difficult
to pin down. (The toolchain used for this build is supposed to build
everything with -fasynchronous-unwind-tables, so I'm not sure why
there's no backtrace.)
I believe the location is in the index function:
0000000000017e10 <index>:
17e10: mov w4, #0x401 // #1025
17e14: movk w4, #0x4010, lsl #16
17e18: dup v0.16b, w1
17e1c: and x2, x0, #0xffffffffffffffe0
17e20: dup v16.4s, w4
17e24: ands x3, x0, #0x1f
17e28: add v7.4s, v16.4s, v16.4s
17e2c: b.eq 17e80 <index+0x70> // b.none
17e30: ld1 {v1.16b, v2.16b}, [x2], #32
17e34: neg x3, x3
17e38: cmeq v3.16b, v1.16b, #0
17e3c: cmeq v5.16b, v1.16b, v0.16b
17e40: cmeq v4.16b, v2.16b, #0
17e44: cmeq v6.16b, v2.16b, v0.16b
17e48: and v3.16b, v3.16b, v7.16b
17e4c: and v4.16b, v4.16b, v7.16b
17e50: and v5.16b, v5.16b, v16.16b
17e54: and v6.16b, v6.16b, v16.16b
17e58: orr v17.16b, v3.16b, v5.16b
17e5c: orr v18.16b, v4.16b, v6.16b
17e60: lsl x3, x3, #1
17e64: addp v17.16b, v17.16b, v18.16b
17e68: mov x5, #0xffffffffffffffff // #-1
17e6c: addp v17.16b, v17.16b, v18.16b
17e70: lsr x3, x5, x3
17e74: mov x5, v17.d[0]
17e78: bic x3, x5, x3
17e7c: cbnz x3, 17ed0 <index+0xc0>
17e80: ld1 {v1.16b, v2.16b}, [x2], #32
17e84: cmeq v3.16b, v1.16b, #0
17e88: cmeq v5.16b, v1.16b, v0.16b
17e8c: cmeq v4.16b, v2.16b, #0
17e90: cmeq v6.16b, v2.16b, v0.16b
17e94: orr v17.16b, v3.16b, v5.16b
17e98: orr v18.16b, v4.16b, v6.16b
17e9c: orr v17.16b, v17.16b, v18.16b
17ea0: addp v17.2d, v17.2d, v17.2d
17ea4: mov x3, v17.d[0]
17ea8: cbz x3, 17e80 <index+0x70>
17eac: and v3.16b, v3.16b, v7.16b
17eb0: and v4.16b, v4.16b, v7.16b
17eb4: and v5.16b, v5.16b, v16.16b
17eb8: and v6.16b, v6.16b, v16.16b
17ebc: orr v17.16b, v3.16b, v5.16b
17ec0: orr v18.16b, v4.16b, v6.16b
17ec4: addp v17.16b, v17.16b, v18.16b
17ec8: addp v17.16b, v17.16b, v18.16b
17ecc: mov x3, v17.d[0]
17ed0: sub x2, x2, #0x20
17ed4: rbit x3, x3
17ed8: clz x3, x3
17edc: tst x3, #0x1
17ee0: add x0, x2, x3, lsr #1
17ee4: csel x0, x0, xzr, eq // eq = none
17ee8: ret
I don't know why valgrind would think the memory is undefined at this
point.
Thanks,
Florian