Posts
MMU-less systems and FDPIC
This article describes ABI and toolchain considerations about systems without a Memory Management Unit (MMU). We will focus on FDPIC and the in-development FDPIC ABI for RISC-V, with updates as I delve deeper into the topic.
Embedded systems often lack MMUs, relying on real-time operating systems (RTOS) like VxWorks or special Linux configurations (CONFIG_MMU=n).
In these systems, the offset between the text and data segments is often not knwon at compile time.
Therefore, a dedicated register is typically set to somewhere in the data segment and writable data is accessed relative to this register.
Why is the offset not known at compile time? There are primarily two reasons.
First, eXecute in Place (XIP), where code resides in ROM while the data segment is copied to RAM. Therefore, the offset between the text and data segments is often not known at compile time.
Second, all processes share the same address space without MMU. However, it is still desired for these processes to share text segments. Therefore needs a mechanism for code to find its corresponding data.
…lld 18 ELF changes
LLVM 18 will be released. As usual, I maintain lld/ELF and have added some notes to https://github.com/llvm/llvm-project/blob/release/18.x/lld/docs/ReleaseNotes.rst. I've meticulously reviewed nearly all the patches that are not authored by me. I'll delve into some of the key changes.
…Toolchain notes on z/Architecture
This article describes some notes about z/Architecture with a focus on the ELF ABI and ELF linkers. An lld/ELF patch sparked my motivation to study the architecture and write this post.
z/Architecture is a big-endian mainframe computer architecture supporting 24-bit, 31-bit, and 64-bit addressing modes.
It is the latest generation in a lineage stretching back to the 1964 with IBM System/360 (32-bit general-purpose registers and 24-bit addressing).
This lineage includes System/370 (1970), System/370 Extended Architecture (1983), Enterprise Systems Architecture/370 (1988), and Enterprise Systems Architecture/390 (1990).
For a deeper dive into the design choices behind z/Architecture's extension from ESA/390, you can refer to "Development and attributes of z/Architecture."

Raw symbol names in inline assembly
For operands in asm statements, GCC has supported the constraints "i" and "s" for a long time (since at least 1992).
// gcc/common.md
(define_constraint "i"
"Matches a general integer constant."
(and (match_test "CONSTANT_P (op)")
(match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))
(define_constraint "s"
"Matches a symbolic integer constant."
(and (match_test "CONSTANT_P (op)")
(match_test "!CONST_SCALAR_INT_P (op)")
(match_test "!flag_pic || LEGITIMATE_PIC_OPERAND_P (op)")))…
Modified condition/decision coverage (MC/DC) and compiler implementations
Key metrics for code coverage include:
- function coverage: determines whether each function been executed.
- line coverage (aka statement coverage): determines whether every line has been executed.
- branch coverage: ensures that both the true and false branches of each conditional statement or the condition of each loop statement been evaluated.
Condition coverage offers a more fine-grained evaluation of branch coverage.
It requires that each individual boolean subexpression (condition) within a compound expression be evaluated to both true and false.
For example, in the boolean expression if (a>0 && f(b) && c==0), each of a>0, f(b), and c==0, condition coverage would require tests that:
Exploring object file formats
My journey with the LLVM project began with a deep dive into the world of lld and binary utilities. Countless hours were spent unraveling the intricacies of object file formats and shaping LLVM's relevant components. Though my interests have since broadened, object file formats remain a personal fascination, often drawing me into discussions around potential changes within LLVM.
This article compares several prominent object file formats, drawing upon my experience and insights.
At the heart of each format lies the representation of essential components like symbols, sections, and relocations. For each control structure, We'll begin with ELF, a widely used format, before venturing into the landscapes of other notable formats.
…2023年总结
一如既往,主要在工具链领域耕耘。
llvm-project
I made 700+ commits this year. Many are clean-up commits or fixup for others' work. I hope that I can do more useful work next year.
- Enabled
--features=layering_checkfor Bazel's llvm and clang projects - Implemented
LLVM_ENABLE_REVERSE_ITERATIONforStringMap - Added
llvm::xxh3_64bitsand adopted it in llvm/clang/lld - Made AArch64 changes to msan and dfsan
- Made various improvements to the clang driver, including
-###exit code, auxiliary files, errors for unsupported target-specific options,-fsanitize=kcfi, and XRay - Made various sanitizer changes
- Made
-fsanitize=functionwork for C and non-x86 architectures - Fixed several major problems of assembler implementation of RISC-V linker relaxation
- clangSema:
%lbrecognization for printf/scanf, checking the failure memory order foratomic_compare_exchange-family built-in functions,-Wc++11-narrowing-const-reference - llvm-objdump:
@pltsymbols for x86.plt.got, mapping symbol improvements,--disassemble-symbolschanges, etc - Supported
R_RISCV_SET_ULEB128/R_RISCV_SUB_ULEB128for.uleb128directives - gcov: fix instrumentation crashes when using inline variables,
#line, and#include, made llvm-cov gcov work with a smaller stack size - LTO: fixed local ifunc for ThinLTO, reported errors when parsing module-level inline assembly
- CodeLayout: fixed a correctness bug and improved performance to be suitable for lld/ELF
--call-graph-profile-sort=hfsortdefault
Reviewed many commits. A lot of people don't add a Reviewed By: tag. Anyway, counting commits with the tag can give an underestimate.
% git shortlog -sn 2679e8bba3e166e3174971d040b9457ec7b7d768...main --grep 'Reviewed .*MaskRay' | awk '{s+=$1}END{print s}'
395…
reviews.llvm.org became a read-only archive
For approximately 10 years, reviews.llvm.org functioned as the code view site for the LLVM project, utilizing a Phabricator instance.
This website hosted numerous invaluable code review discussions.
However, following LLVM's transition to GitHub pull requests, there arises a necessity for a read-only archive of the existing Phabricator instance.
(https://archive.org/ archives a subset of the reviews.llvm.org/Dxxxxx pages.)
The intent is to eliminate a SQL engine. Phabicator operates on a complex database scheme. To minimize time investment, the most feasible approach seems to involve downloading the static HTML pages and employing a lightweight scraping process.
Raphaël Gomès developed phab-archive to serve a read-only archive for Mercurial's Phabricator instance. I have modified the code to suit reviews.llvm.org.
The DNS records of reviews.llvm.org have been pointed to the archive website.
…Exploring the section layout in linker output
Updated in 2026-03.
This article describes section layout and its interaction with dynamic loaders and huge pages.
Let's begin with a Linux x86-64 example involving global variables exhibiting various properties such as read-only versus writable, zero-initialized versus non-zero, and more.
#include <stdio.h>
const int ro = 1;
int w0, w1 = 1;
int *const pw0 = &w0;
int main() {
printf("%d %d %d %p\n", ro, w0, w1, pw0);
}…