bug-libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#35226: export-symbols-regex does not work with C++ mangled symbols o


From: philip . chimento
Subject: bug#35226: export-symbols-regex does not work with C++ mangled symbols on macOS
Date: Wed, 10 Apr 2019 23:59:01 -0700

Hi,

On macOS, it seems that libtool's export-symbols-regex option tests the mangled names of C++ symbols against the given regex, rather than the demangled names, when deciding which symbols to export.

When tested on other systems, it seems that C++ symbols are exported as expected, that is, by testing the demangled names.

Here is a small project that demonstrates the problem:

-----configure.ac-----
AC_INIT([wat], [0])
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CXX
LT_INIT([disable-static])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

-----Makefile.am-----
lib_LTLIBRARIES = libwat.la
libwat_la_LDFLAGS = $(AM_LDFLAGS) -export-symbols-regex "^[^_]"
libwat_la_SOURCES = wat.cpp wat.h
bin_PROGRAMS = wat
wat_LDADD = libwat.la
wat_SOURCES = main.cpp

-----wat.cpp-----
#include "wat.h"
int _private(void) { return 0; }
int csymbol(void) { return _private(); }
int mangledsymbol(void) { return _private(); }

-----wat.h-----
#pragma once
extern "C" int csymbol(void);
int mangledsymbol(void);

-----main.cpp-----
#include "wat.h"
int main(void) {
    return csymbol() + mangledsymbol();
}

The expected behaviour is that the project builds with no errors when executing autoreconf -if && ./configure && make.

However, on the affected system (macOS 10.13.6) this is the output of the link step:

/bin/sh ./libtool  --tag=CXX   --mode=link g++  -g -O2  -export-symbols-regex "^[^_]"  -o libwat.la -rpath /usr/local/lib wat.lo 
libtool: link: /usr/bin/nm -B  .libs/wat.o   | sed -n -e 's/^.*[     ]\([BCDEGRST][BCDEGRST]*\)[     ][     ]*_\([_A-Za-z][_A-Za-z0-9]*\)$/\1 _\2 \2/p' | sed '/ __gnu_lto/d' | /usr/bin/sed 's/.* //' | sort | uniq > .libs/libwat.exp
libtool: link: /usr/bin/grep -E -e "^[^_]" ".libs/libwat.exp" > ".libs/libwat.expT"
libtool: link: mv -f ".libs/libwat.expT" ".libs/libwat.exp"
libtool: link: sed 's|^|_|' < .libs/libwat.exp > .libs/libwat-symbols.expsym
libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libwat.0.dylib  .libs/wat.o    -g -O2   -install_name  /usr/local/lib/libwat.0.dylib -compatibility_version 1 -current_version 1.0 -Wl,-single_module -Wl,-exported_symbols_list,.libs/libwat-symbols.expsym
libtool: link: (cd ".libs" && rm -f "libwat.dylib" && ln -s "libwat.0.dylib" "libwat.dylib")
libtool: link: ( cd ".libs" && rm -f "libwat.la" && ln -s "../libwat.la" "libwat.la" )
/bin/sh ./libtool  --tag=CXX   --mode=link g++  -g -O2   -o wat main.o libwat.la
libtool: link: g++ -g -O2 -o .libs/wat main.o -Wl,-bind_at_load  ./.libs/libwat.dylib
Undefined symbols for architecture x86_64:
  "mangledsymbol()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [wat] Error 1

As you can see, mangledsymbol() is not exported, despite not beginning with an underscore and therefore matching the exported-symbols-regex.

A workaround, at least for the particular name mangling scheme used by GCC and Clang, is to give ^(_Z\d+)?[^_] as the regex. With this regex, the program builds as expected, demonstrating that the mangled symbol names are tested against the regex.

I'd guess that the symbols in libwat.exp should be filtered by demangled name, rather than mangled name. (Although, it looks like the list is generated using nm, so how this happens to work on systems with GNU nm, which also seems to have --no-demangle as the default, I don't know.)

Here are the library's symbols according to nm:

$ nm .libs/libwat.dylib
0000000000000fb0 t __Z13mangledsymbolv
0000000000000f90 t __Z8_privatev
0000000000000fa0 T _csymbol
                 U dyld_stub_binder
$ nm -demangle .libs/libwat.dylib
0000000000000fb0 t mangledsymbol()
0000000000000f90 t _private()
0000000000000fa0 T _csymbol
                 U dyld_stub_binder

Version information:

$ libtool --version
libtool (GNU libtool) 2.4.6
Written by Gordon Matzigkeit, 1996

Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ld -v
@(#)PROGRAM:ld  PROJECT:ld64-409.12
BUILD 17:47:51 Sep 25 2018
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em arm64e arm64_32
LTO support using: LLVM version 10.0.0, (clang-1000.11.45.5) (static support for 21, runtime is 21)
TAPI support using: Apple TAPI version 10.0.0 (tapi-1000.11.8.2)
$ nm --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  Optimized build.
  Default target: x86_64-apple-darwin17.7.0
  Host CPU: broadwell

Best regards,
--
Philip

reply via email to

[Prev in Thread] Current Thread [Next in Thread]