Problematic clang code generation with -O0 - clang

The following snippet:
#include <string>
#include <iostream>
int main()
{
std::string s = std::to_string(5);
std::cout << s << std::endl;
return 0;
}
Fails to link with Clang 3.6 on windows (accompanied with gcc 4.8.2 headers and libraries) when given the following options:
clang++ -std=c++11 -static -O0 bug.cpp
Please note that with -O2 the snippet compiles and links fine, so i suspect it may be some kind of clang bug.
EDIT 1:
I forgot to put the link error:
F:/Programs/LLVM/bin/../lib/gcc/i686-w64-mingw32/4.8.2\libstdc++.a(string-inst.o):(.text$_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag[__ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag]+0x0): multiple definition of
`char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag)'
C:\Users\THEART~1\AppData\Local\Temp\bug-b5df09.o:(.text[__ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag]+0x0): first defined here
F:/Programs/LLVM/bin/../lib/gcc/i686-w64-mingw32/4.8.2\libstdc++.a(string-inst.o):(.text$_ZNSsC2IPcEET_S1_RKSaIcE[__ZNSsC2IPcEET_S1_RKSaIcE]+0x0): multiple definition of `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char*>(char*, char*, std::allocator<char> const&)'
C:\Users\THEART~1\AppData\Local\Temp\bug-b5df09.o:(.text[__ZNSsC2IPcEET_S1_RKSaIcE]+0x0): first defined here
F:/Programs/LLVM/bin/../lib/gcc/i686-w64-mingw32/4.8.2/../../../../i686-w64-mingw32/bin/ld.exe: C:\Users\THEART~1\AppData\Local\Temp\bug-b5df09.o: bad reloc address 0x10 in section `.text[__ZSt9to_stringi]'
collect2.exe: error: ld returned 1 exit status
clang++.exe: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
EDIT 2:
I've been asked why i added the static flag in the compilation flags.
My purpose was to generate full static linked executables without the need of some gcc dlls (libstdc++6.dll libwinpthread.dll etc) so i have mostly been compiling with this command:
clang++ -std=c++11 -static -static-libstdc++ -static-libgcc -O0 bug.cpp
that i've been using with gcc too to generate full static executables.
After some experimenting i noticed that the combination of -static and -O0 flags is the problematic one so i omitted the others to not create any confusion.

Related

Can't link libFuzzer.a using clang with libc++

I'm trying to link together:
libFuzzer.a, compiled with clang++-5.0 and -std=c++11
my fuzz driver, compiled with clang++-5.0 and -std=c++11 -stdlib=libc++
libcurl, compiled with clang-5.0
Specifically, this linker command is being executed:
/bin/bash ../../libtool --silent --tag=CXX --mode=link clang++-5.0 -I../../include -I../../lib -I../../lib -I../../tests/fuzz -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -std=c++11 -stdlib=libc++ -o curl_fuzzer curl_fuzzer-curl_fuzzer.o ../../lib/libcurl.la /root/checkouts/Fuzzer/libFuzzer.a -lssh2 -lssl -lcrypto -lssl -lcrypto -lz -lpthread -lm
Executing this command outputs the following:
/bin/bash ../../libtool --silent --tag=CXX --mode=link clang++-5.0 -I../../include -I../../lib -I../../lib -I../../tests/fuzz -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp -std=c++11 -stdlib=libc++ -o curl_fuzzer curl_fuzzer-curl_fuzzer.o ../../lib/libcurl.la /root/checkouts/Fuzzer/libFuzzer.a -lssh2 -lssl -lcrypto -lssl -lcrypto -lz -lpthread -lm > /tmp/cat.txt 2>&1; head -20 /tmp/cat.txt
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `fuzzer::FileToVector(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long, bool)':
/root/checkouts/Fuzzer/./FuzzerIO.cpp:34: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:40: undefined reference to `std::istream::seekg(long, std::_Ios_Seekdir)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:41: undefined reference to `std::istream::tellg()'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:47: undefined reference to `std::istream::seekg(long, std::_Ios_Seekdir)'
/root/checkouts/Fuzzer/./FuzzerIO.cpp:49: undefined reference to `std::istream::read(char*, long)'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ios':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/basic_ios.h:282: undefined reference to `std::ios_base::~ios_base()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ios':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/basic_ios.h:282: undefined reference to `std::ios_base::~ios_base()'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `fuzzer::FileToString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/root/checkouts/Fuzzer/./FuzzerIO.cpp:54: undefined reference to `std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
/root/checkouts/Fuzzer/libFuzzer.a(FuzzerIO.o): In function `~basic_ifstream':
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/fstream:534: undefined reference to `VTT for std::basic_ifstream<char, std::char_traits<char> >'
<snip>
I've tried doing the following to fix this:
Adding -lc++ - doesn't do anything
Adding -lc++abi - doesn't do anything
It feels like I'm missing something obvious but I'm not sure what...
My installation of clang-5.0 comes from clang-5.0/kali-rolling.
You have compiled part of your code with libstdc++ and part with libc++. When you link them together (using libc++), the parts that have references to libstdc++ don't get resolved.
For example, std::__cxx11::basic_string is definitely a libstdc++ symbol.
Looks like for whatever reason kali's version of clang-5.0 doesn't link binaries with libc++ properly. I tested the same code with google's ossfuzz version of clang (clang-6.0) and everything linked together successfully.
The OP mentioned (2017):
Looks like for whatever reason kali's version of clang-5.0 doesn't link binaries with libc++ properly.
I tested the same code with google's ossfuzz version of clang (clang-6.0) and everything linked together successfully.
At the time, libstdc++ was needed.
But now, from the current LibFuzzer documentation (March 2021)
Recent versions of Clang (starting from 6.0) include libFuzzer, and no extra installation is necessary.
As an illustration of that new ("new" meaning "post CLang 5") usage, Git 2.31.1 (Q1 2021), references the same LibFuzzer 11.0 documentation section:
See commit 68b5c3a (08 Mar 2021) by Andrzej Hunt (ahunt).
(Merged by Junio C Hamano -- gitster -- in commit af10702, 19 Mar 2021)
Makefile: update 'make fuzz-all' docs to reflect modern clang
Signed-off-by: Andrzej Hunt
Clang no longer produces a libFuzzer.a.
Instead, you can include libFuzzer by using -fsanitize=fuzzer.
Therefore we should use that in the example command for building fuzzers.
We also add -fsanitize=fuzzer-no-link to the CFLAGS to ensure that all the required instrumentation is added when compiling git 1, and remove -fsanitize-coverage=trace-pc-guard as it is deprecated.
I happen to have tested with LLVM 11 - however -fsanitize=fuzzer appears to work in a wide range of reasonably modern clangs.
(On my system: what used to be libFuzzer.a now lives under the following path, which is tricky albeit not impossible for a novice such as myself to find:
/usr/lib64/clang/11.0.0/lib/linux/libclang_rt.fuzzer-x86_64.a )

linker option order causing opencv undefined references [duplicate]

I'm writing a small C program that uses librt. I'm quite surprised that the program won't compile if I place the link flag at the start instead of at the end:
At the moment, to compile the program I do:
gcc -o prog prog.c -lrt -std=gnu99
If I were to do the following, it will fail to find the functions in librt:
gcc -std=gnu99 -lrt -o prog prog.c
Yet, this works with other libraries. I found the issue when attempting to use a simple Makefile. make actually compiled prog.c without liking first (using -c flag) and then did the linking.
This is the Makefile:
CC = gcc
CFLAGS = -std=gnu99
LIBS= -lrt
LDFLAGS := -lrt
prog: prog.o
$(CC) -o prog prog.c -lrt -std=gnu99
The output I would get when typing make would be:
gcc -std=gnu99 -c -o prog.o prog.c
gcc -lrt prog.o -o prog
prog.o: In function `main':
prog.c:(.text+0xe6): undefined reference to `clock_gettime'
prog.c:(.text+0x2fc): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
make: *** [buff] Error 1
I have now crafted a Makefile that puts the linking at the end of the gcc line, however I'm puzzled why it doesn't work if the linking flag is at the start.
I would appreciate if anybody can explain this to me. Thanks.
As the linker processes each module (be it a library or a object file), it attempts to resolve each undefined symbol while potentially adding to its list of undefined symbols. When it gets to the end of the list of modules, it either has resolved all undefined symbols and is successful or it reports undefined symbols.
In your case, when it processed librt, it had no undefined symbols. Processing proc resulted in clock_gettime being an undefined symbol. gcc will not go back and look in librt for the undefined symbols.
For that reason, you should always have your code first, followed by your libraries, followed by platform provided libraries.
Hope this helps.
From the ld (the GNU linker) documentation (http://sourceware.org/binutils/docs/ld/Options.html#Options):
The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.
So if you specify the library too early, the linker will scan it, but not find anything of interest. Then the linker moves on to the object file produced by the compiler and finds references that need to be resolved, but it has already scanned the library and won't bother looking there again.

Compile error: libicui18n.so.54 needed by libQt5Core.so.5 not found

#include <opencv2/opencv.hpp> //头文件
using namespace cv; //包含cv命名空间
int main()
{
Mat img=imread("cornea.jpg");
imshow("src",img);
waitKey(0);
return 0;
}
And I compile it with:
g++ test.cpp -o test pkg-config opencv --cflags --libs opencv
Which gives me:
/usr/bin/ld: warning: libicui18n.so.54, needed by //home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)<br/>
/usr/bin/ld: warning: libicuuc.so.54, needed by //home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)<br/>
/usr/bin/ld: warning: libicudata.so.54, needed by //home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5, not found (try using -rpath or -rpath-link)<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_clone_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘uenum_next_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘u_strToLower_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_getStandardName_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucol_setAttribute_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_setMillis_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucol_strcoll_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_setSubstChars_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_getTimeZoneDisplayName_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_openCountryTimeZones_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_fromUnicode_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_open_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_getDefaultName_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucol_open_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucol_close_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_inDaylightTime_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucol_getSortKey_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_getAvailableName_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_close_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_get_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_openTimeZoneIDEnumeration_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_getDSTSavings_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_open_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_openTimeZones_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_toUnicode_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘u_strToUpper_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘u_errorName_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_close_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘uenum_close_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_countAvailable_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_getMaxCharSize_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_getAlias_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucal_getDefaultTimeZone_54’未定义的引用<br/>
//home/lmk/Qt5.5.0/5.5/gcc/lib/libQt5Core.so.5:对‘ucnv_compareNames_54’未定义的引用<br/>
collect2: error: ld returned 1 exit status
The backticks in command line pkg-config opencv --cflags --libs opencv is invisible. I have not got the reason now.
Indeed,in early days, I have installed Qt. But now, I do not want my program have something to do with Qt. In order that my program is not affected by the Qt library function, I shielded the path variables of Qt in the /etc/bash.bashrc file and installed a new gcc of 5.3.0. But the same error is still existing!
I'm using Ubuntu 14.04
Download ICU-54.1 from here
http://www.linuxfromscratch.org/blfs/view/7.7/general/icu.html
and install manually.
For me this solved the problem.

How can I link files compiled with clang -flto using lld?

I am trying to use llvm-lld to link an object that has been compiled with -flto.
I have the ld in the path call lld with all the arguments provided.
I created a simple C++ program, which I compile with clang++:
#include <stdio.h>
int main() {
printf("Goodbye cruel world\n");
return 0;
}
Without the -flto flag I get an executable, with the -flto I get this error:
warning: ignoring unknown argument: -plugin
warning: ignoring unknown argument: -plugin-opt=mcpu=x86-64
Cannot open /tmp/a-f1a2a7.o: Exec format error
clang-3.8: error: linker command failed with exit code 1 (use -v to see invocation)
Here are the arguments being passed to the linker, I see that with -flto the plugin arguments are provided include this plugin option, yet it seems to be unsupported.
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/crtbegin.o -L/usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0 -L/usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../.. -L/mnt/data/tmp/dev/llvm/prev/bin/../lib -L/lib -L/usr/lib -plugin /mnt/data/tmp/dev/llvm/prev/bin/../lib/LLVMgold.so -plugin-opt=mcpu=x86-64 /tmp/a-f1a2a7.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/crtend.o /usr/lib64/gcc/x86_64-pc-linux-gnu/5.2.0/../../../../lib64/crtn.o
Is there a way for lld to link this code?
Yes, you can do it by using gold-linker which supports LTO via plugins:
Here is the instructions how to build and run it

adding linker to command line

I am trying to compile a project and you can find the makefile at this link here https://dl.dropbox.com/u/95042389/Makefile
I have installed ANN and OpenCV 2.3.1.
When I type make, it is returning the errors given below.
sai#sai-HP-EliteBook-8460w:~/workspace/4pcs$ make
g++ -L/home/sai/workspace/OpenCV-2.4.1/lib -L/home/sai/workspace/ann_1.1.2/lib -L/usr/lib 4pcs.o 4pcs_test.o -o 4pcs -lopencv_highgui -lANN -o 4pcs
/usr/bin/ld: 4pcs.o: undefined reference to symbol 'cv::operator*(cv::Mat const&, cv::Mat const&)'
/usr/bin/ld: note: 'cv::operator*(cv::Mat const&, cv::Mat const&)' is defined in DSO /usr/lib/libopencv_core.so.2.3 so try adding it to the linker command line
/usr/lib/libopencv_core.so.2.3: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
make: * [4pcs] Error 1
Then I tried this
sai#sai-HP-EliteBook-8460w:~/workspace/4pcs$ echo $LD_LIBRARY_PATH
/usr/lib:/opt/ros/fuerte/lib:/opt/ros/fuerte/lib:/usr/lib/libopencv_core.2.3
Still the same errors..
Any suggestions?
It was solved by adding
-lopencv_core and then it worked with no errors.

Resources