My Little LLVM: Undefined Behavior is Magic!

MyLittleLLVM通过重新定义未定义行为,引入了多项创新特性,如改进原子操作、位移返回随机数、布尔运算遵循真理原则、浮点数比较规则更新等,同时提升了安全性并优化了编译器Logo。

My Little LLVM: Undefined Behavior is Magic!

There’s been lots of discussion online (and then quite some more) about compilers abusing undefined behavior. As a response the LLVM compiler infrastructure is rebranding and adopting a motto to make undefined behavior friendlier and less prone to corruption.

The re-branding puts to rest a long-standing issue with LLVM’s “dragon” logo actually being a wyvern with an upside-down head, a special form of undefined behavior in its own right. The logo is now clearly a pegasus pony.

Another great side-effect of this rebranding is increased security by auto-magically closing all vulnerabilities used by the hacker who goes by the pseudonym “[Pinkie Pie](https://www.google.com/search?q=pinkie pie hacker)”.

These new features are enabled with the -rainbow clang option, in honor of Rainbow Dash’s unary name.

A Few Examples

C++’s memory model specifies that data races are undefined behavior. It is well established that no sane compiler would optimize atomics, LLVM will therefore supplement the Standard’s happens-before relationship with an LLVM-specific happens-to-work relationship. On most architectures this will be implemented with micro-pause primitives such as x86’s rep rep rep nop instruction.

Shifts by bit-width or larger will now return a normally-distributed random number. This also obsoletes rand() and std::random_shuffle.

bool now obeys the rules of truthiness to avoid that annoying “but what if it’s not zero or one?” interview question. Further, incrementing a bool with ++ now does the right thing.

Atomic integer arithmetic is already specified to be two’s complement. Regular arithmetic will therefore now also be atomic. Except when volatile, but not when volatile atomic.

NaNs will now compare equal, subnormals are free to self-classify as normal / zero / other, negative zero simply won’t be a thing, IEEE-754 has been upgraded to PONY-754, floats will still round with style, and generating a signaling NaN is now guaranteed to not be quiet by being equivalent to putchar(’\a’). While we’re at it none of math.h will set errno anymore. This has nothing to do with undefined behavior but seriously, errno?

Type-punning isn’t a thing anymore. We’re renaming it to type-pony-ing, but it doesn’t do anything surprising besides throw parties. AND WHO DOESN’T LIKE PARTIES‽ EVEN SECURITY PEOPLE DO! 🎉

A Word From Our Sponsors

The sanitizers—especially undefined behavior sanitizer, address sanitizer and thread sanitizer—are great tools when dealing with undefined behavior. Use them on your tests, combine them with fuzzers, try them as cupcake topping! Be warned: their runtimes aren’t designed to be secure and you shouldn’t ship them in production code!

Cutie Marks

To address the horse in the room: we’ve left the new LLVM logo’s cutie mark as implementation-defined. Different instances of the logo can use their own cutie mark to illustrate their proclivities, but must clearly document them.

Posted by JF Bastien and Michael Spencer.

Posted by Unknown at 12:00 AM

Labels: april-1, optimization, sanitizer, undefined-behavior

Location: Equestria

使用clang++编译,报错: /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriter.cpp.o): in function `llvm::SHA1::SHA1()': ASTWriter.cpp:(.text._ZN4llvm4SHA1C2Ev[_ZN4llvm4SHA1C5Ev]+0x14): undefined reference to `llvm::SHA1::init()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriter.cpp.o): in function `clang::ASTWriter::createSignature() const [clone .localalias]': ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0xa0): undefined reference to `llvm::SHA1::update(llvm::StringRef)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0xb6): undefined reference to `llvm::SHA1::result()' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0x11d): undefined reference to `llvm::SHA1::update(llvm::StringRef)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0x15a): undefined reference to `llvm::SHA1::update(llvm::StringRef)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0x193): undefined reference to `llvm::SHA1::update(llvm::StringRef)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter15createSignatureEv+0x1a9): undefined reference to `llvm::SHA1::result()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriter.cpp.o): in function `clang::ASTWriter::createSignatureForNamedModule() const [clone .localalias]': ASTWriter.cpp:(.text._ZNK5clang9ASTWriter29createSignatureForNamedModuleEv+0x86): undefined reference to `llvm::SHA1::update(llvm::StringRef)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter29createSignatureForNamedModuleEv+0x1ba): undefined reference to `llvm::SHA1::update(llvm::ArrayRef<unsigned char>)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter29createSignatureForNamedModuleEv+0x23b): undefined reference to `llvm::SHA1::update(llvm::ArrayRef<unsigned char>)' /usr/bin/ld: ASTWriter.cpp:(.text._ZNK5clang9ASTWriter29createSignatureForNamedModuleEv+0x258): undefined reference to `llvm::SHA1::result()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriter.cpp.o): in function `emitBlob(llvm::BitstreamWriter&, llvm::StringRef, unsigned int, unsigned int)': ASTWriter.cpp:(.text._ZL8emitBlobRN4llvm15BitstreamWriterENS_9StringRefEjj+0x44): undefined reference to `llvm::compression::zstd::isAvailable()' /usr/bin/ld: ASTWriter.cpp:(.text._ZL8emitBlobRN4llvm15BitstreamWriterENS_9StringRefEjj+0x9a): undefined reference to `llvm::compression::zstd::compress(llvm::ArrayRef<unsigned char>, llvm::SmallVectorImpl<unsigned char>&, int, bool)' /usr/bin/ld: ASTWriter.cpp:(.text._ZL8emitBlobRN4llvm15BitstreamWriterENS_9StringRefEjj+0x123): undefined reference to `llvm::compression::zlib::isAvailable()' /usr/bin/ld: ASTWriter.cpp:(.text._ZL8emitBlobRN4llvm15BitstreamWriterENS_9StringRefEjj+0x173): undefined reference to `llvm::compression::zlib::compress(llvm::ArrayRef<unsigned char>, llvm::SmallVectorImpl<unsigned char>&, int)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriter.cpp.o): in function `clang::ASTRecordWriter::AddCXXDefinitionData(clang::CXXRecordDecl const*) [clone .localalias]': ASTWriter.cpp:(.text._ZN5clang15ASTRecordWriter20AddCXXDefinitionDataEPKNS_13CXXRecordDeclE+0x1a98): undefined reference to `clang::CXXRecordDecl::getFirstFriend() const' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriterDecl.cpp.o): in function `clang::ASTDeclWriter::VisitOMPDeclareReductionDecl(clang::OMPDeclareReductionDecl*) [clone .localalias]': ASTWriterDecl.cpp:(.text._ZN5clang13ASTDeclWriter28VisitOMPDeclareReductionDeclEPNS_23OMPDeclareReductionDeclE+0x139): undefined reference to `clang::OMPDeclareReductionDecl::getPrevDeclInScope()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ASTWriterDecl.cpp.o): in function `clang::ASTDeclWriter::VisitOMPDeclareMapperDecl(clang::OMPDeclareMapperDecl*) [clone .localalias]': ASTWriterDecl.cpp:(.text._ZN5clang13ASTDeclWriter25VisitOMPDeclareMapperDeclEPNS_20OMPDeclareMapperDeclE+0x6e): undefined reference to `clang::OMPDeclareMapperDecl::getPrevDeclInScope()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(GlobalModuleIndex.cpp.o): in function `clang::GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer> >, llvm::BitstreamCursor) [clone .localalias]': GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndexC2ESt10unique_ptrIN4llvm12MemoryBufferESt14default_deleteIS3_EENS2_15BitstreamCursorE+0x236): undefined reference to `llvm::BitstreamCursor::EnterSubBlock(unsigned int, unsigned int*)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndexC2ESt10unique_ptrIN4llvm12MemoryBufferESt14default_deleteIS3_EENS2_15BitstreamCursorE+0x33c): undefined reference to `llvm::BitstreamCursor::readRecord(unsigned int, llvm::SmallVectorImpl<unsigned long>&, llvm::StringRef*)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(GlobalModuleIndex.cpp.o): in function `clang::GlobalModuleIndex::readIndex(llvm::StringRef)': GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndex9readIndexEN4llvm9StringRefE+0x246): undefined reference to `llvm::MemoryBufferRef::MemoryBufferRef(llvm::MemoryBuffer const&)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(GlobalModuleIndex.cpp.o): in function `(anonymous namespace)::GlobalModuleIndexBuilder::loadModuleFile(clang::FileEntryRef)': GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x111): undefined reference to `llvm::MemoryBufferRef::MemoryBufferRef(llvm::MemoryBuffer const&)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x389): undefined reference to `llvm::BitstreamCursor::skipRecord(unsigned int)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x417): undefined reference to `llvm::BitstreamCursor::EnterSubBlock(unsigned int, unsigned int*)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x4ad): undefined reference to `llvm::BitstreamCursor::EnterSubBlock(unsigned int, unsigned int*)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x543): undefined reference to `llvm::BitstreamCursor::EnterSubBlock(unsigned int, unsigned int*)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN12_GLOBAL__N_124GlobalModuleIndexBuilder14loadModuleFileEN5clang12FileEntryRefE+0x687): undefined reference to `llvm::BitstreamCursor::readRecord(unsigned int, llvm::SmallVectorImpl<unsigned long>&, llvm::StringRef*)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(GlobalModuleIndex.cpp.o): in function `clang::GlobalModuleIndex::writeIndex(clang::FileManager&, clang::PCHContainerReader const&, llvm::StringRef)': GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndex10writeIndexERNS_11FileManagerERKNS_18PCHContainerReaderEN4llvm9StringRefE+0x110): undefined reference to `llvm::LockFileManager::LockFileManager(llvm::StringRef)' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndex10writeIndexERNS_11FileManagerERKNS_18PCHContainerReaderEN4llvm9StringRefE+0x129): undefined reference to `llvm::LockFileManager::tryLock()' /usr/bin/ld: GlobalModuleIndex.cpp:(.text._ZN5clang17GlobalModuleIndex10writeIndexERNS_11FileManagerERKNS_18PCHContainerReaderEN4llvm9StringRefE+0x65d): undefined reference to `llvm::LockFileManager::~LockFileManager()' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ModuleCache.cpp.o): in function `std::_MakeUniq<llvm::LockFileManager>::__single_object std::make_unique<llvm::LockFileManager, llvm::StringRef&>(llvm::StringRef&)': ModuleCache.cpp:(.text._ZSt11make_uniqueIN4llvm15LockFileManagerEJRNS0_9StringRefEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_[_ZSt11make_uniqueIN4llvm15LockFileManagerEJRNS0_9StringRefEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_]+0x4b): undefined reference to `llvm::LockFileManager::LockFileManager(llvm::StringRef)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(ModuleManager.cpp.o): in function `clang::serialization::ModuleManager::addModule(llvm::StringRef, clang::serialization::ModuleKind, clang::SourceLocation, clang::serialization::ModuleFile*, unsigned int, long, long, clang::ASTFileSignature, clang::ASTFileSignature (*)(llvm::StringRef), clang::serialization::ModuleFile*&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)': ModuleManager.cpp:(.text._ZN5clang13serialization13ModuleManager9addModuleEN4llvm9StringRefENS0_10ModuleKindENS_14SourceLocationEPNS0_10ModuleFileEjllNS_16ASTFileSignatureEPFS8_S3_ERS7_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x7d8): undefined reference to `llvm::MemoryBufferRef::MemoryBufferRef(llvm::MemoryBuffer const&)' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(TemplateArgumentHasher.cpp.o): in function `(anonymous namespace)::TemplateArgumentHasher::AddTemplateArgument(clang::TemplateArgument)': TemplateArgumentHasher.cpp:(.text._ZN12_GLOBAL__N_122TemplateArgumentHasher19AddTemplateArgumentEN5clang16TemplateArgumentE+0xec): undefined reference to `llvm::APSInt::Profile(llvm::FoldingSetNodeID&) const' /usr/bin/ld: /usr/local/lib/libclangSerialization.a(TemplateArgumentHasher.cpp.o): in function `(anonymous namespace)::TemplateArgumentHasher::AddIdentifierInfo(clang::IdentifierInfo const*)': TemplateArgumentHasher.cpp:(.text._ZN12_GLOBAL__N_122TemplateArgumentHasher17AddIdentifierInfoEPKN5clang14IdentifierInfoE+0x61): undefined reference to `llvm::FoldingSetNodeID::AddString(llvm::StringRef)' clang++: error: linker command failed with exit code 1 (use -v to see invocation)
最新发布
08-07
你遇到的错误是典型的 **链接失败(linker error)**,具体表现为: ``` undefined reference to `llvm::SHA1::init()` undefined reference to `llvm::compression::zstd::isAvailable()` undefined reference to `clang::CXXRecordDecl::getFirstFriend()` ... ``` --- ## 🔍 错误分析 这些错误表明: > **你链接的 LLVMClang 库中缺少某些符号定义**,也就是说,链接器找不到这些函数或类的实现。 这通常发生在以下几种情况: --- ## ✅ 常见原因与解决方法 ### 1. **ClangLLVM 版本不一致** 你可能正在使用一个版本的 Clang(比如 17),但链接的是另一个版本的 LLVM(比如 20 或 14),或者反之。 #### 🔍 检查方法: ```bash clang++ --version llvm-config --version ``` #### ✅ 解决方法: 确保你安装的 ClangLLVM 是**完全匹配的版本**,比如: - `clang-20` + `llvm-20-dev` + `libclang-20-dev` - `clang-17` + `llvm-17-dev` + `libclang-17-dev` --- ### 2. **未链接完整的 ClangLLVM 库** 你只链接了部分 Clang 库,但缺少了某些关键库(如 `libclangAST`, `libclangSerialization`, `libclangBasic` 等)。 #### ✅ 解决方法: 确保你链接了所有需要的 ClangLLVM 库。例如: ```bash clang++ -std=c++17 your_file.cpp -o your_tool \ $(llvm-config --cxxflags --ldflags --system-libs --libs core support) \ -lclangAST -lclangTooling -lclangFrontend -lclangBasic \ -lclangLex -lclangParse -lclangSema -lclangAnalysis \ -lclangSerialization -lclangEdit -lclangDriver ``` --- ### 3. **手动编译安装的 Clang/LLVM 未正确安装** 你可能从源码构建了 LLVMClang,并且没有正确安装到系统路径中,导致链接器找不到某些符号。 #### ✅ 解决方法: 确保你在构建 LLVMClang 时启用了所有必要的组件,并正确执行了 `make install`: ```bash cd llvm-project mkdir build && cd build cmake -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm make -j$(nproc) sudo make install ``` 然后确认 `/usr/local/lib` 中包含了所有 `.a` 或 `.so` 文件。 --- ### 4. **缺少 Zstd 或 Zlib 支持** 你看到的: ``` undefined reference to `llvm::compression::zstd::isAvailable()` ``` 表示你的 LLVM 编译时没有启用 Zstd 支持。 #### ✅ 解决方法: 重新配置 LLVM,启用 Zstd: ```bash cmake -DLLVM_ENABLE_ZSTD=ON ... ``` 并确保系统安装了 `libzstd-dev` 和 `zlib1g-dev`: ```bash sudo apt install libzstd-dev zlib1g-dev ``` --- ### 5. **Clang 的一些特性未启用** 如果你使用了某些高级特性(如模块、OpenMP、AST序列化等),但构建 Clang 时没有启用它们,也会导致链接失败。 #### ✅ 解决方法: 确保构建 LLVMClang 时启用了以下选项: ```bash -DBUILD_SHARED_LIBS=OFF \ -DLLVM_BUILD_TOOLS=ON \ -DLLVM_BUILD_EXAMPLES=ON \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_TARGETS_TO_BUILD="X86" ``` --- ## ✅ 推荐完整命令示例(Clang 20) ```bash clang++ -std=c++17 ClassInheritanceDumper.cpp -o class_analyzer \ $(llvm-config --cxxflags --ldflags --system-libs --libs core support) \ -lclangAST -lclangTooling -lclangFrontend -lclangBasic \ -lclangLex -lclangParse -lclangSema -lclangAnalysis \ -lclangSerialization -lclangEdit -lclangDriver ``` --- ## ✅ 推荐调试方式 加上 `-v` 查看详细链接器日志: ```bash clang++ -v ... ``` 你也可以使用 `nm` 或 `objdump` 查看某个 `.a` 文件是否包含缺失的符号: ```bash nm /usr/local/lib/libclangSerialization.a | grep SHA1 ``` --- ## ✅ 总结检查清单 | 检查项 | 是否完成 | |--------|----------| | ClangLLVM 版本是否一致? | ✅ | | 是否链接了所有需要的 Clang 库? | ✅ | | 是否启用了 Zstd 和 Zlib 支持? | ✅ | | 是否从源码构建并正确安装? | ✅ | | 使用 `nm` 或 `objdump` 验证库中是否有缺失符号? | ✅ | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值