This post describes how to compile a single C++ source file to an
object file with the Clang API. Here is the code. It behaves like a
simplified clang
executable that handles -c
and -S
.
Migrating comments to giscus
Followed this guide: https://www.patrickthurmond.com/blog/2023/12/11/commenting-is-available-now-thanks-to-giscus
Add the following to layout/_partial/article.ejs
1 | <% if (!index && post.comments) { %> |
Unfortunately comments from Disqus have not been migrated yet. If you've left comments in the past, thank you. Apologies they are now gone.
While you can create Github Discussions via GraphQL API, I haven't found a solution that works out of the box. https://www.davidangulo.xyz/posts/dirty-ruby-script-to-migrate-comments-from-disqus-to-giscus/ provides a Ruby solution, which is promising but no longer works.
1 | Failed to define value method for :name, because EnterpriseOrderField already responds to that method. Use `value_method:` to override the method name or `value_method: false` to disable Enum value me |
lld 20 ELF changes
LLVM 20 will be released. As usual, I maintain lld/ELF and have added some notes to https://github.com/llvm/llvm-project/blob/release/20.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.
Natural loops
A dominator tree can be used to compute natural loops.
- For every node
H
in a post-order traversal of the dominator tree (or the original CFG), find all predecessors that are dominated byH
. This identifies all back edges. - Each back edge
T->H
identifies a natural loop withH
as the header.- Perform a flood fill starting from
T
in the reversed dominator tree (from exiting block to header) - All visited nodes reachable from the root belong to the natural loop
associated with the back edge. These nodes are guaranteed to be
reachable from
H
due to the dominator property. - Visited nodes unreachable from the root should be ignored.
- Loops associated with visited nodes are considered subloops.
- Perform a flood fill starting from
Understanding and improving Clang -ftime-report
Clang provides a few options to generate timing report. Among them,
-ftime-report
and -ftime-trace
can be used to
analyze the performance of Clang's internal passes.
-fproc-stat-report
records time and memory on spawned processes (ld
, and gas if-fno-integrated-as
).-ftime-trace
, introduced in 2019, generates Clang timing information in the Chrome Trace Event format (JSON). The format supports nested events, providing a rich view of the front end.-ftime-report
: The option name is borrowed from GCC.
This post focuses on the traditional -ftime-report
,
which uses a line-based textual format.
Understanding
-ftime-report
output
The output consists of information about multiple timer groups. The last group spans the largest interval and encompasses timing data from other groups.
Up to Clang 19, the last group is called "Clang front-end time report". You would see something like the following.
2024年总结
一如既往,主要在工具链领域耕耘。
Blogging
I have been busy creating posts, authoring a total of 31 blog posts (including this one). 7 posts resonated on Hacker News, garnering over 50 points. (https://news.ycombinator.com/from?site=maskray.me).
I have also revised many posts initially written between 2020 and 2024.
Mastodon: https://hachyderm.io/@meowray
Skipping boring functions in debuggers
In debuggers, stepping into a function with arguments that involve function calls may step into the nested function calls, even if they are simple and uninteresting, such as those found in the C++ STL.
GDB
Consider the following example:
1 |
|
When GDB stops at the foo
call, the step
(s
) command will step into std::vector::back
and std::unique_ptr::operator*
. While you can execute
finish
(fin
) and then execute s
again, it's time-consuming and distracting, especially when dealing with
complex argument expressions.
Exporting Tweets
On https://x.com/settings/, click
More -> Settings and privacy -> Download an archive of your data
.
Wait for a message from x.com: "@XXX your X data is ready" Download the
archive.
1 | cp data/tweets.js tweets.ts |
Change the first line from window.YTD.tweets.part0 = [
to let part0 = [
, and append
1 | import { unescape } from "@std/html/entities"; |
Then run deno run --allow-write=. tweets.ts
1 | % cat 2022/index.md |
tweet0
tweet1
Simplifying disassembly with LLVM tools
Both compiler developers and security researchers have built disassemblers. They often prioritize different aspects. Compiler toolchains, benefiting from direct contributions from CPU vendors, tend to offer more accurate and robust decoding. Security-focused tools, on the other hand, often excel in user interface design.
For quick disassembly tasks, rizin provides a convenient command-line interface.
clang-format and single-line statements
The Google C++ Style is widely adopted by projects. It contains a brace omission guideline in Looping and branching statements:
For historical reasons, we allow one exception to the above rules: the curly braces for the controlled statement or the line breaks inside the curly braces may be omitted if as a result the entire statement appears on either a single line (in which case there is a space between the closing parenthesis and the controlled statement) or on two lines (in which case there is a line break after the closing parenthesis and there are no braces).