Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clang PGO and glibc on x86_64: ld.lld: error: duplicate symbol: __getcwd #86405

Open
ms178 opened this issue Mar 23, 2024 · 2 comments
Open

Clang PGO and glibc on x86_64: ld.lld: error: duplicate symbol: __getcwd #86405

ms178 opened this issue Mar 23, 2024 · 2 comments
Labels
clang Clang issues not falling into any other category lld

Comments

@ms178
Copy link

ms178 commented Mar 23, 2024

I am using the following PKGBUILD for Glibc where I inject the PGO-Flags. Clang version is: bbcfe6f:

# Maintainer: Marcus Seyfarth <marcus85@gmx.de>

pkgbase=glibc
pkgname=(glibc lib32-glibc)
pkgver=2.39
pkgrel=16.1
pkgdesc='GNU C Library'
arch=('x86_64')
url='https://www.gnu.org/software/libc'
license=('GPL' 'LGPL')
depends=('linux-api-headers' 'tzdata')
makedepends=('git' 'gd' 'python' 'lib32-gcc-libs')
optdepends=('perl: for mtrace'
            'gd: graph image generation with memusage')
backup=(etc/gai.conf
        etc/locale.gen
        etc/nscd.conf)
options=('staticlibs' '!lto' 'buildflags')
install=glibc.install
source=("git+https://sourceware.org/git/glibc.git#branch=azanella/clang"
#source=("git+https://sourceware.org/git/glibc.git"
        locale-gen
        locale.gen.txt
        lib32-glibc.conf
        malloc_tune.patch
        mathlto.patch
        #nostackshrink.patch
        tzselect-proper-zone-file.patch
        04-mandriva-va_args.patch
        05-mandriva-zstdcompressedlocals.patch
        06-mandriva-nss-crash.patch
        07-mandriva-nostrictaliasing.patch
        #08-mandriva-float.patch
        nptl.patch
        )
sha256sums=('SKIP'
            )

prepare() {

    mkdir -p glibc-build lib32-glibc-build

  [[ -d glibc-$pkgver ]] && ln -s glibc-$pkgver glibc

    local src
    for src in "${source[@]}"; do
        src="${src%%::*}"
        src="${src##*/}"
        [[ $src = *.patch ]] || continue
        echo "Applying patch $src..."
        patch --directory="glibc" --forward --strip=1 < "$src"
    done
}

build() {

  cd "$srcdir/glibc-build"

  echo "slibdir=/usr/lib" >> configparms
  echo "rtlddir=/usr/lib" >> configparms
  echo "sbindir=/usr/bin" >> configparms
  echo "rootsbindir=/usr/bin" >> configparms

  # Credits @allanmcrae
  # https://github.com/allanmcrae/toolchain/blob/f18604d70c5933c31b51a320978711e4e6791cf1/glibc/PKGBUILD
  # remove fortify for building libraries
  CFLAGS=${CFLAGS/-Wp,-D_FORTIFY_SOURCE=2/}

  "$srcdir/glibc/configure" \
      --prefix=/usr \
      --libdir=/usr/lib \
      --libexecdir=/usr/lib \
      --with-headers=/usr/include \
      --disable-bind-now \
      --without-selinux \
      --disable-fortify-source \
      --disable-systemtap \
      --disable-cet \
      --enable-kernel=6.8.1 \
      --enable-multi-arch \
      --disable-profile \
      --disable-crypt \
      --disable-werror

  # build libraries with fortify disabled
  echo "build-programs=no" >> configparms
  echo "CFLAGS += -g3 -mllvm -vp-counters-per-site=6 -fprofile-generate=/home/marcus/Downloads/glibc-%p.profraw" >> configparms
  echo "LDFLAGS += -g3 -mllvm -vp-counters-per-site=6 -fprofile-generate=/home/marcus/Downloads/glibc-%p.profraw" >> configparms
  make -O

  # re-enable fortify for programs
  sed -i "/build-programs=/s#no#yes#" configparms
  echo "CFLAGS += -Wp,-D_FORTIFY_SOURCE=0" >> configparms
  make -O

  # build info pages manually for reproducibility
  make info

  cd "$srcdir/lib32-glibc-build"
  export CC="clang -m32 -mfpmath=sse -mstackrealign"
  export CXX="clang++ -m32 -mfpmath=sse -mstackrealign"

  echo "slibdir=/usr/lib32" >> configparms
  echo "rtlddir=/usr/lib32" >> configparms
  echo "sbindir=/usr/bin" >> configparms
  echo "rootsbindir=/usr/bin" >> configparms

  "$srcdir/glibc/configure" \
      --host=i686-pc-linux-gnu \
      --prefix=/usr \
      --libdir=/usr/lib32 \
      --libexecdir=/usr/lib32 \
      --disable-cet \
      --enable-kernel=6.8.1 \
      --disable-bind-now \
      --without-selinux \
      --disable-fortify-source \
      --disable-systemtap \
      --disable-profile \
      --disable-crypt \
      --disable-sanity-checks \
      --disable-werror \
      "${_configure_flags[@]}"

  # build libraries with fortify disabled
  echo "build-programs=no" >> configparms
  echo "CFLAGS += -g3 -mllvm -vp-counters-per-site=6 -fprofile-generate=/home/marcus/Downloads/glibc-%p.profraw" >> configparms
  echo "LDFLAGS += -g3 -mllvm -vp-counters-per-site=6 -fprofile-generate=/home/marcus/Downloads/glibc-%p.profraw" >> configparms
  make -O

  # re-enable fortify for programs
  sed -i "/build-programs=/s#no#yes#" configparms
  echo "CFLAGS += -Wp,-D_FORTIFY_SOURCE=0" >> configparms
  make -O

  # pregenerate C.UTF-8 locale until it is built into glibc
  # (https://sourceware.org/glibc/wiki/Proposals/C.UTF-8, FS#74864)
  elf/ld.so --library-path "$PWD" locale/localedef -c -f ../glibc/localedata/charmaps/UTF-8 -i ../glibc/localedata/locales/C ../C.UTF-8/
}

# Credits for skip_test() and check() @allanmcrae
# https://github.com/allanmcrae/toolchain/blob/f18604d70c5933c31b51a320978711e4e6791cf1/glibc/PKGBUILD
skip_test() {
  test=${1}
  file=${2}
  sed -i "s/\b${test}\b//" "${srcdir}"/glibc/${file}
}

check() (
  cd glibc-build

  # adjust/remove buildflags that cause false-positive testsuite failures
  sed -i '/FORTIFY/d' configparms                                     # failure to build testsuite
  sed -i 's/-Werror=format-security/-Wformat-security/' config.make   # failure to build testsuite
  sed -i '/CFLAGS/s/-fno-plt//' config.make                           # 16 failures
  sed -i '/CFLAGS/s/-fexceptions//' config.make                       # 1 failure
  LDFLAGS=${LDFLAGS/,-z,now/}                                         # 10 failures

  # The following tests fail due to restrictions in the Arch build system
  # The correct fix is to add the following to the systemd-nspawn call:
  # --system-call-filter="@clock @memlock @pkey"
  _skip_test test-errno-linux        sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-mlock2              sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-ntp_gettime         sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-ntp_gettimex        sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-pkey                sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-process_mrelease    sysdeps/unix/sysv/linux/Makefile
  _skip_test tst-adjtime             time/Makefile

  make -O check
)

package_glibc() {
  pkgdesc='GNU C Library'
  depends=('linux-api-headers>=4.10' tzdata filesystem)
  optdepends=('gd: for memusagestat'
              'perl: for mtrace')
  install=glibc.install
  backup=(etc/gai.conf
          etc/locale.gen
          etc/nscd.conf)

  make -C glibc-build install_root="$pkgdir" install
  rm -f "$pkgdir"/etc/ld.so.cache

  # Shipped in tzdata
  rm -f "$pkgdir"/usr/bin/{tzselect,zdump,zic}

  cd glibc

  install -dm755 "$pkgdir"/usr/lib/{locale,systemd/system,tmpfiles.d}
  install -m644 nscd/nscd.conf "$pkgdir/etc/nscd.conf"
  install -m644 nscd/nscd.service "$pkgdir/usr/lib/systemd/system"
  install -m644 nscd/nscd.tmpfiles "$pkgdir/usr/lib/tmpfiles.d/nscd.conf"
  install -dm755 "$pkgdir/var/db/nscd"

  install -m644 posix/gai.conf "$pkgdir"/etc/gai.conf

  install -m755 "$srcdir/locale-gen" "$pkgdir/usr/bin"

  # Create /etc/locale.gen
  install -m644 "$srcdir/locale.gen.txt" "$pkgdir/etc/locale.gen"
  sed -e '1,3d' -e 's|/| |g' -e 's|\\| |g' -e 's|^|#|g' \
    "$srcdir/glibc/localedata/SUPPORTED" >> "$pkgdir/etc/locale.gen"

  # install C.UTF-8 so that it is always available
  install -dm755 "$pkgdir/usr/lib/locale"
  cp -r "$srcdir/C.UTF-8" -t "$pkgdir/usr/lib/locale"
  sed -i '/#C\.UTF-8 /d' "$pkgdir/etc/locale.gen"

  # Provide tracing probes to libstdc++ for exceptions, possibly for other
  # libraries too. Useful for gdb's catch command.
  #install -Dm644 "$srcdir/sdt.h" "$pkgdir/usr/include/sys/sdt.h"
  #install -Dm644 "$srcdir/sdt-config.h" "$pkgdir/usr/include/sys/sdt-config.h"
}

package_lib32-glibc() {
  pkgdesc='GNU C Library (32-bit)'
  depends=("glibc=$pkgver")
  options+=('!emptydirs')

  cd lib32-glibc-build

  make install_root="$pkgdir" install
  rm -rf "$pkgdir"/{etc,sbin,usr/{bin,sbin,share},var}

  # We need to keep 32 bit specific header files
  find "$pkgdir/usr/include" -type f -not -name '*-32.h' -delete

  # Dynamic linker
  install -d "$pkgdir/usr/lib"
  ln -s ../lib32/ld-linux.so.2 "$pkgdir/usr/lib/"

  # Add lib32 paths to the default library search path
  install -Dm644 "$srcdir/lib32-glibc.conf" "$pkgdir/etc/ld.so.conf.d/lib32-glibc.conf"

  # Symlink /usr/lib32/locale to /usr/lib/locale
  ln -s ../lib/locale "$pkgdir/usr/lib32/locale"
}

I see the following error:

ld.lld: error: duplicate symbol: __getcwd
>>> defined at getcwd.c:49 (../sysdeps/unix/sysv/linux/getcwd.c:49)
>>>            /tmp/makepkg/glibc/src/glibc-build/elf/dl-allobjs.os:(__getcwd)
>>> defined at getcwd.c:49 (/tmp/makepkg/glibc/src/glibc/io/../sysdeps/unix/sysv/linux/getcwd.c:49)
>>>            getcwd.os:(__GI___getcwd) in archive /tmp/makepkg/glibc/src/glibc-build/libc_pic.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:1309: /tmp/makepkg/glibc/src/glibc-build/elf/librtld.map] error 1

Flags in /etc/makepkg.conf:

export CC=clang
export CXX=clang++
export CC_LD=lld
export CXX_LD=lld
export AR=llvm-ar
export NM=llvm-nm
export STRIP=llvm-strip
export OBJCOPY=llvm-objcopy
export OBJDUMP=llvm-objdump
export READELF=llvm-readelf
export RANLIB=llvm-ranlib
export HOSTCC=clang
export HOSTCXX=clang++
export HOSTAR=llvm-ar
export CPPFLAGS="-D_FORTIFY_SOURCE=0"
export CFLAGS="-O3 -march=native -mtune=native -maes -mbmi2 -mpclmul -mllvm -inline-threshold=1500 -mllvm -extra-vectorizer-passes -mllvm -enable-cond-stores-vec -mllvm -slp-vectorize-hor-store -mllvm -enable-loopinterchange -mllvm -enable-loop-distribute -mllvm -enable-unroll-and-jam -mllvm -enable-loop-flatten -mllvm -unroll-runtime-multi-exit -mllvm -aggressive-ext-opt -mllvm -enable-interleaved-mem-accesses -mllvm -enable-masked-interleaved-mem-accesses -fno-math-errno -falign-functions=32 -funroll-loops -fomit-frame-pointer -mprefer-vector-width=256 -mllvm -adce-remove-loops -mllvm -enable-ext-tsp-block-placement -mllvm -enable-gvn-hoist -mllvm -enable-dfa-jump-thread -fcf-protection=none -mharden-sls=none -Wno-error -fgnuc-version=6.5.0"
export CXXFLAGS="${CFLAGS} -Wp,-U_GLIBCXX_ASSERTIONS"
export LDFLAGS="-Wl,-O3,--as-needed -Wl,-mllvm -Wl,-extra-vectorizer-passes -Wl,-mllvm -Wl,-enable-cond-stores-vec -Wl,-mllvm -Wl,-slp-vectorize-hor-store -Wl,-mllvm -Wl,-enable-loopinterchange -Wl,-mllvm -Wl,-enable-loop-distribute -Wl,-mllvm -Wl,-enable-unroll-and-jam -Wl,-mllvm -Wl,-enable-loop-flatten -Wl,-mllvm -Wl,-unroll-runtime-multi-exit -Wl,-mllvm -Wl,-aggressive-ext-opt -Wl,-mllvm -Wl,-enable-interleaved-mem-accesses -Wl,-mllvm -Wl,-enable-masked-interleaved-mem-accesses -march=native -maes -mbmi2 -mpclmul -fuse-ld=lld -Wl,-zmax-page-size=0x200000 -Wl,-mllvm -Wl,-adce-remove-loops -Wl,-mllvm -Wl,-enable-ext-tsp-block-placement -Wl,-mllvm -Wl,-enable-gvn-hoist -Wl,-mllvm -Wl,-enable-dfa-jump-thread -Wl,--undefined-version -fcf-protection=none -mharden-sls=none"
export CCLDFLAGS="$LDFLAGS"
export CXXLDFLAGS="$LDFLAGS"
export ASFLAGS="-D__AVX__=1 -D__AVX2__=1 -D__FMA__=1"
@github-actions github-actions bot added clang Clang issues not falling into any other category lld labels Mar 23, 2024
@ms178
Copy link
Author

ms178 commented Mar 23, 2024

@zatrazz To not derail the BOLT thread any further, this is another unique issue at the moment with your Clang/Glibc branch. The idea was to gather PGO data from the test run, but adding the neccessary flags leads to the reported duplicate symbol error.

@ms178
Copy link
Author

ms178 commented Mar 23, 2024

I've tried mold, bfd and gold which also all error out. Gold throws the best error messages:

/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member GCDAProfiling.c.o at 4640 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfiling.c.o at 44444 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingInternal.c.o at 58096 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingValue.c.o at 64924 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingBuffer.c.o at 105932 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingFile.c.o at 124548 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingMerge.c.o at 175920 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingMergeFile.c.o at 188824 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingNameVar.c.o at 196276 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingVersionVar.c.o at 199500 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingWriter.c.o at 202732 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformAIX.c.o at 224796 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformDarwin.c.o at 227880 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformFuchsia.c.o at 230972 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformLinux.c.o at 234064 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformOther.c.o at 246728 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingPlatformWindows.c.o at 249816 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingRuntime.cpp.o at 252908 is not an ELF object
/usr/bin/ld.gold: error: /usr/lib/clang/19/lib/x86_64-pc-linux-gnu/libclang_rt.profile.a: member InstrProfilingUtil.c.o at 259812 is not an ELF object
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [../Makerules:601: /tmp/makepkg/glibc/src/glibc-build/libc_pic.os] error 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category lld
Projects
None yet
Development

No branches or pull requests

1 participant