diff options
author | johannst <johannst@users.noreply.github.com> | 2023-08-22 21:38:08 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2023-08-22 21:38:08 +0000 |
commit | f0cf514eb3ca30c5170e534c3861ad73996c7726 (patch) | |
tree | d5d1eb653716e4c01174f9bd86bf85f47e8ac15b /print.html | |
parent | 928b2fa4af916a5f75d1269620914f7bb4225e6e (diff) | |
download | notes-f0cf514eb3ca30c5170e534c3861ad73996c7726.tar.gz notes-f0cf514eb3ca30c5170e534c3861ad73996c7726.zip |
deploy: 9bb639287cae88b32fc1b17b7a4b494340e54434
Diffstat (limited to 'print.html')
-rw-r--r-- | print.html | 354 |
1 files changed, 346 insertions, 8 deletions
@@ -84,7 +84,7 @@ <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <div class="sidebar-scrollbox"> - <ol class="chapter"><li class="chapter-item expanded affix "><a href="intro.html">Introduction</a></li><li class="chapter-item expanded "><a href="tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="chapter-item expanded "><a href="tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="chapter-item expanded "><a href="tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="chapter-item expanded "><a href="tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="chapter-item expanded "><a href="tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="chapter-item expanded "><a href="tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="chapter-item expanded "><a href="tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="chapter-item expanded "><a href="tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="chapter-item expanded "><a href="tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="chapter-item expanded "><a href="tools/gdbserver.html"><strong aria-hidden="true">1.10.</strong> gdbserver</a></li><li class="chapter-item expanded "><a href="tools/radare2.html"><strong aria-hidden="true">1.11.</strong> radare2</a></li><li class="chapter-item expanded "><a href="tools/qemu.html"><strong aria-hidden="true">1.12.</strong> qemu</a></li><li class="chapter-item expanded "><a href="tools/pacman.html"><strong aria-hidden="true">1.13.</strong> pacman</a></li><li class="chapter-item expanded "><a href="tools/dot.html"><strong aria-hidden="true">1.14.</strong> dot</a></li></ol></li><li class="chapter-item expanded "><a href="monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="chapter-item expanded "><a href="monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="chapter-item expanded "><a href="monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="chapter-item expanded "><a href="monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="chapter-item expanded "><a href="monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="chapter-item expanded "><a href="monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="chapter-item expanded "><a href="trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="chapter-item expanded "><a href="trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="chapter-item expanded "><a href="trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="chapter-item expanded "><a href="trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="chapter-item expanded "><a href="trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="chapter-item expanded "><a href="binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="chapter-item expanded "><a href="binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="chapter-item expanded "><a href="binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="chapter-item expanded "><a href="binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="chapter-item expanded "><a href="binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="chapter-item expanded "><a href="development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="chapter-item expanded "><a href="development/c++.html"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="chapter-item expanded "><a href="development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="chapter-item expanded "><a href="development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="chapter-item expanded "><a href="development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="chapter-item expanded "><a href="development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li><li class="chapter-item expanded "><a href="development/symbolver.html"><strong aria-hidden="true">5.7.</strong> symbol versioning</a></li><li class="chapter-item expanded "><a href="development/python.html"><strong aria-hidden="true">5.8.</strong> python</a></li><li class="chapter-item expanded "><a href="development/gcov.html"><strong aria-hidden="true">5.9.</strong> gcov</a></li></ol></li><li class="chapter-item expanded "><a href="linux/index.html"><strong aria-hidden="true">6.</strong> Linux</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="linux/systemd.html"><strong aria-hidden="true">6.1.</strong> systemd</a></li><li class="chapter-item expanded "><a href="linux/coredump.html"><strong aria-hidden="true">6.2.</strong> coredump</a></li><li class="chapter-item expanded "><a href="linux/ptrace_scope.html"><strong aria-hidden="true">6.3.</strong> ptrace_scope</a></li><li class="chapter-item expanded "><a href="linux/cryptsetup.html"><strong aria-hidden="true">6.4.</strong> cryptsetup</a></li><li class="chapter-item expanded "><a href="linux/swap.html"><strong aria-hidden="true">6.5.</strong> swap</a></li><li class="chapter-item expanded "><a href="linux/input.html"><strong aria-hidden="true">6.6.</strong> input</a></li><li class="chapter-item expanded "><a href="linux/acl.html"><strong aria-hidden="true">6.7.</strong> acl</a></li><li class="chapter-item expanded "><a href="linux/zfs.html"><strong aria-hidden="true">6.8.</strong> zfs</a></li></ol></li><li class="chapter-item expanded "><a href="network/index.html"><strong aria-hidden="true">7.</strong> Network</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="network/tcpdump.html"><strong aria-hidden="true">7.1.</strong> tcpdump</a></li><li class="chapter-item expanded "><a href="network/firewall-cmd.html"><strong aria-hidden="true">7.2.</strong> firewall-cmd</a></li><li class="chapter-item expanded "><a href="network/nftables.html"><strong aria-hidden="true">7.3.</strong> nftables</a></li></ol></li><li class="chapter-item expanded "><a href="web/index.html"><strong aria-hidden="true">8.</strong> Web</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="web/html.html"><strong aria-hidden="true">8.1.</strong> html</a></li><li class="chapter-item expanded "><a href="web/chartjs.html"><strong aria-hidden="true">8.2.</strong> chartjs</a></li></ol></li><li class="chapter-item expanded "><a href="arch/index.html"><strong aria-hidden="true">9.</strong> Arch</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="arch/x86_64.html"><strong aria-hidden="true">9.1.</strong> x86_64</a></li><li class="chapter-item expanded "><a href="arch/arm64.html"><strong aria-hidden="true">9.2.</strong> arm64</a></li><li class="chapter-item expanded "><a href="arch/armv7.html"><strong aria-hidden="true">9.3.</strong> armv7</a></li><li class="chapter-item expanded "><a href="arch/riscv.html"><strong aria-hidden="true">9.4.</strong> riscv</a></li></ol></li></ol> + <ol class="chapter"><li class="chapter-item expanded affix "><a href="intro.html">Introduction</a></li><li class="chapter-item expanded "><a href="tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="chapter-item expanded "><a href="tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="chapter-item expanded "><a href="tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="chapter-item expanded "><a href="tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="chapter-item expanded "><a href="tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="chapter-item expanded "><a href="tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="chapter-item expanded "><a href="tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="chapter-item expanded "><a href="tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="chapter-item expanded "><a href="tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="chapter-item expanded "><a href="tools/gdbserver.html"><strong aria-hidden="true">1.10.</strong> gdbserver</a></li><li class="chapter-item expanded "><a href="tools/radare2.html"><strong aria-hidden="true">1.11.</strong> radare2</a></li><li class="chapter-item expanded "><a href="tools/qemu.html"><strong aria-hidden="true">1.12.</strong> qemu</a></li><li class="chapter-item expanded "><a href="tools/pacman.html"><strong aria-hidden="true">1.13.</strong> pacman</a></li><li class="chapter-item expanded "><a href="tools/dot.html"><strong aria-hidden="true">1.14.</strong> dot</a></li></ol></li><li class="chapter-item expanded "><a href="monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="chapter-item expanded "><a href="monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="chapter-item expanded "><a href="monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="chapter-item expanded "><a href="monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="chapter-item expanded "><a href="monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="chapter-item expanded "><a href="monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="chapter-item expanded "><a href="trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="chapter-item expanded "><a href="trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="chapter-item expanded "><a href="trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="chapter-item expanded "><a href="trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="chapter-item expanded "><a href="trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="chapter-item expanded "><a href="binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="chapter-item expanded "><a href="binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="chapter-item expanded "><a href="binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="chapter-item expanded "><a href="binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="chapter-item expanded "><a href="binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="chapter-item expanded "><a href="development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="chapter-item expanded "><a href="development/c++.html"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="chapter-item expanded "><a href="development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="chapter-item expanded "><a href="development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="chapter-item expanded "><a href="development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="chapter-item expanded "><a href="development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li><li class="chapter-item expanded "><a href="development/symbolver.html"><strong aria-hidden="true">5.7.</strong> symbol versioning</a></li><li class="chapter-item expanded "><a href="development/python.html"><strong aria-hidden="true">5.8.</strong> python</a></li><li class="chapter-item expanded "><a href="development/gcov.html"><strong aria-hidden="true">5.9.</strong> gcov</a></li><li class="chapter-item expanded "><a href="development/pgo.html"><strong aria-hidden="true">5.10.</strong> pgo</a></li></ol></li><li class="chapter-item expanded "><a href="linux/index.html"><strong aria-hidden="true">6.</strong> Linux</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="linux/systemd.html"><strong aria-hidden="true">6.1.</strong> systemd</a></li><li class="chapter-item expanded "><a href="linux/coredump.html"><strong aria-hidden="true">6.2.</strong> coredump</a></li><li class="chapter-item expanded "><a href="linux/ptrace_scope.html"><strong aria-hidden="true">6.3.</strong> ptrace_scope</a></li><li class="chapter-item expanded "><a href="linux/cryptsetup.html"><strong aria-hidden="true">6.4.</strong> cryptsetup</a></li><li class="chapter-item expanded "><a href="linux/swap.html"><strong aria-hidden="true">6.5.</strong> swap</a></li><li class="chapter-item expanded "><a href="linux/input.html"><strong aria-hidden="true">6.6.</strong> input</a></li><li class="chapter-item expanded "><a href="linux/acl.html"><strong aria-hidden="true">6.7.</strong> acl</a></li><li class="chapter-item expanded "><a href="linux/zfs.html"><strong aria-hidden="true">6.8.</strong> zfs</a></li></ol></li><li class="chapter-item expanded "><a href="network/index.html"><strong aria-hidden="true">7.</strong> Network</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="network/tcpdump.html"><strong aria-hidden="true">7.1.</strong> tcpdump</a></li><li class="chapter-item expanded "><a href="network/firewall-cmd.html"><strong aria-hidden="true">7.2.</strong> firewall-cmd</a></li><li class="chapter-item expanded "><a href="network/nftables.html"><strong aria-hidden="true">7.3.</strong> nftables</a></li></ol></li><li class="chapter-item expanded "><a href="web/index.html"><strong aria-hidden="true">8.</strong> Web</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="web/html.html"><strong aria-hidden="true">8.1.</strong> html</a></li><li class="chapter-item expanded "><a href="web/chartjs.html"><strong aria-hidden="true">8.2.</strong> chartjs</a></li></ol></li><li class="chapter-item expanded "><a href="arch/index.html"><strong aria-hidden="true">9.</strong> Arch</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="arch/x86_64.html"><strong aria-hidden="true">9.1.</strong> x86_64</a></li><li class="chapter-item expanded "><a href="arch/arm64.html"><strong aria-hidden="true">9.2.</strong> arm64</a></li><li class="chapter-item expanded "><a href="arch/armv7.html"><strong aria-hidden="true">9.3.</strong> armv7</a></li><li class="chapter-item expanded "><a href="arch/riscv.html"><strong aria-hidden="true">9.4.</strong> riscv</a></li></ol></li></ol> </div> <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div> </nav> @@ -1021,7 +1021,7 @@ list-keys -t vi-copy list keymaps for vi-copy mode git show --stat <commit> ................ show files changed by <commit> git show <commit> [<file>] .............. show diffs for <commit> - git git show <commit>:<file> ............ show <file> at <commit> + git show <commit>:<file> ................ show <file> at <commit> </code></pre> <h2 id="patching"><a class="header" href="#patching">Patching</a></h2> <pre><code class="language-markdown"> git format-patch <opt> <since>/<revision range> @@ -2736,6 +2736,7 @@ objdump -D -b binary -m i386:x86-64 test-bin <li><a href="development/./symbolver.html">symbol versioning</a></li> <li><a href="development/./python.html">python</a></li> <li><a href="development/./gcov.html">gcov</a></li> +<li><a href="development/./pgo.html">pgo</a></li> </ul> <div style="break-before: page; page-break-before: always;"></div><h1 id="cfilt1"><a class="header" href="#cfilt1">c++filt(1)</a></h1> <h2 id="demangle-symbol"><a class="header" href="#demangle-symbol">Demangle symbol</a></h2> @@ -2746,6 +2747,7 @@ objdump -D -b binary -m i386:x86-64 test-bin <pre><code class="language-markdown"> readelf -W --dyn-syms <elf> | c++filt </code></pre> <div style="break-before: page; page-break-before: always;"></div><h1 id="c"><a class="header" href="#c">c++</a></h1> +<p>openstd <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/standards">cpp standards</a>.</p> <p>Source files of most examples is available <a href="https://github.com/johannst/notes/tree/master/src/development/c%2B%2B">here</a>.</p> <h2 id="type-deduction"><a class="header" href="#type-deduction">Type deduction</a></h2> <p>Force compile error to see what <code>auto</code> is deduced to.</p> @@ -2754,6 +2756,191 @@ objdump -D -b binary -m i386:x86-64 test-bin // force compile error typename decltype(foo)::_; </code></pre> +<h2 id="strict-aliasing-and-type-punning"><a class="header" href="#strict-aliasing-and-type-punning">Strict aliasing and type punning</a></h2> +<p>The <code>strict aliasing</code> rules describe via which <code>alias</code> a value can be accessed.</p> +<blockquote> +<p>Informal: an <code>alias</code> is a reference / pointer to a value.</p> +</blockquote> +<p>Accessing a value through an alias that violates the strict aliasing rules is +<code>undefined behavior (UB)</code>.</p> +<p>Examples below on <a href="https://godbolt.org/z/TsvTY9zfj">godbolt</a>.</p> +<pre><code class="language-cpp">int i = 0; + +// Valid aliasing (signed / unsigned type). +*reinterpret_cast<signed int*>(&i); +*reinterpret_cast<unsigned int*>(&i); + +// Valid aliasing (cv qualified type). +*reinterpret_cast<const int*>(&i); +*reinterpret_cast<const unsigned*>(&i); + +// Valid aliasing (byte type). +*reinterpret_cast<char*>(&i); +*reinterpret_cast<std::byte*>(&i); + +// Invalid aliasing, dereferencing pointer is UB. +*reinterpret_cast<short*>(&i); +*reinterpret_cast<float*>(&i); +</code></pre> +<blockquote> +<p>NOTE: Casting pointer to invalid aliasing type is not directly UB, but +dereferencing the pointer is UB.</p> +</blockquote> +<pre><code class="language-cpp">short s[2] = { 1, 2 }; + +// Invalid aliasing (UB) - type punning, UB to deref ptr (int has stricter +// alignment requirements than short). +*reinterpret_cast<int*>(s); + + +// Arbitrary byte pointer. +char c[4] = { 1, 2, 3, 4 }; + +// Invalid aliasing (UB) - type punning, UB to deref ptr (int has stricter +// alignment requirements than char). +*reinterpret_cast<int*>(c); +</code></pre> +<p>At the time of writing, the current <a href="http://eel.is/c++draft/basic.lval#11">c++ std draft</a> +contains the following.</p> +<pre><code class="language-text">If a program attempts to access the stored value of an object through a glvalue +whose type is not **similar** (7.3.6) to one of the following types the +behavior is undefined [44] + +(11.1) the dynamic type of the object, +(11.2) a type that is the signed or unsigned type corresponding to the dynamic + type of the object, or +(11.3) a char, unsigned char, or std::byte type. + +[44]: The intent of this list is to specify those circumstances in which an + object can or cannot be aliased. +</code></pre> +<p>The paragraph is short but one also needs to understand the meaning of +<a href="http://eel.is/c++draft/conv.qual#def:similar_types">similar (<em>similar_types</em>)</a>.</p> +<p>This paragraph is actually somewhat more explicit in the <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf">c++17 std</a>.</p> +<pre><code class="language-text">If a program attempts to access the stored value of an object through a glvalue +of other than one of the following types the behavior is undefined [63] + +(11.1) the dynamic type of the object, +(11.2) a cv-qualified version of the dynamic type of the object, +(11.3) a type similar (as defined in 7.5) to the dynamic type of the object, +(11.4) a type that is the signed or unsigned type corresponding to the dynamic + type of the object, +(11.5) a type that is the signed or unsigned type corresponding to a + cv-qualified version of the dynamic type of the object, +(11.6) an aggregate or union type that includes one of the aforementioned types + among its elements or non- static data members (including, recursively, + an element or non-static data member of a subaggregate or contained + union), +(11.7) a type that is a (possibly cv-qualified) base class type of the dynamic + type of the object, +(11.8) a char, unsigned char, or std::byte type. + +[63]: The intent of this list is to specify those circumstances in which an + object may or may not be aliased. +</code></pre> +<p>Additional references:</p> +<ul> +<li> +<p><a href="https://gist.github.com/shafik/848ae25ee209f698763cffee272a58f8">What is the Strict Aliasing Rule and Why do we care</a></p> +<p>The article shows a small example how the compiler may optimized using the +strict aliasing rules.</p> +<pre><code class="language-cpp">int alias(int* i, char* c) { + *i = 1; + *c = 'a'; // char* may alias int* + return *i; +} + +int noalias(int* i, short* s) { + *i = 1; + *s = 2; // short* does not alias int* + return *i; +} +</code></pre> +<pre><code class="language-x86asm">alias(int*, char*): +mov DWORD PTR [rdi] ,0x1 ; *i = 1; +mov BYTE PTR [rsi], 0x61 ; *c = 'a'; +mov eax,DWORD PTR [rdi] ; Must reload, char* can alias int*. +ret + +noalias(int*, short*): +mov DWORD PTR [rdi], 0x1 ; *i = 1; +mov WORD PTR [rsi], 0x2 ; *s = 2; +mov eax,0x1 ; Must not reload, short* can not alias int*. +ret +</code></pre> +</li> +<li> +<p><a href="https://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing">reinterpret_cast</a> type aliasing</p> +<blockquote> +<ol start="5"> +<li>Any object pointer type <code>T1*</code> can be converted to another object pointer +type <code>cv T2*</code>. This is exactly equivalent to <code>static_cast<cv T2*>(static_cast<cv void*>(expression))</code> (which implies that if T2's +alignment requirement is not stricter than T1's, the value of the pointer +does not change and conversion of the resulting pointer back to its +original type yields the original value). In any case, the resulting +pointer may only be dereferenced safely if allowed by the type aliasing +rules (see below).</li> +</ol> +</blockquote> +<pre><code class="language-cpp">int I; +char* X = reinterpret_cast<char*>(&I); // Valid, char allowed to alias int. +*X = 42; +int* Y = reinterpret_cast<int*>(X); // Cast back to original type. +*Y = 1337; // safe + +char C[4]; +int* P = reinterpret_cast<int*>(C); // Cast is ok, not yet UB. +*P = 1337; // UB, violates strict aliasing / alignment rules. + // https://stackoverflow.com/questions/52492229/c-byte-array-to-int +</code></pre> +</li> +<li> +<p>On <code>gcc</code> strict aliasing is enabled starting with <code>-O2</code>.</p> +<pre><code class="language-bash">for i in {0..3} g s; do echo "-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)"; done +-O0 -fstrict-aliasing [disabled] +-O1 -fstrict-aliasing [disabled] +-O2 -fstrict-aliasing [enabled] +-O3 -fstrict-aliasing [enabled] +-Og -fstrict-aliasing [disabled] +-Os -fstrict-aliasing [enabled] +</code></pre> +</li> +</ul> +<h3 id="__restrict-keyword"><a class="header" href="#__restrict-keyword"><code>__restrict</code> keyword</a></h3> +<p>The <code>__restrict</code> keyword allows the programmer to tell the compiler that two +pointer will not alias each other.</p> +<pre><code class="language-cpp">int alias(int* a, int* b) { + *a = 1; + *b = 2; + return *a; +} + +// alias(int*, int*): # @alias(int*, int*) +// mov dword ptr [rdi], 1 +// mov dword ptr [rsi], 2 +// mov eax, dword ptr [rdi] +// ret + +int noalias(int* __restrict a, int* __restrict b) { + *a = 1; + *b = 2; + return *a; +} + +// noalias(int*, int*): # @noalias(int*, int*) +// mov dword ptr [rdi], 1 +// mov dword ptr [rsi], 2 +// mov eax, 1 +// ret +</code></pre> +<p>However this should only be used with care and in a narrow scope, as it is easy +to violate self defined contract, see <a href="https://godbolt.org/z/e8x1af3Mh">godbolt</a>.</p> +<h3 id="type-punning"><a class="header" href="#type-punning">Type punning</a></h3> +<p>The correct way to do <code>type-punning</code> in c++:</p> +<ol> +<li><a href="https://en.cppreference.com/w/cpp/numeric/bit_cast"><code>std::bit_cast</code></a> (c++20)</li> +<li><a href="https://godbolt.org/z/3PM4jGvEz"><code>std::memcpy</code></a></li> +</ol> <h2 id="variadic-templates-parameter-pack"><a class="header" href="#variadic-templates-parameter-pack">Variadic templates (<a href="https://en.cppreference.com/w/cpp/language/parameter_pack">parameter pack</a>)</a></h2> <pre><code class="language-cpp">#include <iostream> @@ -3904,6 +4091,7 @@ func_v2 <li><a href="https://sourceware.org/binutils/docs/ld/VERSION.html">Binutils ld: Symbol Versioning</a></li> <li><a href="https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html">LSB: Symbol Versioning</a></li> <li><a href="https://akkadia.org/drepper/dsohowto.pdf">How To Write Shared Libraries</a></li> +<li><a href="https://refspecs.linuxbase.org/elf/elf.pdf">LSB: ELF File Format</a></li> </ul> <div style="break-before: page; page-break-before: always;"></div><h1 id="python"><a class="header" href="#python">python</a></h1> <h2 id="decorator-run"><a class="header" href="#decorator-run">Decorator [<a href="https://www.online-python.com/IDdiE0gpYU">run</a>]</a></h2> @@ -4085,6 +4273,146 @@ clean: 1: 16: return 0; -: 17:} </code></pre> +<div style="break-before: page; page-break-before: always;"></div><h1 id="profile-guided-optimization-pgo"><a class="header" href="#profile-guided-optimization-pgo">Profile guided optimization (pgo)</a></h1> +<p><code>pgo</code> is an optimization technique to optimize a program for its usual +workload.</p> +<p>It is applied in two phases:</p> +<ol> +<li>Collect profiling data (best with representative benchmarks).</li> +<li>Optimize program based on collected profiling data.</li> +</ol> +<p>The following simple program is used as demonstrator.</p> +<pre><code class="language-c">#include <stdio.h> + +#define NOINLINE __attribute__((noinline)) + +NOINLINE void foo() { puts("foo()"); } +NOINLINE void bar() { puts("bar()"); } + +int main(int argc, char *argv[]) { + if (argc == 2) { + foo(); + } else { + bar(); + } +} +</code></pre> +<h2 id="clang"><a class="header" href="#clang">clang</a></h2> +<p>On the actual machine with <code>clang 15.0.7</code>, the following code is generated for +the <code>main()</code> function.</p> +<pre><code class="language-x86asm"># clang -o test test.c -O3 + +0000000000001160 <main>: + 1160: 50 push rax + ; Jump if argc != 2. + 1161: 83 ff 02 cmp edi,0x2 + 1164: 75 09 jne 116f <main+0xf> + ; foor() is on the hot path (fall-through). + 1166: e8 d5 ff ff ff call 1140 <_Z3foov> + 116b: 31 c0 xor eax,eax + 116d: 59 pop rcx + 116e: c3 ret + ; bar() is on the cold path (branch). + 116f: e8 dc ff ff ff call 1150 <_Z3barv> + 1174: 31 c0 xor eax,eax + 1176: 59 pop rcx + 1177: c3 ret +</code></pre> +<p>The following shows how to compile with profiling instrumentation and how to +optimize the final program with the collected profiling data (<a href="https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization">llvm +pgo</a>).</p> +<p>The arguments to <code>./test</code> are chosen such that <code>9/10</code> runs call <code>bar()</code>, which +is currently on the <code>cold path</code>.</p> +<pre><code class="language-bash"># Compile test program with profiling instrumentation. +clang -o test test.cc -O3 -fprofile-instr-generate + +# Collect profiling data from multiple runs. +for i in {0..10}; do + LLVM_PROFILE_FILE="prof.clang/%p.profraw" ./test $(seq 0 $i) +done + +# Merge raw profiling data into single profile data. +llvm-profdata merge -o pgo.profdata prof.clang/*.profraw + +# Optimize test program with profiling data. +clang -o test test.cc -O3 -fprofile-use=pgo.profdata +</code></pre> +<blockquote> +<p>NOTE: If <code>LLVM_PROFILE_FILE</code> is not given the profile data is written to +<code>default.profraw</code> which is re-written on each run. If the <code>LLVM_PROFILE_FILE</code> +contains a <code>%m</code> in the filename, a unique integer will be generated and +consecutive runs will update the same generated profraw file, +<code>LLVM_PROFILE_FILE</code> can specify a new file every time, however that requires +more storage in general.</p> +</blockquote> +<p>After optimizing the program with the profiling data, the <code>main()</code> function +looks as follows.</p> +<pre><code class="language-x86asm">0000000000001060 <main>: + 1060: 50 push rax + ; Jump if argc == 2. + 1061: 83 ff 02 cmp edi,0x2 + 1064: 74 09 je 106f <main+0xf> + ; bar() is on the hot path (fall-through). + 1066: e8 e5 ff ff ff call 1050 <_Z3barv> + 106b: 31 c0 xor eax,eax + 106d: 59 pop rcx + 106e: c3 ret + ; foo() is on the cold path (branch). + 106f: e8 cc ff ff ff call 1040 <_Z3foov> + 1074: 31 c0 xor eax,eax + 1076: 59 pop rcx + 1077: c3 ret +</code></pre> +<h2 id="gcc"><a class="header" href="#gcc">gcc</a></h2> +<p>With <code>gcc 13.2.1</code> on the current machine, the optimizer puts <code>bar()</code> on the +<code>hot path</code> by default.</p> +<pre><code class="language-x86asm">0000000000001040 <main>: + 1040: 48 83 ec 08 sub rsp,0x8 + ; Jump if argc == 2. + 1044: 83 ff 02 cmp edi,0x2 + 1047: 74 0c je 1055 <main+0x15> + ; bar () is on the hot path (fall-through). + 1049: e8 22 01 00 00 call 1170 <_Z3barv> + 104e: 31 c0 xor eax,eax + 1050: 48 83 c4 08 add rsp,0x8 + 1054: c3 ret + ; foo() is on the cold path (branch). + 1055: e8 06 01 00 00 call 1160 <_Z3foov> + 105a: eb f2 jmp 104e <main+0xe> + 105c: 0f 1f 40 00 nop DWORD PTR [rax+0x0] + +</code></pre> +<p>The following shows how to compile with profiling instrumentation and how to +optimize the final program with the collected profiling data.</p> +<p>The arguments to <code>./test</code> are chosen such that <code>2/3</code> runs call <code>foo()</code>, which +is currently on the <code>cold path</code>.</p> +<pre><code class="language-bash">gcc -o test test.cc -O3 -fprofile-generate +./test 1 +./test 1 +./test 2 2 +gcc -o test test.cc -O3 -fprofile-use +</code></pre> +<blockquote> +<p>NOTE: Consecutive runs update the generated <code>test.gcda</code> profile data file +rather than re-write it.</p> +</blockquote> +<p>After optimizing the program with the profiling data, the <code>main()</code> function</p> +<pre><code class="language-x86asm">0000000000001040 <main.cold>: + ; bar() is on the cold path (branch). + 1040: e8 05 00 00 00 call 104a <_Z3barv> + 1045: e9 25 00 00 00 jmp 106f <main+0xf> + +0000000000001060 <main>: + 1060: 51 push rcx + ; Jump if argc != 2. + 1061: 83 ff 02 cmp edi,0x2 + 1064: 0f 85 d6 ff ff ff jne 1040 <main.cold> + ; for() is on the hot path (fall-through). + 106a: e8 11 01 00 00 call 1180 <_Z3foov> + 106f: 31 c0 xor eax,eax + 1071: 5a pop rdx + 1072: c3 ret +</code></pre> <div style="break-before: page; page-break-before: always;"></div><h1 id="linux"><a class="header" href="#linux">Linux</a></h1> <ul> <li><a href="linux/./systemd.html">systemd</a></li> @@ -4102,6 +4430,9 @@ clean: <pre><code class="language-text">systemctl [opts] [cmd] [opts] --user + --type=TYPE List only given types eg, service, timer, socket (use --type=help for a list) + --state=STATE List only given states eg running, enabled (use --state=help for a list) + --failed List only failed services [cmd] list-units <pattern> List units in memory @@ -4119,6 +4450,13 @@ clean: cat <unit> Print unit file show <unit> Show properties of unit </code></pre> +<h3 id="example-list-failed-units"><a class="header" href="#example-list-failed-units">Example: List failed units</a></h3> +<pre><code class="language-bash"># List all system failed units. +systemctl --failed + +# List all user failed units. +systemctl --user --failed +</code></pre> <h3 id="example-trivial-user-unit"><a class="header" href="#example-trivial-user-unit">Example: Trivial user unit</a></h3> <pre><code class="language-bash"># Generate unit mkdir -p ~/.config/systemd/user @@ -4360,7 +4698,7 @@ For example as <code>systemd</code> service:</p> <div style="break-before: page; page-break-before: always;"></div><h1 id="linux-input"><a class="header" href="#linux-input">Linux input</a></h1> <p>Some notes on using <code>/dev/input/*</code> device driver files.</p> <h2 id="mousex--mice"><a class="header" href="#mousex--mice">mouseX / mice</a></h2> -<p>These device files are created by the [mousedev] driver.</p> +<p>These device files are created by the <a href="https://elixir.bootlin.com/linux/latest/source/drivers/input/mousedev.c#L842">mousedev</a> driver.</p> <ul> <li><code>/dev/input/mouseX</code> represents the input stream for a <em>SINGLE</em> mouse device.</li> <li><code>/dev/input/mice</code> represents the merged input stream for <em>ALL</em> mouse devices.</li> @@ -4375,9 +4713,9 @@ For example as <code>systemd</code> service:</p> <pre><code class="language-bash">sudo cat /dev/input/mice | od -tx1 -w3 -v </code></pre> <h2 id="eventx"><a class="header" href="#eventx">eventX</a></h2> -<p>These device files are created by the [evdev] driver.</p> +<p>These device files are created by the <a href="https://elixir.bootlin.com/linux/latest/source/drivers/input/evdev.c#L1337">evdev</a> driver.</p> <ul> -<li><code>/dev/input/eventX</code> represents the generic input event interface a <em>SINGLE</em> input deivece.</li> +<li><code>/dev/input/eventX</code> represents the generic input event interface a <em>SINGLE</em> input device.</li> </ul> <p>Input events are encoded as given by the <code>input_event</code> struct below. Reading from the <code>eventX</code> device file will always yield whole number of input events.</p> @@ -4391,7 +4729,7 @@ from the <code>eventX</code> device file will always yield whole number of input <p>On most 64bit machines the raw data stream can be inspected as follows.</p> <pre><code class="language-bash">sudo cat /dev/input/event4 | od -tx1 -w24 -v </code></pre> -<h2 id="identifyin-device-files"><a class="header" href="#identifyin-device-files">Identifyin device files.</a></h2> +<h2 id="identifying-device-files"><a class="header" href="#identifying-device-files">Identifying device files.</a></h2> <p>To find out which device file is assigned to which input device the following file <code>/proc/bus/input/devices</code> in the proc filesystem can be consulted.</p> <p>This yields entries as follows and shows which <code>Handlers</code> are assigned to which @@ -4474,8 +4812,6 @@ int main(int argc, char* argv[]) { } } </code></pre> -<p>[mousedev]: TODO /home/johannst/dev/linux/drivers/input/mousedev.c -[evdev]: TODO /home/johannst/dev/linux/drivers/input/evdev.c</p> <div style="break-before: page; page-break-before: always;"></div><h1 id="access-control-list-acl"><a class="header" href="#access-control-list-acl">access control list (acl)</a></h1> <blockquote> <p>This describes <code>POSIX</code> acl.</p> @@ -5430,6 +5766,7 @@ Hi ASM-World! <li><a href="https://sourceware.org/binutils/docs/as">GNU Assembler</a></li> <li><a href="https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops">GNU Assembler Directives</a></li> <li><a href="https://sourceware.org/binutils/docs/as/i386_002dDependent.html">GNU Assembler <code>x86_64</code> dependent features</a></li> +<li><a href="https://github.com/johannst/juicebox-asm"><code>juicebox-asm</code> an <code>x86_64</code> jit assembler playground</a></li> </ul> <div style="break-before: page; page-break-before: always;"></div><h1 id="arm64"><a class="header" href="#arm64">arm64</a></h1> <p>keywords: arm64, aarch64, abi</p> @@ -5975,6 +6312,7 @@ required when compiling natively on riscv.</p> <ul> <li><a href="https://sourceware.org/binutils/docs/as">GNU Assembler</a></li> <li><a href="https://sourceware.org/binutils/docs/as/Pseudo-Ops.html#Pseudo-Ops">GNU Assembler Directives</a></li> +<li><a href="https://github.com/johannst/rv64i-linux-user-no-std">rv64i-linux-user-no-std</a></li> </ul> </main> |