Posts
ODR violation detection
This article describes how to detect C++ One Definition Rule (ODR) violations. There are many good resources on the Internet about how ODR violations can introduce subtle bugs, so I will not repeat that here.
…_FORTIFY_SOURCE
Updated in 2024-08.
glibc 2.3.4 introduced _FORTIFY_SOURCE in 2004 to catch security errors due to misuse of some C library functions.
The initially supported functions were fprintf, gets, memcpy, memmove, mempcpy, memset, printf, snprintf, sprintf, stpcpy, strcat, strcpy, strncat, strncpy, vfprintf, vprintf, vsnprintf, vsprintf and focused on buffer overflow detection and dangerous printf %n uses.
The implementation leverages inline functions and __builtin_object_size (see [PATCH] Object size checking to prevent (some) buffer overflows).
More functions were added over time and __builtin_constant_p was used as well. As of 2022-11 glibc defines 79 default version *_chk functions.
lld linked musl on PowerPC64
I was asked about a segfault related to lld linked musl libc.so on PowerPC64.
/usr/lib/ld-musl-powerpc64le.so.1 /path/to/thingworked. The kernel ELF loader loads rtld and rtld loads the executable./path/to/thingsegfaulted. The kernel ELF loader loads both rtld and the executable.
Therefore the bug is likely due to a difference between the two modes.
…Distribution of debug information
Updated in 2024-08.
Note: The article will likely get frequent updates in the next few days.
This article describes some approaches to distribute debug information. Commands below will use two simple C files for demonstration.
cat > a.c <<eof
void foo(int);
int main() { foo(42); }
eof
cat > b.c <<eof
#include <stdio.h>
void foo(int x) { printf("%d\n", x); }
eof…
Layering check with Clang
Updated in 2023-07.
This article describes some Clang header modules features that apply to #include.
These features enforce a more explicit dependency graph, which provide documentation purposes and makes refactoring convenient.
The benefits of clean header inclusions are well described in Include What You Use as well, so I won't repeat them here.
When using C++20 modules, these features apply to #include in a global module fragment (module;) but have no effect for import declarations.
Layering check
-fmodules-decluse
For a #include directive, this option emits an error if the following conditions are satisfied (see clang/lib/Lex/ModuleMap.cpp diagnoseHeaderInclusion):
- The main file is within a module (called "source module", say,
A). - The main file or an included file from the source module includes a file from another module
B. Adoes not have a use-declaration ofB(nouse B).
For the first condition, -fmodule-map-file= is needed to load the source module map and -fmodule-name=A is needed to indicate that the source file is logically part of module A.
For the second condition, the module map defining B must be loaded by specifying -fimplicit-module-maps (implied by -fmodules and -fcxx-modules) or a -fmodule-map-file=.
zstd compressed debug sections
Updated in 2022-10.
In January I wrote Compressed debug sections.
The venerable zlib shows its age and there are replacements which are better in every metric except adoption and a larger memory footprint.
The obvious choice was Zstandard, but I was not so confident about adoptinig it and solving the ecosystem issue.
At any rate, I slowly removed some legacy .zdebug support from llvm-project so that a new format could be more easily introduced.
lld 15 ELF changes
llvm-project 15 was just released. I added some lld/ELF notes to https://github.com/llvm/llvm-project/blob/release/15.x/lld/docs/ReleaseNotes.rst. Here I will elaborate on some changes.
…-march=, -mcpu=, and -mtune=
Updated in 2025-05.
In GCC and Clang, there are three major options specifying the architecture and microarchitecture the generated code can run on. The general semantics are described below, but each target machine may assign different semantics.
-march=X: (execution domain) Generate code that can use instructions available in the architecture X-mtune=X: (optimization domain) Optimize for the microarchitecture X, but does not change the ABI or make assumptions about available instructions-mcpu=X: Specify both-march=and-mtune=but can be overridden by the two options. The supported values are generally the same as-mtune=. The architecture name is inferred fromX
glibc and DT_GNU_HASH
Updated in 2026-02.
tl;dr "Easy Anti-Cheat"'s incompatibility with glibc 2.36 provides shared objects (libc.so.6, ld-linux-x86_64.so.2) is an instance of Hyrum's law.
- On 2022-08-02 glibc 2.36 was released.
- On the same day the x86-64 package was moved to
[core]on Arch Linux. - On 2022-08-03 Jelgnum reported that with the new glibc, "Easy Anti-Cheat" cannot load the anti-cheat module (GLIBC update broke EAC for most games that use it).
- Multiple Arch Linux game users confirmed the problem.
- Frogging101 bisected the problem to the glibc commit Do not use --hash-style=both for building glibc shared objects.
- The problem led to heated discussions, some clickbait news, and claims such as "glibc breaks ABI" and "glibc does not prioritize compatibility with pre-existing applications".
I feel compelled to demystify the accident and wish that people can stop defamation to glibc.
…