https://sourceware.org/bugzilla/show_bug.cgi?id=34403

            Bug ID: 34403
           Summary: libelf.a bundles lib/crc32.o whose public crc32 symbol
                    collides with zlib's when statically linking —
                    eu-strip fails with "multiple definition of   crc32
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libelf
          Assignee: unassigned at sourceware dot org
          Reporter: robb at datalogics dot com
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Created attachment 16847
  --> https://sourceware.org/bugzilla/attachment.cgi?id=16847&action=edit
Makefile.am patch against elfutils 0.195

Since elfutils 0.193, statically linking the elfutils tools (or any consumer of
the installed libelf.a) together with a static zlib fails with a duplicate
  symbol error. Building 0.195 with BUILD_STATIC enabled against a static
libz.a (zlib 1.3.1, clang 21 / GNU ld 2.44, observed identically with earlier
  toolchains):

    CCLD     strip
  /usr/bin/ld: libz.a(crc32.c.o): in function `crc32':
  crc32.c:(.text+0x900): multiple definition of `crc32';
../libelf/libelf.a(crc32.o):crc32.c:(.text+0x0): first defined here
  clang: error: linker command failed with exit code 1 (use -v to see
invocation)
  make[2]: *** [Makefile:834: strip] Error 1

  Versions 0.190/0.191/0.192 link the same configuration successfully.

  Root cause:

  Commit f5d6e088f84dd ("Add libeu objects to libelf.a static archive", first
released in 0.193, the fix for bug #32293) makes libelf/Makefile.am bundle
every
  object listed in lib/libeu.manifest into libelf.a via libelf_a_LIBADD. That
manifest includes crc32.o, which exports a global, default-visibility crc32
symbol
  — the same name (and the same standard CRC-32) as zlib's.

  The failure sequence, confirmed with ld --trace-symbol:

  1. strip.o references crc32_file (for the .gnu_debuglink checksum). Scanning
libelf.a extracts crc32_file.o, whose crc32 reference is satisfied within the
  same archive by crc32.o. libelf.a now contributes a strong global crc32.
  2. -lz is scanned next: deflate.c.o/inflate.c.o are needed (libelf's
elf_compress uses them), and since zlib 1.2.12 deflate.c.o also references
crc32_z.
  elfutils' crc32.o does not define crc32_z, so the linker is forced to extract
libz.a(crc32.c.o) — which also defines crc32. Two strong definitions → hard
  error.

  Before 0.193 this could not happen: crc32.o/crc32_file.o lived only in the
internal libeu.a, which the tool link lines place after -lz. By the time
libeu.a
  was scanned, crc32 was already defined by zlib's crc32.c.o, so
libeu.a(crc32.o) was never extracted.

  Note the problem is not limited to the elfutils tools: the installed libelf.a
now exposes a public crc32, so any downstream program statically linking
  libelf.a alongside libz.a can hit the same collision in its own link (e.g. if
the application itself calls zlib's crc32() and links -lelf before -lz). Link
  reordering cannot fix it, because zlib's crc32.c.o is always required (for
crc32_z) whenever the compression code is pulled in.

  Suggested fix:

  Exclude crc32.o from the objects bundled into libelf.a. libelf's internal
users already go through the hidden __libelf_crc32 wrapper (libelf_crc32.o),
and
  libdwfl uses its own __libdwfl_crc32. The still-bundled crc32_file.o then
resolves crc32 from zlib, which is a hard dependency of libelf anyway
(functionally
  identical implementation — the .gnu_debuglink CRC is defined as the zlib
CRC-32). Patch against 0.195 attached.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to