diff options
author | johannst <johannst@users.noreply.github.com> | 2021-11-28 22:26:50 +0000 |
---|---|---|
committer | johannst <johannst@users.noreply.github.com> | 2021-11-28 22:26:50 +0000 |
commit | ba7d38240198ba854384328843da52a26209f488 (patch) | |
tree | 5987f887632ff95cd115beff9841eac7856bc0e3 /print.html | |
parent | 241f2c89769a72a0e04540a0310af2817b60ae24 (diff) | |
download | notes-ba7d38240198ba854384328843da52a26209f488.tar.gz notes-ba7d38240198ba854384328843da52a26209f488.zip |
deploy: 6660154d7eaae83f3e8765af8b93dcd651e05452
Diffstat (limited to 'print.html')
-rw-r--r-- | print.html | 365 |
1 files changed, 357 insertions, 8 deletions
@@ -83,7 +83,7 @@ <nav id="sidebar" class="sidebar" aria-label="Table of contents"> <div id="sidebar-scrollbox" class="sidebar-scrollbox"> - <ol class="chapter"><li class="expanded affix "><a href="intro.html">Introduction</a></li><li class="expanded "><a href="tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="expanded "><a href="tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="expanded "><a href="tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="expanded "><a href="tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="expanded "><a href="tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="expanded "><a href="tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="expanded "><a href="tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="expanded "><a href="tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="expanded "><a href="tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="expanded "><a href="tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="expanded "><a href="tools/radare2.html"><strong aria-hidden="true">1.10.</strong> radare2</a></li><li class="expanded "><a href="tools/qemu.html"><strong aria-hidden="true">1.11.</strong> qemu</a></li></ol></li><li class="expanded "><a href="monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="expanded "><a href="monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="expanded "><a href="monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="expanded "><a href="monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="expanded "><a href="monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="expanded "><a href="monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="expanded "><a href="monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="expanded "><a href="trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="expanded "><a href="trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="expanded "><a href="trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="expanded "><a href="trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="expanded "><a href="trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="expanded "><a href="trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="expanded "><a href="binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="expanded "><a href="binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="expanded "><a href="binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="expanded "><a href="binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="expanded "><a href="binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="expanded "><a href="binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="expanded "><a href="development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="expanded "><a href="development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="expanded "><a href="development/c++.html"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="expanded "><a href="development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="expanded "><a href="development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="expanded "><a href="development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="expanded "><a href="development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li></ol></li><li class="expanded "><a href="arch/index.html"><strong aria-hidden="true">6.</strong> Arch</a></li><li><ol class="section"><li class="expanded "><a href="arch/x86_64.html"><strong aria-hidden="true">6.1.</strong> x86_64</a></li><li class="expanded "><a href="arch/arm64.html"><strong aria-hidden="true">6.2.</strong> arm64</a></li><li class="expanded "><a href="arch/armv7.html"><strong aria-hidden="true">6.3.</strong> armv7</a></li></ol></li></ol> + <ol class="chapter"><li class="expanded affix "><a href="intro.html">Introduction</a></li><li class="expanded "><a href="tools/index.html"><strong aria-hidden="true">1.</strong> Tools</a></li><li><ol class="section"><li class="expanded "><a href="tools/zsh.html"><strong aria-hidden="true">1.1.</strong> zsh</a></li><li class="expanded "><a href="tools/bash.html"><strong aria-hidden="true">1.2.</strong> bash</a></li><li class="expanded "><a href="tools/fish.html"><strong aria-hidden="true">1.3.</strong> fish</a></li><li class="expanded "><a href="tools/tmux.html"><strong aria-hidden="true">1.4.</strong> tmux</a></li><li class="expanded "><a href="tools/git.html"><strong aria-hidden="true">1.5.</strong> git</a></li><li class="expanded "><a href="tools/awk.html"><strong aria-hidden="true">1.6.</strong> awk</a></li><li class="expanded "><a href="tools/emacs.html"><strong aria-hidden="true">1.7.</strong> emacs</a></li><li class="expanded "><a href="tools/gpg.html"><strong aria-hidden="true">1.8.</strong> gpg</a></li><li class="expanded "><a href="tools/gdb.html"><strong aria-hidden="true">1.9.</strong> gdb</a></li><li class="expanded "><a href="tools/radare2.html"><strong aria-hidden="true">1.10.</strong> radare2</a></li><li class="expanded "><a href="tools/qemu.html"><strong aria-hidden="true">1.11.</strong> qemu</a></li><li class="expanded "><a href="tools/pacman.html"><strong aria-hidden="true">1.12.</strong> pacman</a></li></ol></li><li class="expanded "><a href="monitor/index.html"><strong aria-hidden="true">2.</strong> Resource analysis & monitor</a></li><li><ol class="section"><li class="expanded "><a href="monitor/lsof.html"><strong aria-hidden="true">2.1.</strong> lsof</a></li><li class="expanded "><a href="monitor/ss.html"><strong aria-hidden="true">2.2.</strong> ss</a></li><li class="expanded "><a href="monitor/pidstat.html"><strong aria-hidden="true">2.3.</strong> pidstat</a></li><li class="expanded "><a href="monitor/pgrep.html"><strong aria-hidden="true">2.4.</strong> pgrep</a></li><li class="expanded "><a href="monitor/pmap.html"><strong aria-hidden="true">2.5.</strong> pmap</a></li><li class="expanded "><a href="monitor/pstack.html"><strong aria-hidden="true">2.6.</strong> pstack</a></li></ol></li><li class="expanded "><a href="trace_profile/index.html"><strong aria-hidden="true">3.</strong> Trace and Profile</a></li><li><ol class="section"><li class="expanded "><a href="trace_profile/strace.html"><strong aria-hidden="true">3.1.</strong> strace</a></li><li class="expanded "><a href="trace_profile/ltrace.html"><strong aria-hidden="true">3.2.</strong> ltrace</a></li><li class="expanded "><a href="trace_profile/perf.html"><strong aria-hidden="true">3.3.</strong> perf</a></li><li class="expanded "><a href="trace_profile/oprofile.html"><strong aria-hidden="true">3.4.</strong> OProfile</a></li><li class="expanded "><a href="trace_profile/time.html"><strong aria-hidden="true">3.5.</strong> time</a></li></ol></li><li class="expanded "><a href="binary/index.html"><strong aria-hidden="true">4.</strong> Binary</a></li><li><ol class="section"><li class="expanded "><a href="binary/od.html"><strong aria-hidden="true">4.1.</strong> od</a></li><li class="expanded "><a href="binary/xxd.html"><strong aria-hidden="true">4.2.</strong> xxd</a></li><li class="expanded "><a href="binary/readelf.html"><strong aria-hidden="true">4.3.</strong> readelf</a></li><li class="expanded "><a href="binary/objdump.html"><strong aria-hidden="true">4.4.</strong> objdump</a></li><li class="expanded "><a href="binary/nm.html"><strong aria-hidden="true">4.5.</strong> nm</a></li></ol></li><li class="expanded "><a href="development/index.html"><strong aria-hidden="true">5.</strong> Development</a></li><li><ol class="section"><li class="expanded "><a href="development/c++filt.html"><strong aria-hidden="true">5.1.</strong> c++filt</a></li><li class="expanded "><a href="development/c++.html"><strong aria-hidden="true">5.2.</strong> c++</a></li><li class="expanded "><a href="development/glibc.html"><strong aria-hidden="true">5.3.</strong> glibc</a></li><li class="expanded "><a href="development/gcc.html"><strong aria-hidden="true">5.4.</strong> gcc</a></li><li class="expanded "><a href="development/make.html"><strong aria-hidden="true">5.5.</strong> make</a></li><li class="expanded "><a href="development/ld.so.html"><strong aria-hidden="true">5.6.</strong> ld.so</a></li><li class="expanded "><a href="development/symbolver.html"><strong aria-hidden="true">5.7.</strong> symbol versioning</a></li><li class="expanded "><a href="development/python.html"><strong aria-hidden="true">5.8.</strong> python</a></li></ol></li><li class="expanded "><a href="arch/index.html"><strong aria-hidden="true">6.</strong> Arch</a></li><li><ol class="section"><li class="expanded "><a href="arch/x86_64.html"><strong aria-hidden="true">6.1.</strong> x86_64</a></li><li class="expanded "><a href="arch/arm64.html"><strong aria-hidden="true">6.2.</strong> arm64</a></li><li class="expanded "><a href="arch/armv7.html"><strong aria-hidden="true">6.3.</strong> armv7</a></li></ol></li></ol> </div> <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div> </nav> @@ -170,6 +170,7 @@ <li><a href="tools/./gdb.html">gdb</a></li> <li><a href="tools/./radare2.html">radare2</a></li> <li><a href="tools/./qemu.html">qemu</a></li> +<li><a href="tools/./pacman.html">pacman</a></li> </ul> <h1><a class="header" href="#zsh1" id="zsh1">zsh(1)</a></h1> <h2><a class="header" href="#keybindings" id="keybindings">Keybindings</a></h2> @@ -1886,6 +1887,45 @@ launched with the <strong>same</strong> parameters.</p> <li><a href="https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html">QEMU machine protocol (QMP)</a></li> <li><a href="https://qemu-project.gitlab.io/qemu/system/images.html#vm-005fsnapshots">QEMU VM Snapshots</a></li> </ul> +<h1><a class="header" href="#pacman1" id="pacman1">pacman(1)</a></h1> +<h2><a class="header" href="#remote-package-repositories" id="remote-package-repositories">Remote package repositories</a></h2> +<pre><code class="language-text">pacman -Sy refresh package database +pacman -S <pkg> install pkg +pacman -Ss <regex> search remote package database +pacman -Si <pkg> get info for pkg +pacman -Su upgrade installed packages +pacman -Sc clean local package cache +</code></pre> +<h2><a class="header" href="#remove-packages" id="remove-packages">Remove packages</a></h2> +<pre><code class="language-text">pacman -Rsn <pkg> uninstall package and unneeded deps + config files +</code></pre> +<h2><a class="header" href="#local-package-database" id="local-package-database">Local package database</a></h2> +<p>Local package database of installed packages.</p> +<pre><code class="language-text">pacman -Q list all installed packages +pacman -Qs <regex> search local package database +pacman -Ql <pkg> list files installed by pkg +pacman -Qo <file> query package that owns file +pacman -Qe only list explicitly installed packages +</code></pre> +<h2><a class="header" href="#local-file-database" id="local-file-database">Local file database</a></h2> +<p>Local file database which allows to search packages owning certain files. +Also searches non installed packages, but database must be synced.</p> +<pre><code class="language-text">pacman -Fy refresh file database +pacman -Fl <pkg> list files in pkg (must not be installed) +pacman -Fx <regex> search +</code></pre> +<h2><a class="header" href="#hacks" id="hacks">Hacks</a></h2> +<p>Uninstall all orphaned packages (including config files) that were installed as +dependencies.</p> +<pre><code class="language-text">pacman -Rsn $(pacman -Qqtq) +</code></pre> +<p>List explicitly installed packages that are not required as dependency by any +package and sort by size.</p> +<pre><code class="language-text">pacman -Qetq | xargs pacman -Qi | + awk '/Name/ { name=$3 } + /Installed Size/ { printf "%8.2f%s %s\n", $4, $5, name }' | + sort -h +</code></pre> <h1><a class="header" href="#resource-analysis--monitor" id="resource-analysis--monitor">Resource analysis & monitor</a></h1> <ul> <li><a href="monitor/./lsof.html">lsof</a></li> @@ -2238,6 +2278,8 @@ the <code>.rodata</code> section as follows:</p> <li><a href="development/./gcc.html">gcc</a></li> <li>[make] (./make.md)</li> <li><a href="development/./ld.so.html">ld.so</a></li> +<li><a href="development/./symbolver.html">symbol versioning</a></li> +<li><a href="development/./python.html">python</a></li> </ul> <h1><a class="header" href="#cfilt1" id="cfilt1">c++filt(1)</a></h1> <h2><a class="header" href="#demangle-symbol" id="demangle-symbol">Demangle symbol</a></h2> @@ -2295,6 +2337,13 @@ LD_PRELOAD=./libmtrace.so <binary> <li><code>-E</code> run only preprocessor</li> <li><code>-dM</code> list only <code>#define</code> statements</li> </ul> +<h3><a class="header" href="#target-options" id="target-options">Target options</a></h3> +<pre><code class="language-bash"># List all target options with their description. +gcc --help=target + +# Configure for current cpu arch and query (-Q) value of options. +gcc -march=native -Q --help=target +</code></pre> <h2><a class="header" href="#a-hrefhttpsgccgnuorgonlinedocsgccother-builtinshtmlbuiltinsa" id="a-hrefhttpsgccgnuorgonlinedocsgccother-builtinshtmlbuiltinsa"><a href="https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html">Builtins</a></a></h2> <h3><a class="header" href="#__builtin_expectexpr-cond" id="__builtin_expectexpr-cond"><code>__builtin_expect(expr, cond)</code></a></h3> <p>Give the compiler a hint which branch is hot, so it can lay out the code @@ -2546,6 +2595,303 @@ search for and where to put the function pointer: </code></pre> As we can see the offset from relocation at index <code>0</code> points to <code>GOT[3]</code>.</li> </ul> +<h1><a class="header" href="#elf-symbol-versioning" id="elf-symbol-versioning">ELF Symbol Versioning</a></h1> +<p>The <a href="https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html">ELF symbol versioning</a> mechanism allows to attach version +information to symbols. +This can be used to express symbol version requirements or to provide certain +symbols multiple times in the same ELF file with different versions (eg for +backwards compatibility).</p> +<p>The <code>libpthread.so</code> library is an example which provides the +<code>pthread_cond_wait</code> symbol multiple times but in different versions. +With readelf the version of the symbol can be seen after the <code>@</code>.</p> +<pre><code class="language-bash">> readelf -W --dyn-syms /lib/libpthread.so + +Symbol table '.dynsym' contains 342 entries: + Num: Value Size Type Bind Vis Ndx Name + ... + 141: 0000f080 696 FUNC GLOBAL DEFAULT 16 pthread_cond_wait@@GLIBC_2.3.2 + 142: 00010000 111 FUNC GLOBAL DEFAULT 16 pthread_cond_wait@GLIBC_2.2.5 +</code></pre> +<p>The <code>@@</code> denotes the <strong>default symbol version</strong> which will be used during +static linking against the library. +The following dump shows that the <code>tmp</code> program linked against <code>lpthread</code> will +depend on the symbol version <code>GLIBC_2.3.2</code>, which is the default version.</p> +<pre><code class="language-bash">> echo "#include <pthread.h> + int main() { + return pthread_cond_wait(0,0); + }" | gcc -o tmp -xc - -lpthread; + readelf -W --dyn-syms tmp | grep pthread_cond_wait; + +Symbol table '.dynsym' contains 7 entries: + Num: Value Size Type Bind Vis Ndx Name + ... + 2: 00000000 0 FUNC GLOBAL DEFAULT UND pthread_cond_wait@GLIBC_2.3.2 (2) +</code></pre> +<blockquote> +<p>Only <strong>one</strong> symbol can be annotated as the <code>@@</code> default version.</p> +</blockquote> +<p>Using the <code>--version-info</code> flag with readelf, more details on the symbol +version info compiled into the <code>tmp</code> ELF file can be obtained.</p> +<ul> +<li>The <code>.gnu.version</code> section contains the version definition for each symbol in +the <code>.dynsym</code> section. <code>pthread_cond_wait</code> is at index <code>2</code> in the <code>.dynsym</code> +section, the corresponding symbol version is at index <code>2</code> in the +<code>.gnu.version</code> section.</li> +<li>The <code>.gnu.version_r</code> section contains symbol version requirements per shared +library dependency (<code>DT_NEEDED</code> dynamic entry).</li> +</ul> +<pre><code class="language-bash">> readelf -W --version-info --dyn-syms tmp + +Symbol table '.dynsym' contains 7 entries: + Num: Value Size Type Bind Vis Ndx Name + 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND + 1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable + 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND pthread_cond_wait@GLIBC_2.3.2 (2) + 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (3) + 4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ + 5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable + 6: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (3) + +Version symbols section '.gnu.version' contains 7 entries: + Addr: 0x0000000000000534 Offset: 0x000534 Link: 6 (.dynsym) + 000: 0 (*local*) 0 (*local*) 2 (GLIBC_2.3.2) 3 (GLIBC_2.2.5) + 004: 0 (*local*) 0 (*local*) 3 (GLIBC_2.2.5) + +Version needs section '.gnu.version_r' contains 2 entries: + Addr: 0x0000000000000548 Offset: 0x000548 Link: 7 (.dynstr) + 000000: Version: 1 File: libc.so.6 Cnt: 1 + 0x0010: Name: GLIBC_2.2.5 Flags: none Version: 3 + 0x0020: Version: 1 File: libpthread.so.0 Cnt: 1 + 0x0030: Name: GLIBC_2.3.2 Flags: none Version: 2 +</code></pre> +<p>The gnu dynamic linker allows to inspect the version processing during runtime +by setting the <code>LD_DEBUG</code> environment variable accordingly.</p> +<pre><code class="language-text"># version: Display version dependencies. +> LD_DEBUG=versions ./tmp + 717904: checking for version `GLIBC_2.2.5' in file /usr/lib/libc.so.6 [0] required by file ./tmp [0] + 717904: checking for version `GLIBC_2.3.2' in file /usr/lib/libpthread.so.0 [0] required by file ./tmp [0] + ... + +# symbols : Display symbol table processing. +# bindings: Display information about symbol binding. +> LD_DEBUG=symbols,bindings ./tmp + ... + 718123: symbol=pthread_cond_wait; lookup in file=./tmp [0] + 718123: symbol=pthread_cond_wait; lookup in file=/usr/lib/libpthread.so.0 [0] + 718123: binding file ./tmp [0] to /usr/lib/libpthread.so.0 [0]: normal symbol `pthread_cond_wait' [GLIBC_2.3.2] +</code></pre> +<h2><a class="header" href="#example-version-script" id="example-version-script">Example: version script</a></h2> +<p>The following shows an example C++ library <code>libfoo</code> which provides the same +symbol multiple times but in different versions.</p> +<pre><code class="language-cpp">// file: libfoo.cc +#include<stdio.h> + +// Bind function symbols to version nodes. +// +// ..@ -> Is the unversioned symbol. +// ..@@.. -> Is the default symbol. + +__asm__(".symver func_v0,func@"); +__asm__(".symver func_v1,func@LIB_V1"); +__asm__(".symver func_v2,func@@LIB_V2"); + +extern "C" { + void func_v0() { puts("func_v0"); } + void func_v1() { puts("func_v1"); } + void func_v2() { puts("func_v2"); } +} + +__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1"); +__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2"); + +void func_cpp_v1(int) { puts("func_cpp_v1"); } +void func_cpp_v2(int) { puts("func_cpp_v2"); } + +void func_cpp(int) { puts("func_cpp_v2"); } +</code></pre> +<p>Version script for <code>libfoo</code> which defines which symbols for which versions are +exported from the ELF file.</p> +<pre><code class="language-ld"># file: libfoo.ver +LIB_V1 { + global: + func; + extern "C++" { + "func_cpp(int)"; + }; + local: + *; +}; + +LIB_V2 { + global: + func; + extern "C++" { + "func_cpp(int)"; + }; +} LIB_V1; +</code></pre> +<blockquote> +<p>The <strong>local:</strong> section in <code>LIB_V1</code> is a catch all, that matches any symbol +not explicitly specified, and defines that the symbol is local and therefore +not exported from the ELF file.</p> +</blockquote> +<p>The library <code>libfoo</code> can be linked with the version definitions in <code>libfoo.ver</code> +by passing the version script to the linker with the <code>--version-script</code> flag.</p> +<pre><code class="language-bash">> g++ -shared -fPIC -o libfoo.so libfoo.cc -Wl,--version-script=libfoo.ver +> readelf -W --dyn-syms libfoo.so | c++filt + +Symbol table '.dynsym' contains 14 entries: + Num: Value Size Type Bind Vis Ndx Name + ... + 6: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIB_V1 + 7: 000000000000114b 29 FUNC GLOBAL DEFAULT 13 func_cpp(int)@LIB_V1 + 8: 0000000000001168 29 FUNC GLOBAL DEFAULT 13 func_cpp(int)@@LIB_V2 + 9: 0000000000001185 29 FUNC GLOBAL DEFAULT 13 func_cpp(int)@@LIB_V1 + 10: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS LIB_V2 + 11: 0000000000001109 22 FUNC GLOBAL DEFAULT 13 func + 12: 000000000000111f 22 FUNC GLOBAL DEFAULT 13 func@LIB_V1 + 13: 0000000000001135 22 FUNC GLOBAL DEFAULT 13 func@@LIB_V2 +</code></pre> +<p>The following program demonstrates how to make use of the different versions:</p> +<pre><code class="language-cpp">// file: main.cc +#include <dlfcn.h> +#include <assert.h> + +// Links against default symbol in the lib.so. +extern "C" void func(); + +int main() { + // Call the default version. + func(); + +#ifdef _GNU_SOURCE + typedef void (*fnptr)(); + + // Unversioned lookup. + fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, "func"); + // Version lookup. + fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V1"); + fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V2"); + + assert(fn_v0 != 0); + assert(fn_v1 != 0); + assert(fn_v2 != 0); + + fn_v0(); + fn_v1(); + fn_v2(); +#endif + + return 0; +} +</code></pre> +<p>Compiling and running results in:</p> +<pre><code class="language-bash">> g++ -o main main.cc -ldl ./libfoo.so && ./main +func_v2 +func_v0 +func_v1 +func_v2 +</code></pre> +<h2><a class="header" href="#references-1" id="references-1">References</a></h2> +<ul> +<li><a href="https://akkadia.org/drepper/symbol-versioning">ELF Symbol Versioning</a></li> +<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> +</ul> +<h1><a class="header" href="#python" id="python">python</a></h1> +<h2><a class="header" href="#decorator-a-hrefhttpswwwonline-pythoncomiddie0gpyuruna" id="decorator-a-hrefhttpswwwonline-pythoncomiddie0gpyuruna">Decorator [<a href="https://www.online-python.com/IDdiE0gpYU">run</a>]</a></h2> +<p>Some decorator examples with type annotation.</p> +<pre><code class="language-python">from typing import Callable + +def log(f: Callable[[int], None]) -> Callable[[int], None]: + def inner(x: int): + print(f"log::inner f={f.__name__} x={x}") + f(x) + return inner + +@log +def some_fn(x: int): + print(f"some_fn x={x}") + + +def log_tag(tag: str) -> Callable[[Callable[[int], None]], Callable[[int], None]]: + def decorator(f: Callable[[int], None]) -> Callable[[int], None]: + def inner(x: int): + print(f"log_tag::inner f={f.__name__} tag={tag} x={x}") + f(x) + return inner + return decorator + +@log_tag("some_tag") +def some_fn2(x: int): + print(f"some_fn2 x={x}") +</code></pre> +<h2><a class="header" href="#walrus-operator-a-hrefhttpswwwonline-pythoncom9t12pvmkvyruna" id="walrus-operator-a-hrefhttpswwwonline-pythoncom9t12pvmkvyruna">Walrus operator [<a href="https://www.online-python.com/9T12PvmKVy">run</a>]</a></h2> +<p>Walrus operator <code>:=</code> added since <strong>python 3.8</strong>.</p> +<pre><code class="language-python">from typing import Optional + +# Example 1: if let statements + +def foo(ret: Optional[int]) -> Optional[int]: + return ret + +if r := foo(None): + print(f"foo(None) -> {r}") + +if r := foo(1337): + print(f"foo(1337) -> {r}") + +# Example 2: while let statements + +toks = iter(['a', 'b', 'c']) +while tok := next(toks, None): + print(f"{tok}") + +# Example 3: list comprehension + +print([tok for t in [" a", " ", " b "] if (tok := t.strip())]) +</code></pre> +<h2><a class="header" href="#a-hrefhttpsdocspythonorg3libraryunittesthtmlunittesta-a-hrefhttpswwwonline-pythoncom2fit4ucbziruna" id="a-hrefhttpsdocspythonorg3libraryunittesthtmlunittesta-a-hrefhttpswwwonline-pythoncom2fit4ucbziruna"><a href="https://docs.python.org/3/library/unittest.html">Unittest</a> [<a href="https://www.online-python.com/2fit4UcbzI">run</a>]</a></h2> +<p>Run unittests directly from the command line as <br /> +<code>python3 -m unittest -v test</code></p> +<p>Optionally pass <code>-k <patter></code> to only run subset of tests.</p> +<pre><code class="language-python"># file: test.py + +import unittest + +class MyTest(unittest.TestCase): + def setUp(self): + pass + def tearDown(self): + pass + # Tests need to start with the prefix 'test'. + def test_foo(self): + self.assertEqual(1 + 2, 3) + def test_bar(self): + with self.assertRaises(IndexError): + list()[0] +</code></pre> +<h2><a class="header" href="#a-hrefhttpsdocspythonorg3librarydoctesthtmldoctesta-a-hrefhttpswwwonline-pythoncomlzst51unihruna" id="a-hrefhttpsdocspythonorg3librarydoctesthtmldoctesta-a-hrefhttpswwwonline-pythoncomlzst51unihruna"><a href="https://docs.python.org/3/library/doctest.html">Doctest</a> [<a href="https://www.online-python.com/LZst51UNIH">run</a>]</a></h2> +<p>Run doctests directly from the command line as <br /> +<code>python -m doctest -v test.py</code></p> +<pre><code class="language-python"># file: test.py + +def sum(a: int, b: int) -> int: + """Sum a and b. + + >>> sum(1, 2) + 3 + + >>> sum(10, 20) + 30 + """ + return a + b +</code></pre> +<h2><a class="header" href="#a-hrefhttpsdocspythonorg3librarytimeithtmltimeita" id="a-hrefhttpsdocspythonorg3librarytimeithtmltimeita"><a href="https://docs.python.org/3/library/timeit.html">timeit</a></a></h2> +<p>Micro benchmarking.</p> +<pre><code class="language-bash">python -m timeit '[x.strip() for x in ["a ", " b"]]' +</code></pre> <h1><a class="header" href="#arch" id="arch">Arch</a></h1> <ul> <li><a href="arch/./x86_64.html">x86_64</a></li> @@ -2805,7 +3151,7 @@ greeting_len: <pre><code class="language-bash">> gcc -o greet greet.s -nostartfiles -nostdlib && ./greet Hi ASM-World! </code></pre> -<h2><a class="header" href="#references-1" id="references-1">References</a></h2> +<h2><a class="header" href="#references-2" id="references-2">References</a></h2> <ul> <li><a href="https://www.uclibc.org/docs/psABI-x86_64.pdf">SystemV AMD64 ABI</a></li> <li><a href="https://www.amd.com/system/files/TechDocs/24592.pdf">AMD64 Vol1: Application Programming</a></li> @@ -3034,7 +3380,7 @@ Hi ASM-World! distributions. Explicitly specifying the dynamic linker should not be required when compiling natively on arm64.</p> </blockquote> -<h2><a class="header" href="#references-2" id="references-2">References</a></h2> +<h2><a class="header" href="#references-3" id="references-3">References</a></h2> <ul> <li><a href="https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst">Procedure Call Standard ARM64</a></li> <li><a href="https://developer.arm.com/documentation/den0024/latest">ARMv8-A Programmer's Guide</a></li> @@ -3104,10 +3450,13 @@ blx <Rm> // absolute branch to address in register Rm & </code></pre> <h3><a class="header" href="#loadstore" id="loadstore">Load/Store</a></h3> <p>Different addressing modes.</p> -<pre><code class="language-armasm">str r1, [r0] // [r0]=r1 -str r1, [r0, #4] // [r0+4]=r1 -str r1, [r0, #4]! // r0+=4; [r0]=r1 -str r1, [r0], 4 // [r0]=r1; r0+=4 +<pre><code class="language-armasm">ldr r1, [r0] // r1 = [r0] +ldr r1, [r0, #4] // r1 = [r0+4] + +ldr r1, [r0, #4]! // pre-inc : r0+=4; r1 = [r0] +ldr r1, [r0], #4 // post-inc: [r0] = r1; r0+=4 + +ldr r0, [r1, r2, lsl #3] // r0 = [r1 + (r2<<3)] </code></pre> <p>Load/store multiple registers full-descending.</p> <pre><code class="language-armasm">stmfd r0!, {r1-r2, r5} // r0-=4; [r0]=r5 @@ -3275,7 +3624,7 @@ Hi ASM-World! distributions. Explicitly specifying the dynamic linker should not be required when compiling natively on arm.</p> </blockquote> -<h2><a class="header" href="#references-3" id="references-3">References</a></h2> +<h2><a class="header" href="#references-4" id="references-4">References</a></h2> <ul> <li><a href="https://github.com/ARM-software/abi-aa/blob/master/aapcs32/aapcs32.rst">Procedure Call Standard ARM</a></li> <li><a href="https://developer.arm.com/documentation/den0013/latest">ARMv7-A Programmer's Guide</a></li> |