<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Eli Bendersky's website - Linkers and Loaders</title><link href="https://eli.thegreenplace.net/" rel="alternate"></link><link href="https://eli.thegreenplace.net/feeds/linkers-and-loaders.atom.xml" rel="self"></link><id>https://eli.thegreenplace.net/</id><updated>2024-07-30T21:35:34-07:00</updated><entry><title>Building static binaries with Go on Linux</title><link href="https://eli.thegreenplace.net/2024/building-static-binaries-with-go-on-linux/" rel="alternate"></link><published>2024-07-30T14:35:00-07:00</published><updated>2024-07-30T21:35:34-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2024-07-30:/2024/building-static-binaries-with-go-on-linux/</id><summary type="html">&lt;p&gt;One of Go's advantages is being able to produce statically-linked
binaries &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;. This doesn't mean that Go always produces such binaries by default,
however; in some scenarios it requires extra work to make this happen.
Specifics here are OS-dependent; here we focus on Unix systems.&lt;/p&gt;
&lt;div class="section" id="basics-hello-world"&gt;
&lt;h2&gt;Basics - hello world&lt;/h2&gt;
&lt;p&gt;This post …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;One of Go's advantages is being able to produce statically-linked
binaries &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;. This doesn't mean that Go always produces such binaries by default,
however; in some scenarios it requires extra work to make this happen.
Specifics here are OS-dependent; here we focus on Unix systems.&lt;/p&gt;
&lt;div class="section" id="basics-hello-world"&gt;
&lt;h2&gt;Basics - hello world&lt;/h2&gt;
&lt;p&gt;This post goes over a series of experiments: we take simple programs and use
&lt;tt class="docutils literal"&gt;go build&lt;/tt&gt; to produce binaries on a Linux machine. We then examine whether
the produced binary is statically or dynamically linked. The first example is
a simple &amp;quot;hello, world&amp;quot;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fmt&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After building it with &lt;tt class="docutils literal"&gt;go build&lt;/tt&gt;, we get a binary. There are a few ways on
Linux to determine whether a binary is statically or dynamically linked. One
is the &lt;tt class="docutils literal"&gt;file&lt;/tt&gt; tool:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ file ./helloworld
helloworld: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=Flm7stIXKLPfvBhTgXmR/PPwdjFUEkc9NCSPRC7io/PofU_qoulSqJ0Ktvgx5g/eQXbAL15zCEIXOBSPZgY, with debug_info, not stripped
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can see it says &amp;quot;statically linked&amp;quot;. Another way is to use &lt;tt class="docutils literal"&gt;ldd&lt;/tt&gt;, which
prints the shared object dependencies of a given binary:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ ldd ./helloworld
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, we can also use the ubiquitous &lt;tt class="docutils literal"&gt;nm&lt;/tt&gt; tool, asking it to list the
undefined symbols in a binary (these are symbols the binary expects the dynamic
linker to provide at run-time from shared objects):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ nm -u ./helloworld
&amp;lt;empty output&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All of these tell us that a simple &lt;tt class="docutils literal"&gt;helloworld&lt;/tt&gt; is a statically-linked binary.
Throughout the post I'll mostly be using &lt;tt class="docutils literal"&gt;ldd&lt;/tt&gt; (out of habit), but you can
use any approach you like.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="dns-and-user-groups"&gt;
&lt;h2&gt;DNS and user groups&lt;/h2&gt;
&lt;p&gt;There are two pieces of functionality the Go standard library defers to the
system's &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; on Unix machines, when some conditions are met. When cgo
is enabled (as it often - but not always - is on Unix machines), Go will call
the C library for DNS lookups in the &lt;tt class="docutils literal"&gt;net&lt;/tt&gt; package and for user and group
ID lookups in the &lt;tt class="docutils literal"&gt;os/user&lt;/tt&gt; package.&lt;/p&gt;
&lt;p&gt;Let's observe this with an experiment:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fmt&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;net&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LookupHost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;go.dev&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we build this program, we notice it's &lt;em&gt;dynamically&lt;/em&gt; linked, expecting to
load a &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; shared object at run-time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go build lookuphost.go
$ ldd ./lookuphost
  linux-vdso.so.1 (0x00007b50cb22a000)
  libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007b50cae00000)
  /lib64/ld-linux-x86-64.so.2 (0x00007b50cb22c000)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is explained in the &lt;a class="reference external" href="https://pkg.go.dev/net#hdr-Name_Resolution"&gt;net package documentation&lt;/a&gt; in some detail. The Go
standard library does have a pure Go implementation of this functionality
(although it may lack some advanced features). We can ask the toolchain to use
it in a couple of ways. First, we can set the &lt;tt class="docutils literal"&gt;netgo&lt;/tt&gt; build tag:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go build -tags netgo lookuphost.go
$ ldd ./lookuphost
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Second, we can disable cgo entirely with the &lt;tt class="docutils literal"&gt;CGO_ENABLED&lt;/tt&gt; env var. This env
var is usually on by default on Unix systems:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go env CGO_ENABLED
1
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we disable it explicitly for our build, we'll get a static binary again:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ CGO_ENABLED=0 go build lookuphost.go
$ ldd ./lookuphost
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similarly, some of the functionality of the &lt;tt class="docutils literal"&gt;os/user&lt;/tt&gt; package uses &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;
by default. Here's an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;encoding/json&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;log&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;os&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;os/user&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;je&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stdout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;je&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This produces a dynamically-linked binary:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go build userlookup.go
$ ldd ./userlookup
  linux-vdso.so.1 (0x0000708301084000)
  libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x0000708300e00000)
  /lib64/ld-linux-x86-64.so.2 (0x0000708301086000)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As with &lt;tt class="docutils literal"&gt;net&lt;/tt&gt;, we can ask the Go toolchain to use the pure Go implementation
of this user lookup functionality. The build tag for this is &lt;tt class="docutils literal"&gt;osusergo&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go build -tags osusergo userlookup.go
$ ldd ./userlookup
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or, we can disable cgo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ CGO_ENABLED=0 go build userlookup.go
$ ldd ./userlookup
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="linking-c-into-our-go-binary"&gt;
&lt;h2&gt;Linking C into our go binary&lt;/h2&gt;
&lt;p&gt;We've seen that the standard library has some functionality that may require
dynamic linking by default, but this is relatively easy to override. What
happens when we actually have C code as part of our Go program, though?&lt;/p&gt;
&lt;p&gt;Go supports C extensions and FFI using &lt;a class="reference external" href="https://pkg.go.dev/cmd/cgo"&gt;cgo&lt;/a&gt;.
For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="c1"&gt;// #include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="c1"&gt;// void helloworld() {&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="c1"&gt;//   printf(&amp;quot;hello, world from C\n&amp;quot;);&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="c1"&gt;// }&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;helloworld&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A program built from this source will be dynamically linked, due to cgo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ go build cstdio.go
$ ldd ./cstdio
  linux-vdso.so.1 (0x00007bc6d68e3000)
  libc.so.6 =&amp;gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007bc6d6600000)
  /lib64/ld-linux-x86-64.so.2 (0x00007bc6d68e5000)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In our C code, &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt; is a call to &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;; even if we don't explicitly
call into the C runtime in our C code, cgo may do it in the scaffolding code
it generates.&lt;/p&gt;
&lt;p&gt;Note that cgo may be involved even if your project has no C code of its own;
several dependencies may bring in cgo. Some popular packages - like the
&lt;a class="reference external" href="https://pkg.go.dev/github.com/mattn/go-sqlite3"&gt;go-sqlite3&lt;/a&gt; driver - depend
on cgo, and importing them will impose a cgo requirement on a program.&lt;/p&gt;
&lt;p&gt;Obviously, building with &lt;tt class="docutils literal"&gt;CGO_ENABLED=0&lt;/tt&gt; is no longer an option.
So what's the recourse?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="linking-a-libc-statically"&gt;
&lt;h2&gt;Linking a &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; statically&lt;/h2&gt;
&lt;p&gt;To recap, once we have C code as part of our Go binary, it's going to be
dynamically linked on Unix, because:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The C code calls into &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; (the C runtime)&lt;/li&gt;
&lt;li&gt;The &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; typically used on Unix systems is &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Glibc"&gt;glibc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The recommended way to link to &lt;tt class="docutils literal"&gt;glibc&lt;/tt&gt; is dynamically (for various
technical and license-related reasons that are outside the scope of this
post)&lt;/li&gt;
&lt;li&gt;Therefore, &lt;tt class="docutils literal"&gt;go build&lt;/tt&gt; produces dynamically-linked Go binaries&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To change this flow of events, we can interpose at step (2) - use a &lt;em&gt;different&lt;/em&gt;
&lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; implementation, one that's statically linked. Luckily, such an
implementation exists and is well used and tested - &lt;a class="reference external" href="https://wiki.musl-libc.org/"&gt;musl&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To follow along, start by installing musl. The standard instructions using
&lt;tt class="docutils literal"&gt;./configure &lt;span class="pre"&gt;--prefix=&amp;lt;MUSLDIR&amp;gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;make&lt;/tt&gt; / &lt;tt class="docutils literal"&gt;make install&lt;/tt&gt; work well.
We'll use &lt;tt class="docutils literal"&gt;$MUSLDIR&lt;/tt&gt; to refer to the directory where musl is installed.
musl comes with a &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; wrapper that makes it easy to pass all the right
flags. To re-build our &lt;tt class="docutils literal"&gt;cstdio&lt;/tt&gt; example using musl, run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ CC=$MUSLDIR/bin/musl-gcc go build --ldflags &amp;#39;-linkmode external -extldflags &amp;quot;-static&amp;quot;&amp;#39; cstdio.go
$ ldd ./cstdio
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;CC&lt;/tt&gt; env var tells &lt;tt class="docutils literal"&gt;go build&lt;/tt&gt; which C compiler to use for cgo; the
linker flags instruct it to use an external linker for the final build
(&lt;a class="reference external" href="https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/cmd/cgo/doc.go;l=830"&gt;read this for the gory details&lt;/a&gt;)
and then to perform a static link.&lt;/p&gt;
&lt;p&gt;This approach works for more complex use cases as well! I won't paste the code
here, but the &lt;a class="reference external" href="https://github.com/eliben/code-for-blog/tree/main/2024/go-static-linking"&gt;sample repository accompanying this post&lt;/a&gt; has a file
called &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;use-sqlite.go&lt;/span&gt;&lt;/tt&gt;; it uses the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;go-sqlite3&lt;/span&gt;&lt;/tt&gt; package. Try
&lt;tt class="docutils literal"&gt;go build&lt;/tt&gt;-ing it normally and observe the dynamically linked binary produced;
next, try to build it with the flags shown above to use musl, and observe
that the produced binary will be statically linked.&lt;/p&gt;
&lt;p&gt;Another curious tidbit is that we now have another way to build a statically-linked
&lt;tt class="docutils literal"&gt;lookuphost&lt;/tt&gt; program - by linking it with musl:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ CC=$MUSLDIR/bin/musl-gcc go build --ldflags &amp;#39;-linkmode external -extldflags &amp;quot;-static&amp;quot;&amp;#39; lookuphost.go
$ ldd ./lookuphost
  not a dynamic executable
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since we didn't provide &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-tags&lt;/span&gt; netgo&lt;/tt&gt; and didn't disable cgo, the Go toolchain
uses calls into &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; to implement DNS lookup; however, since these calls
end up in the statically-linked musl, the final binary is statically linked!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-zig-as-our-c-compiler"&gt;
&lt;h2&gt;Using Zig as our C compiler&lt;/h2&gt;
&lt;p&gt;Another alternative emerged recently to achieve what we want: using the Zig
toolchain. &lt;a class="reference external" href="https://ziglang.org/"&gt;Zig&lt;/a&gt; is a new systems programming language,
which uses a bundled toolchain approach similar to Go. Its toolchain bundles
together a Zig compiler, C/C++ compiler, linker and &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt; for static linking.
Therefore, Zig can actually be used to link Go binaries statically with C code!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Instead&lt;/em&gt; of installing musl, we could instead install Zig and use its
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;x86_64-linux-musl&lt;/span&gt;&lt;/tt&gt; target (adjust the architecture if needed). This is
done by pointing to the &lt;tt class="docutils literal"&gt;zig&lt;/tt&gt; binary as our &lt;tt class="docutils literal"&gt;CC=&lt;/tt&gt; env var; assuming Zig
is installed in &lt;tt class="docutils literal"&gt;$ZIGDIR&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ CC=&amp;quot;$ZIGDIR/zig cc -target x86_64-linux-musl&amp;quot; go build cstdio.go
$ CC=&amp;quot;$ZIGDIR/zig cc -target x86_64-linux-musl&amp;quot; go build use-sqlite.go
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These will produce statically-linked Go binaries; the &lt;tt class="docutils literal"&gt;zig&lt;/tt&gt; driver takes
care of setting the right linker flags automatically, so the command-line ends
up being slightly simpler than invoking &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;musl-gcc&lt;/span&gt;&lt;/tt&gt;. Another advantage of Zig
here is that enables cross-compilation of Go programs that include C code &lt;a class="footnote-reference" href="#footnote-2" id="footnote-reference-2"&gt;[2]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I did find some issues with this approach, however; for example, attempting to
link the &lt;tt class="docutils literal"&gt;lookuphost.go&lt;/tt&gt; sample fails with a slew of linker errors.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="summary"&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Making sure Go produces a statically-linked binary on Linux takes a little
bit of effort, but works well overall.&lt;/p&gt;
&lt;p&gt;There's a &lt;a class="reference external" href="https://github.com/golang/go/issues/26492"&gt;long standing accepted proposal&lt;/a&gt;
about adding a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-static&lt;/span&gt;&lt;/tt&gt; flag to &lt;tt class="docutils literal"&gt;go build&lt;/tt&gt; that would take care of setting
up all the flags required for a static build. AFAICT, the proposal is just
waiting for someone with enough grit and dedication to implement and test it
in all the interesting scenarios.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="code"&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;The code for all the experiments described in this post
&lt;a class="reference external" href="https://github.com/eliben/code-for-blog/tree/main/2024/go-static-linking"&gt;is available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;A &lt;em&gt;statically-linked&lt;/em&gt; binary doesn't have run-time dependencies on
other libraries (typically in the form of shared objects), not even
the C runtime library (&lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;). I wrote much more about this topic
&lt;a class="reference external" href="https://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux"&gt;in the past&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-2" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Go is well-known for its cross-compilation capabilities, but it
depends on the C toolchain to compile C code. Therefore, when cgo is
involved, cross-compilation is challenging. Zig can help with this
because &lt;em&gt;its&lt;/em&gt; toolchain supports cross compilation for Zig &lt;em&gt;and&lt;/em&gt; C! It
does so by bundling LLVM with a bunch of targets linked in.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="Go"></category><category term="Compilation"></category><category term="Linkers and Loaders"></category><category term="Linux"></category></entry><entry><title>Some notes on Luz - an assembler, linker and CPU simulator</title><link href="https://eli.thegreenplace.net/2017/some-notes-on-luz-an-assembler-linker-and-cpu-simulator/" rel="alternate"></link><published>2017-01-05T06:27:00-08:00</published><updated>2024-05-04T19:46:23-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2017-01-05:/2017/some-notes-on-luz-an-assembler-linker-and-cpu-simulator/</id><summary type="html">&lt;p&gt;A few years ago I &lt;a class="reference external" href="https://eli.thegreenplace.net/2010/05/05/introducing-luz"&gt;wrote about Luz&lt;/a&gt; - a
self-educational project to implement a CPU simulator and a toolchain for it,
consisting of an assembler and a linker. Since then, I received some questions
by email that made me realize I could do a better job explaining what the
project …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A few years ago I &lt;a class="reference external" href="https://eli.thegreenplace.net/2010/05/05/introducing-luz"&gt;wrote about Luz&lt;/a&gt; - a
self-educational project to implement a CPU simulator and a toolchain for it,
consisting of an assembler and a linker. Since then, I received some questions
by email that made me realize I could do a better job explaining what the
project is and what one can learn from it.&lt;/p&gt;
&lt;p&gt;So I went back to the &lt;a class="reference external" href="https://github.com/eliben/luz-cpu"&gt;Luz repository&lt;/a&gt; and
fixed it up to be more modern, in-line with current documentation standards on
GitHub. The landing &lt;cite&gt;README&lt;/cite&gt; page should now provide a good overview, but I also
wanted to write up some less formal documentation I could point to - a place to
show-off some of the more interesting features in Luz; a blog post seemed like
the perfect medium for this.&lt;/p&gt;
&lt;p&gt;As before, it makes sense to start with the Luz toplevel diagram:&lt;/p&gt;
&lt;img alt="Luz toplevel diagram" class="align-center" src="https://eli.thegreenplace.net/images/2010/05/luz_proj_toplevel.png" /&gt;
&lt;p&gt;Luz is a collection of related libraries and programs written in Python,
implementing all the stages shown in the diagram above.&lt;/p&gt;
&lt;div class="section" id="the-cpu-simulator"&gt;
&lt;h2&gt;The CPU simulator&lt;/h2&gt;
&lt;p&gt;The Luz CPU is inspired by MIPS (for the instruction set), by Altera Nios II
(for the way &amp;quot;peripherals&amp;quot; are attached to the CPU), and by MPC 555 (for the
memory controller) and is aimed at embedded uses, like Nios II. The &lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/doc/luz_user_manual.rst"&gt;Luz user
manual&lt;/a&gt;
lists the complete instruction set explaining what each instructions means.&lt;/p&gt;
&lt;p&gt;The simulator itself is functional only - it performs the instructions one after
the other, without trying to simulate how long their execution takes. It's not
very remarkable and is designed to be simple and readable. The most interesting
feature it has, IMHO, is how it maps &amp;quot;peripherals&amp;quot; and even CPU control
registers into memory. Rather than providing special instructions or traps for
OS system calls, Luz facilitates &amp;quot;bare-metal&amp;quot; programming (by which I mean,
without an OS) by mapping &amp;quot;peripherals&amp;quot; into memory, allowing the programmer to
access them by reading and writing special memory locations.&lt;/p&gt;
&lt;p&gt;My inspiration here was soft-core embeddable CPUs like Nios II, which let you
configure what peripherals to connect and how to map them. The CPU can be
configured before it's loaded onto real HW, for example to attach as many SPI
interfaces as needed. For Luz, to create a new peripheral and attach it to the
simulator one implements the &lt;tt class="docutils literal"&gt;Peripheral&lt;/tt&gt; interface:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Peripheral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; An abstract memory-mapped perhipheral interface.&lt;/span&gt;
&lt;span class="sd"&gt;        Memory-mapped peripherals are accessed through memory&lt;/span&gt;
&lt;span class="sd"&gt;        reads and writes.&lt;/span&gt;

&lt;span class="sd"&gt;        The address given to reads and writes is relative to the&lt;/span&gt;
&lt;span class="sd"&gt;        peripheral&amp;#39;s memory map.&lt;/span&gt;
&lt;span class="sd"&gt;        Width is 1, 2, 4 for byte, halfword and word accesses.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_mem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_mem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Luz implements some built-in features as peripherals as well; for example, the
&lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/luz_asm_sim/lib/simlib/peripheral/coreregisters.py"&gt;core registers&lt;/a&gt;
(interrupt control, exception control, etc). The idea here is that embedded CPUs
can have multiple custom &amp;quot;registers&amp;quot; to control various features, and creating
dedicated names for them bloats instruction encoding (you need 5 bits to encode
one of 32 registers, etc.); it's better to just map them to memory.&lt;/p&gt;
&lt;p&gt;Another example is the &lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/luz_asm_sim/lib/simlib/peripheral/debugqueue.py"&gt;debug queue&lt;/a&gt;
- a peripheral useful for testing and debugging. It's a single word mapped to
address &lt;tt class="docutils literal"&gt;0xF0000&lt;/tt&gt; in the simulator. When the peripheral gets a write, it
stores it in a special queue and optionally emits the value to stdout. The
queue can later be examined. Here is a simple Luz assembly program that makes
use of it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# Counts from 0 to 9 [inclusive], pushing these numbers into the debug queue

    .segment code
    .global asm_main

    .define ADDR_DEBUG_QUEUE, 0xF0000

asm_main:
    li $k0, ADDR_DEBUG_QUEUE

    li $r9, 10                          # r9 is the loop limit
    li $r5, 0                           # r5 is the loop counter

loop:
    sw $r5, 0($k0)                      # store loop counter to debug queue
    addi $r5, $r5, 1                    # increment loop counter
    bltu $r5, $r9, loop                 # loop back if not reached limit

    halt
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using the interactive runner to run this program we get:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ python run_test_interactive.py loop_simple_debugqueue
DebugQueue: 0x0
DebugQueue: 0x1
DebugQueue: 0x2
DebugQueue: 0x3
DebugQueue: 0x4
DebugQueue: 0x5
DebugQueue: 0x6
DebugQueue: 0x7
DebugQueue: 0x8
DebugQueue: 0x9
Finished successfully...
Debug queue contents:
[&amp;#39;0x0&amp;#39;, &amp;#39;0x1&amp;#39;, &amp;#39;0x2&amp;#39;, &amp;#39;0x3&amp;#39;, &amp;#39;0x4&amp;#39;, &amp;#39;0x5&amp;#39;, &amp;#39;0x6&amp;#39;, &amp;#39;0x7&amp;#39;, &amp;#39;0x8&amp;#39;, &amp;#39;0x9&amp;#39;]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="assembler"&gt;
&lt;h2&gt;Assembler&lt;/h2&gt;
&lt;p&gt;There's a small snippet of Luz assembly shown above. It's your run-of-the-mill
RISC assembly, with the familiar set of instructions, fairly simple addressing
modes and almost every instruction requiring registers (note how we can't store
into the debug queue directly, for example, without dereferencing a register
that holds its address).&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/doc/luz_user_manual.rst"&gt;Luz user manual&lt;/a&gt;
contains a complete reference for the instructions, including their encodings.
Every instruction is a 32-bit word, with the 6 high bits for the opcode (meaning
up to 64 distinct instructions are supported).&lt;/p&gt;
&lt;p&gt;The code snippet also shows off some special features of the full Luz toolchain,
like the special label &lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt;. I'll discuss these later on in the section
about linking.&lt;/p&gt;
&lt;p&gt;Assembly languages are usually fairly simple to parse, and Luz is no exception.
When I started working on Luz, I decided to use the &lt;a class="reference external" href="http://www.dabeaz.com/ply/"&gt;PLY&lt;/a&gt; library for the lexer and parser mainly because I
wanted to play with it. These days I'd probably just hand-roll a parser.&lt;/p&gt;
&lt;p&gt;Luz takes another cool idea from MIPS - &lt;a class="reference external" href="https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/altReg.html"&gt;register aliases&lt;/a&gt;. While
the assembler doesn't enforce any specific ABI on the coder, some conventions are
very important when writing large assembly programs, and especially when
interfacing with routines written by other programmers. To facilitate this, Luz
designates register aliases for callee-saved registers and temporary registers.&lt;/p&gt;
&lt;p&gt;For example, the general-purpose register number 19 can be referred to in Luz
assembly as &lt;tt class="docutils literal"&gt;$r19&lt;/tt&gt; but also as &lt;tt class="docutils literal"&gt;$s1&lt;/tt&gt; - the callee-saved register 1. When
writing standalone Luz programs, one is free to ignore these conventions. To
get a taste of how ABI-conformant Luz assembly would look, take a look at
&lt;a class="reference external" href="https://github.com/eliben/luz-cpu/tree/main/luz_asm_sim/tests_full/procedure_call_stack_convention"&gt;this example&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To be honest, ABI was on my mind because I was initially envisioning a full
programming environment for Luz, including a C compiler. When you have a
compiler, you must have some set of conventions for generated code like
procedure parameter passing, saved registers and so on; in other words, the
platform ABI.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="linker"&gt;
&lt;h2&gt;Linker&lt;/h2&gt;
&lt;p&gt;In my view, one of the distinguishing features of Luz from other assembler
projects out there is the linker. Luz features a full linker that supports
creating single &amp;quot;binaries&amp;quot; from multiple assembly files, handling all the dirty
work necessary to make that happen. Each assembly file is first &amp;quot;assembled&amp;quot; into
a position-independent object file; these are glued together by the linker which
applies the necessary relocations to resolve symbols across object files. The
&lt;a class="reference external" href="https://github.com/eliben/luz-cpu/tree/main/luz_asm_sim/tests_full/prime_sieve"&gt;prime sieve example&lt;/a&gt;
shows this in action - the program is divided into three &lt;tt class="docutils literal"&gt;.lasm&lt;/tt&gt; files: two
for subroutines and one for &amp;quot;main&amp;quot;.&lt;/p&gt;
&lt;p&gt;As we've seen above, the main subroutine in Luz is called &lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt;. This is
a special name for the linker (not unlike the &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; symbol for &lt;a class="reference external" href="https://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux"&gt;modern
Linux assemblers&lt;/a&gt;).
The linker collects a set of object files produced by assembly, and makes sure
to invoke &lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt; from the special location &lt;tt class="docutils literal"&gt;0x100000&lt;/tt&gt;. This is where
the simulator starts execution.&lt;/p&gt;
&lt;p&gt;Luz also has the concept of &lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/luz_asm_sim/lib/asmlib/objectfile.py"&gt;object files&lt;/a&gt;.
They are not unlike ELF images in nature: there's a segment table, an export
table and a relocation table for each object, serving the expected roles. It is
the job of the linker to make sense in this list of objects and correctly
connect all call sites to final subroutine addresses.&lt;/p&gt;
&lt;p&gt;Luz's &lt;a class="reference external" href="https://github.com/eliben/luz-cpu/blob/main/luz_asm_sim/luz_asm.py"&gt;standalone assembler&lt;/a&gt; can
write an assembled image into a file in &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Intel_HEX"&gt;Intel HEX format&lt;/a&gt;, a popular format used in embedded
systems to encode binary images or data in ASCII.&lt;/p&gt;
&lt;p&gt;The linker was quite a bit of effort to develop. Since all real Luz programs are
small I didn't really need to break them up into multiple assembly files; but
I really wanted to learn how to write a real linker :) Moreover, as already
mentioned my original plans for Luz included a C compiler, and that would make a
linker very helpful, since I'd need to link some &amp;quot;system&amp;quot; code into the user's
program. Even today, Luz has some &amp;quot;startup code&amp;quot; it links into every image:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# The special segments added by the linker.
# __startup: 3 words
# __heap: 1 word
#
LINKER_STARTUP_CODE = string.Template(r&amp;#39;&amp;#39;&amp;#39;
        .segment __startup

    LI      $$sp, ${SP_POINTER}
    CALL    asm_main

        .segment __heap
        .global __heap
    __heap:
        .word 0
&amp;#39;&amp;#39;&amp;#39;)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code sets up the stack pointer to the initial address allocated for the
stack, and calls the user's &lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="debugger-and-disassembler"&gt;
&lt;h2&gt;Debugger and disassembler&lt;/h2&gt;
&lt;p&gt;Luz comes with a simple program runner that will execute a Luz program
(consisting of multiple assembly files); it also has an interactive mode - a
debugger. Here's a sample session with the simple loop example shown above:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ python run_test_interactive.py -i loop_simple_debugqueue

LUZ simulator started at 0x00100000

[0x00100000] [lui $sp, 0x13] &amp;gt;&amp;gt; set alias 0
[0x00100000] [lui $r29, 0x13] &amp;gt;&amp;gt; s
[0x00100004] [ori $r29, $r29, 0xFFFC] &amp;gt;&amp;gt; s
[0x00100008] [call 0x40003 [0x10000C]] &amp;gt;&amp;gt; s
[0x0010000C] [lui $r26, 0xF] &amp;gt;&amp;gt; s
[0x00100010] [ori $r26, $r26, 0x0] &amp;gt;&amp;gt; s
[0x00100014] [lui $r9, 0x0] &amp;gt;&amp;gt; s
[0x00100018] [ori $r9, $r9, 0xA] &amp;gt;&amp;gt; s
[0x0010001C] [lui $r5, 0x0] &amp;gt;&amp;gt; s
[0x00100020] [ori $r5, $r5, 0x0] &amp;gt;&amp;gt; s
[0x00100024] [sw $r5, 0($r26)] &amp;gt;&amp;gt; s
[0x00100028] [addi $r5, $r5, 0x1] &amp;gt;&amp;gt; s
[0x0010002C] [bltu $r5, $r9, -2] &amp;gt;&amp;gt; s
[0x00100024] [sw $r5, 0($r26)] &amp;gt;&amp;gt; s
[0x00100028] [addi $r5, $r5, 0x1] &amp;gt;&amp;gt; s
[0x0010002C] [bltu $r5, $r9, -2] &amp;gt;&amp;gt; s
[0x00100024] [sw $r5, 0($r26)] &amp;gt;&amp;gt; s
[0x00100028] [addi $r5, $r5, 0x1] &amp;gt;&amp;gt; r
$r0   = 0x00000000   $r1   = 0x00000000   $r2   = 0x00000000   $r3   = 0x00000000
$r4   = 0x00000000   $r5   = 0x00000002   $r6   = 0x00000000   $r7   = 0x00000000
$r8   = 0x00000000   $r9   = 0x0000000A   $r10  = 0x00000000   $r11  = 0x00000000
$r12  = 0x00000000   $r13  = 0x00000000   $r14  = 0x00000000   $r15  = 0x00000000
$r16  = 0x00000000   $r17  = 0x00000000   $r18  = 0x00000000   $r19  = 0x00000000
$r20  = 0x00000000   $r21  = 0x00000000   $r22  = 0x00000000   $r23  = 0x00000000
$r24  = 0x00000000   $r25  = 0x00000000   $r26  = 0x000F0000   $r27  = 0x00000000
$r28  = 0x00000000   $r29  = 0x0013FFFC   $r30  = 0x00000000   $r31  = 0x0010000C

[0x00100028] [addi $r5, $r5, 0x1] &amp;gt;&amp;gt; s 100
[0x00100030] [halt] &amp;gt;&amp;gt; q
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are many interesting things here demonstrating how Luz works:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Note the start up at &lt;tt class="docutils literal"&gt;0x1000000&lt;/tt&gt; - this is where Luz places the start-up
segment - three instructions that set up the stack pointer and then &lt;tt class="docutils literal"&gt;call&lt;/tt&gt;
the user's code (&lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt;). The user's &lt;tt class="docutils literal"&gt;asm_main&lt;/tt&gt; starts running at
the fourth instruction executed by the simulator.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;li&lt;/tt&gt; is a pseudo-instruction, broken into two real instructions: &lt;tt class="docutils literal"&gt;lui&lt;/tt&gt;
for the upper half of the register, followed by &lt;tt class="docutils literal"&gt;ori&lt;/tt&gt; for the lower half of
the register. The reason for this is &lt;tt class="docutils literal"&gt;li&lt;/tt&gt; having a 32-bit immediate, which
can't fit in a Luz instruction. Therefore, it's broken into two parts which
only need 16-bit immediates. This trick is common in RISC ISAs.&lt;/li&gt;
&lt;li&gt;Jump labels are resolved to be relative by the assembler: the jump to &lt;tt class="docutils literal"&gt;loop&lt;/tt&gt;
is replaced by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-2&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Disassembly! The debugger shows the instruction decoded from every word where
execution stops. Note how this exposes pseudo-instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="the-in-progress-rtl-implementation"&gt;
&lt;h2&gt;The in-progress RTL implementation&lt;/h2&gt;
&lt;p&gt;Luz was a hobby project, but an ambitious one :-) Even before I wrote the first
line of the assembler or simulator, I started working on an actual CPU
implementation in synthesizable VHDL, meaning to get a complete RTL image to run
on FPGAs. Unfortunately, I didn't finish this part of the project
and what you find in Luz's &lt;tt class="docutils literal"&gt;experimental/luz_uc&lt;/tt&gt; directory is only 75%
complete. The ALU is there, the registers, the hookups to peripherals, even
parts of the control path - dealing with instruction fetching, decoding, etc. My
original plan was to implement a pipelined CPU (a RISC ISA makes this relatively
simple), which perhaps was a bit too much. I should have started simpler.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Luz was an extremely educational project for me. When I started working on it,
I mostly had embedded programming experience and was just starting to get
interested in systems programming. Luz flung me into the world of assemblers,
linkers, binary images, calling conventions, and so on. Besides, Python was
a new language for me at the time - Luz started just months after
&lt;a class="reference external" href="https://eli.thegreenplace.net/2008/05/14/python"&gt;I first got into Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Its ~8000 lines of Python code are thus likely not my best Python code, but they
should be readable and well commented. I did modernize it a bit over the years,
for example to make it run on both Python 2 and 3.&lt;/p&gt;
&lt;p&gt;I still hope to get back to the RTL implementation project one day. It's really
very close to being able to run realistic assembly programs on &lt;em&gt;real hardware&lt;/em&gt;
(FPGAs). My dream back then was to fully close the loop by adding a Luz code
generation backend to &lt;a class="reference external" href="https://github.com/eliben/pycparser"&gt;pycparser&lt;/a&gt;. Maybe
I'll still fulfill it one day :-)&lt;/p&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="Assembly"></category><category term="EE &amp; Embedded"></category><category term="Linkers and Loaders"></category><category term="Python"></category></entry><entry><title>Library order in static linking</title><link href="https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking" rel="alternate"></link><published>2013-07-09T05:56:27-07:00</published><updated>2023-06-30T23:16:27-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2013-07-09:/2013/07/09/library-order-in-static-linking</id><summary type="html">
        &lt;p&gt;I'll start with a slightly sneaky but educational example. Suppose we have this code:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;volatile&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt; src[] = {&lt;span style="color: #007f7f"&gt;1&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;2&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;3&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;4&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;5&lt;/span&gt;};
&lt;span style="color: #00007f; font-weight: bold"&gt;volatile&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt; dst[&lt;span style="color: #007f7f"&gt;50&lt;/span&gt;] = {&lt;span style="color: #007f7f"&gt;0&lt;/span&gt;};

&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* memcpy(&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* dst, &lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* src, &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; len);

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;main&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; argc, &lt;span style="color: #00007f; font-weight: bold"&gt;const&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;* argv[])
{
    memcpy(dst, src, &lt;span style="color: #00007f; font-weight: bold"&gt;sizeof&lt;/span&gt;(src));
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; dst[&lt;span style="color: #007f7f"&gt;4 …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">
        &lt;p&gt;I'll start with a slightly sneaky but educational example. Suppose we have this code:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;volatile&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt; src[] = {&lt;span style="color: #007f7f"&gt;1&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;2&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;3&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;4&lt;/span&gt;, &lt;span style="color: #007f7f"&gt;5&lt;/span&gt;};
&lt;span style="color: #00007f; font-weight: bold"&gt;volatile&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt; dst[&lt;span style="color: #007f7f"&gt;50&lt;/span&gt;] = {&lt;span style="color: #007f7f"&gt;0&lt;/span&gt;};

&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* memcpy(&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* dst, &lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* src, &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; len);

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;main&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; argc, &lt;span style="color: #00007f; font-weight: bold"&gt;const&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;* argv[])
{
    memcpy(dst, src, &lt;span style="color: #00007f; font-weight: bold"&gt;sizeof&lt;/span&gt;(src));
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; dst[&lt;span style="color: #007f7f"&gt;4&lt;/span&gt;];
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It runs just fine and the return value is 5. Now, suppose this is part of a larger project that consists of many object files and libraries, and somewhere within the project there's a library that contains this code:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; &lt;span style="color: #00007f"&gt;memcpy&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;* aa, &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;* bb, &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;* cc) {
    &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; i;
    &lt;span style="color: #00007f; font-weight: bold"&gt;for&lt;/span&gt; (i = &lt;span style="color: #007f7f"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #007f7f"&gt;100&lt;/span&gt;; ++i) {
        cc[i] = aa[i] + bb[i];
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the previous snippet gets linked with this library, what happens? Would you expect it to still return 5? Return something else? Crash? The answer is: it depends - the result can be either correct or a segmentation fault. It depends on the order in which the objects and libraries in the project were fed to the linker.&lt;/p&gt;
&lt;p&gt;If you fully understand why this depends on linking order, as well as how to avoid the problem (and more serious problems, like circular dependencies) then congratulate yourself and move on - this article is probably not for you. Otherwise, read on.&lt;/p&gt;
&lt;div class="section" id="the-basics"&gt;
&lt;h3&gt;The basics&lt;/h3&gt;
&lt;p&gt;Let's start by defining the scope of this article: first, my examples are demonstrating the use of the gcc and binutils toolchain on Linux. Compatible toolchains (like clang instead of gcc) apply too. Second, the discussion here resolves around &lt;em&gt;static&lt;/em&gt; linking that's done at compile/link time.&lt;/p&gt;
&lt;p&gt;To understand why linking order matters, it's first instructional to understand how the linker works with respect to linking libraries and objects together. Just as a quick reminder - an object file both &lt;em&gt;provides&lt;/em&gt; (exports) external symbols &lt;em&gt;to&lt;/em&gt; other objects and libraries, and &lt;em&gt;expects&lt;/em&gt; (imports) symbols &lt;em&gt;from&lt;/em&gt; other objects and libraries. For example, in this C code:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; imported(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt;);

&lt;span style="color: #00007f; font-weight: bold"&gt;static&lt;/span&gt; &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;internal&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; x) {
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; x * &lt;span style="color: #007f7f"&gt;2&lt;/span&gt;;
}

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;exported&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; x) {
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; imported(x) * internal(x);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The names of the functions speak for themselves. Let's compile it and look at the symbol table:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc -c x.c
$ nm x.o
000000000000000e T exported
                 U imported
0000000000000000 t internal
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This means: &lt;tt class="docutils literal"&gt;exported&lt;/tt&gt; is an external symbol - defined in the object file and visible from the outside. &lt;tt class="docutils literal"&gt;imported&lt;/tt&gt; is an undefined symbol; in other words, the linker is expected to find it elsewhere. When we talk about linking later, the term &lt;em&gt;undefined&lt;/em&gt; can become confusing - so it helps to remember that this is where it comes from originally. &lt;tt class="docutils literal"&gt;internal&lt;/tt&gt; is defined within the object but invisible from the outside.&lt;/p&gt;
&lt;p&gt;Now, a &lt;em&gt;library&lt;/em&gt; is simply a collection of object files. Just a bunch of object files glued together. Creating a library is a very trivial operation that doesn't do anything special besides placing many object files into the same file. This in itself is important, because a horde of object files is not convenient to deal with. For example, on my system &lt;tt class="docutils literal"&gt;libc.a&lt;/tt&gt; (the static version of the C library) consists of almost 1500 object files. It's way nicer to just carry &lt;tt class="docutils literal"&gt;libc.a&lt;/tt&gt; around.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-linking-process"&gt;
&lt;h3&gt;The linking process&lt;/h3&gt;
&lt;p&gt;This section defines the linking process in a somewhat dry, algorithmic manner. This process is the key to understanding why linking order matters.&lt;/p&gt;
&lt;p&gt;Consider a linker invocation:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc main.o -L/some/lib/dir -lfoo -lbar -lbaz
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The linker is almost always invoked through the compiler driver &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; when compiling C or C++ code. This is because the driver knows how to provide the correct command-line arguments to the linker itself (&lt;tt class="docutils literal"&gt;ld&lt;/tt&gt;) with all the support libraries, etc. We'll see more of this later.&lt;/p&gt;
&lt;p&gt;Anyhow, as you can see the object files and libraries are provided in a certain order on the command-line, from left to right. This is the linking order. Here's what the linker does:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The linker maintains a &lt;em&gt;symbol table&lt;/em&gt;. This symbol table does a bunch of things, but among them is keeping two lists:&lt;ul&gt;
&lt;li&gt;A list of symbols exported by all the objects and libraries encountered so far.&lt;/li&gt;
&lt;li&gt;A list of undefined symbols that the encountered objects and libraries requested to import and were not found yet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When the linker encounters a new object file, it looks at:&lt;ul&gt;
&lt;li&gt;The symbols it exports: these are added to the list of exported symbols mentioned above. If any symbol is in the undefined list, it's removed from there because it has now been found. If any symbol has already been in the exported list, we get a &amp;quot;multiple definition&amp;quot; error: two different objects export the same symbol and the linker is confused.&lt;/li&gt;
&lt;li&gt;The symbols it imports: these are added to the list of undefined symbols, unless they can be found in the list of exported symbols.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When the linker encounters a new library, things are a bit more interesting. The linker goes over all the objects in the library. For each one, it first looks at the symbols it exports.&lt;ul&gt;
&lt;li&gt;If any of the symbols it exports are on the undefined list, the object is added to the link and the next step is executed. Otherwise, the next step is skipped.&lt;/li&gt;
&lt;li&gt;If the object has been added to the link, it's treated as described above - its undefined and exported symbols get added to the symbol table.&lt;/li&gt;
&lt;li&gt;Finally, if &lt;em&gt;any&lt;/em&gt; of the objects in the library has been included in the link, the library is rescanned again - it's possible that symbols imported by the included object can be found in other objects within the same library.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the linker finishes, it looks at the symbol table. If any symbols remain in the undefined list, the linker will throw an &amp;quot;undefined reference&amp;quot; error. For example, when you create an executable and forget to include the file with the &lt;tt class="docutils literal"&gt;main&lt;/tt&gt; function, you'll get something like:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;/usr/lib/x86_64-linux-gnu/crt1.o: In function &amp;#39;_start&amp;#39;:
(.text+0x20): undefined reference to &amp;#39;main&amp;#39;
collect2: ld returned 1 exit status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that after the linker has looked at a library, it won't look at it again. Even if it exports symbols that may be needed by some later library. The only time where a linker goes back to rescan objects it has already seen happens within a single library - as mentioned above, once an object from some library is taken into the link, all other objects in the same library will be rescanned. Flags passed to the linker can tweak this process - again, we'll see some examples later.&lt;/p&gt;
&lt;p&gt;Also note that when a library is examined, an object file within it can be left out of the link if it does not provide symbols that the symbol table needs. This is a very important feature of static linking. The C library I mentioned before makes a heavy use of this feature, by mostly splitting itself to an-object-per-function. So, for example if the only C standard library function your code uses is &lt;tt class="docutils literal"&gt;strlen&lt;/tt&gt;, only &lt;tt class="docutils literal"&gt;strlen.o&lt;/tt&gt; will be taken into the link from &lt;tt class="docutils literal"&gt;libc.a&lt;/tt&gt; - and your executable will be very small.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="simple-examples"&gt;
&lt;h3&gt;Simple examples&lt;/h3&gt;
&lt;p&gt;The previous section can be hard to digest, so here are some simple examples that show the process in action.&lt;/p&gt;
&lt;p&gt;Let's start with the most basic case, of linking two objects together:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ cat simplefunc.c
int func(int i) {
    return i + 21;
}

$ cat simplemain.c
int func(int);

int main(int argc, const char* argv[])
{
    return func(argc);
}

$ gcc -c simplefunc.c
$ gcc -c simplemain.c
$ gcc simplefunc.o simplemain.o
$ ./a.out ; echo $?
22
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Everything links and works as expected. Note that since these are object files, the linking order does not matter. Object files are always taken into the link. We can pass them to the linker in reversed order and it still works:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc simplemain.o simplefunc.o
$ ./a.out ; echo $?
22
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let's do something different. Let's put &lt;tt class="docutils literal"&gt;simplefunc.c&lt;/tt&gt; into a library:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ ar r libsimplefunc.a simplefunc.o
$ ranlib libsimplefunc.a
$ gcc  simplemain.o -L. -lsimplefunc
$ ./a.out ; echo $?
22
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Works like a charm. But note what happens if the linking order is reversed now:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. -lsimplefunc  simplemain.o
simplemain.o: In function &amp;#39;main&amp;#39;:
simplemain.c:(.text+0x15): undefined reference to &amp;#39;func&amp;#39;
collect2: ld returned 1 exit status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Understanding the linking algorithm outlined above makes this case simple to explain. When the linker encounters &lt;tt class="docutils literal"&gt;libsimplefunc.a&lt;/tt&gt;, it still hasn't seen &lt;tt class="docutils literal"&gt;simplemain.o&lt;/tt&gt;, which means that &lt;tt class="docutils literal"&gt;func&lt;/tt&gt; is not yet on the undefined list. When the linker looks into the library it sees &lt;tt class="docutils literal"&gt;simplefunc.o&lt;/tt&gt; that exports &lt;tt class="docutils literal"&gt;func&lt;/tt&gt;. But since it doesn't need &lt;tt class="docutils literal"&gt;func&lt;/tt&gt;, this object file is not included in the link. When the linker does reach &lt;tt class="docutils literal"&gt;simplemain.o&lt;/tt&gt; and sees that &lt;tt class="docutils literal"&gt;func&lt;/tt&gt; is, indeed required, it's added to the undefined list (because it's not on the exported list). The linker then reaches the end of the link and &lt;tt class="docutils literal"&gt;func&lt;/tt&gt; is still undefined.&lt;/p&gt;
&lt;p&gt;Note how this doesn't happen in the previous linking order - since &lt;tt class="docutils literal"&gt;simplemain.o&lt;/tt&gt; comes first, &lt;tt class="docutils literal"&gt;func&lt;/tt&gt; is on the undefined list &lt;em&gt;before&lt;/em&gt; the linker sees the library, so the object file exporting it does get included.&lt;/p&gt;
&lt;p&gt;This brings us to the most important corollary of the linking process outlined above:&lt;/p&gt;
&lt;blockquote&gt;
If object or library AA needs a symbol from library BB, then AA should come &lt;em&gt;before&lt;/em&gt; library BB in the command-line invocation of the linker.&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="circular-dependency"&gt;
&lt;h3&gt;Circular dependency&lt;/h3&gt;
&lt;p&gt;The corollary above is an important summary of the linking process - it's certainly much more practical to keep in mind because it's so short. But it makes one wonder - what happens if AA needs a symbol from BB, but BB also needs a symbol from AA? While officially this isn't a good programming practice, in reality it happens quite a lot. But AA can't come both before and after BB on the command-line, right? That's just silly. Wait, is it, really?&lt;/p&gt;
&lt;p&gt;Let's see an example and start simple. Imagine that instead of &lt;tt class="docutils literal"&gt;simplefunc.c&lt;/tt&gt;, the &lt;tt class="docutils literal"&gt;func&lt;/tt&gt; symbol is provided thus:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ cat func_dep.c
int bar(int);

int func(int i) {
    return bar(i + 1);
}
$ cat bar_dep.c
int func(int);

int bar(int i) {
    if (i &amp;gt; 3)
        return i;
    else
        return func(i);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These two files depend on each other and get placed into different libraries. If we link them in one order, we fail:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  simplemain.o -L.  -lbar_dep -lfunc_dep
./libfunc_dep.a(func_dep.o): In function &amp;#39;func&amp;#39;:
func_dep.c:(.text+0x14): undefined reference to &amp;#39;bar&amp;#39;
collect2: ld returned 1 exit status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, the other order does work:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  simplemain.o -L. -lfunc_dep -lbar_dep
$ ./a.out ; echo $?
4
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quiz: can you figure out why? Hint: just go over the linking process algorithm with this command-line. What undefined symbols does the symbol table contain when the linker first sees &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-lfunc_dep&lt;/span&gt;&lt;/tt&gt;?&lt;/p&gt;
&lt;p&gt;But this is a very simple case. Let's look at a trickier one. We'll add a dependency to &lt;tt class="docutils literal"&gt;bar&lt;/tt&gt; on another function from &lt;tt class="docutils literal"&gt;libfunc_dep.a&lt;/tt&gt;, but one that lives in a different object:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ cat bar_dep.c
int func(int);
int frodo(int);

int bar(int i) {
    if (i &amp;gt; 3)
        return frodo(i);
    else
        return func(i);
}

$ cat frodo_dep.c
int frodo(int i) {
    return 6 * i;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We'll recompile all these files into separate objects, and the &lt;tt class="docutils literal"&gt;libfunc_dep.a&lt;/tt&gt; library will now be:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ ar r libfunc_dep.a func_dep.o frodo_dep.o
$ ranlib libfunc_dep.a
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here's a drawing of the libraries, with arrows showing the dependencies:&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/2013/07/circdep2.png" /&gt;
&lt;p&gt;Now linking fails no matter what order we list the libraries in:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. simplemain.o -lfunc_dep -lbar_dep
./libbar_dep.a(bar_dep.o): In function &amp;#39;bar&amp;#39;:
bar_dep.c:(.text+0x17): undefined reference to &amp;#39;frodo&amp;#39;
collect2: ld returned 1 exit status
$ gcc  -L. simplemain.o -lbar_dep -lfunc_dep
./libfunc_dep.a(func_dep.o): In function &amp;#39;func&amp;#39;:
func_dep.c:(.text+0x14): undefined reference to &amp;#39;bar&amp;#39;
collect2: ld returned 1 exit status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To solve this, consider that it's perfectly valid to list a library more than once on the link line; so in fact, we can provide &lt;tt class="docutils literal"&gt;libfunc_dep.a&lt;/tt&gt; both before and after &lt;tt class="docutils literal"&gt;libbar_dep.a&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. simplemain.o -lfunc_dep -lbar_dep -lfunc_dep
$ ./a.out ; echo $?
24
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another quiz: will the same trick work providing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-lbar_dep&lt;/span&gt;&lt;/tt&gt; twice? Why not?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-linker-flags-to-control-the-process"&gt;
&lt;h3&gt;Using linker flags to control the process&lt;/h3&gt;
&lt;p&gt;As I've mentioned above, the linker has a number of interesting flags that can be used to control the process in a fine-grained manner. For example, circular dependency problems can be easily resolved with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--start-group&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--end-group&lt;/span&gt;&lt;/tt&gt;. Here's an instructive portion from &lt;tt class="docutils literal"&gt;man ld&lt;/tt&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;--start-group archives --end-group&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The specified archives are searched repeatedly until no new undefined references are created.  Normally, an archive is searched only once in the order that it is specified on the command line.  If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference.  By grouping the archives, they all be searched repeatedly until all possible references are resolved.&lt;/p&gt;
&lt;p&gt;Using this option has a significant performance cost.  It is best to use it only when there are unavoidable circular references between two or more archives.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here's how this helps in our case:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc simplemain.o -L. -Wl,--start-group -lbar_dep -lfunc_dep -Wl,--end-group
$ ./a.out ; echo $?
24
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It's interesting to note the &amp;quot;significant performance cost&amp;quot; warning in the excerpt above. This explains &lt;em&gt;why&lt;/em&gt; the linking process is the way it is. Presumably, linkers could just re-scan the whole library list until no new symbols got resolved. This would eliminate most circular-dependency and linking order problems in the world, but it would also be slow. Linking is already a critical part of the compilation time of large systems, since it looks at the whole program and requires quite a bit of memory. It's better to make it as fast as possible for well-behaved programs (that got their linking order right), and provide special options like groups for the difficult circular dependency cases.&lt;/p&gt;
&lt;p&gt;There's at least one another linker flag that can help us resolve the circular dependency here. We can use the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--undefined&lt;/span&gt;&lt;/tt&gt; flag to tell the linker - &amp;quot;buddy, here's a symbol I want you to add to the undefined list&amp;quot;. In our case this makes the link error go away even though the libraries are specified only once:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc simplemain.o -L. -Wl,--undefined=bar -lbar_dep -lfunc_dep
$ ./a.out ; echo $?
24
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Figuring out why this works is left as an exercise to the reader.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="back-to-the-original-example"&gt;
&lt;h3&gt;Back to the original example&lt;/h3&gt;
&lt;p&gt;Let's go back to the example this article started with. &lt;tt class="docutils literal"&gt;main&lt;/tt&gt; assumes it gets the correct &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt; from the C library, but the &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt; it gets linked with does something else. Assuming the &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt; here was packed into the &lt;tt class="docutils literal"&gt;libstray_memcpy.a&lt;/tt&gt; library:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. main_using_memcpy.o -lstray_memcpy
$ ./a.out
Segmentation fault (core dumped)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is the expected behavior. Since &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-lstray_memcpy&lt;/span&gt;&lt;/tt&gt; was provided after &lt;tt class="docutils literal"&gt;main_using_memcpy.o&lt;/tt&gt; on the command-line, it gets linked in. But what happens if the order is reversed:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. -lstray_memcpy main_using_memcpy.o
$ ./a.out ; echo $?
5
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The program links and works correctly. The reason for this is simple: even without us explicitly asking for it, gcc asks the linker to link the C library as well. The full linker invocation command of gcc is pretty complex, and can be examined by passing the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-###&lt;/span&gt;&lt;/tt&gt; flag to gcc. But in our case this amounts to:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc  -L. -lstray_memcpy main_using_memcpy.o -lc
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the linker sees &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-lstray_memcpy&lt;/span&gt;&lt;/tt&gt;, the symbol table does not yet have an undefined entry for &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt;, so the object file with the wrong function does not get linked. The linker adds this undefined entry only after it sees &lt;tt class="docutils literal"&gt;main_using_memcpy.o&lt;/tt&gt;. Then, when it reaches &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-lc&lt;/span&gt;&lt;/tt&gt;, the object file holding &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt; from the C library &lt;em&gt;does&lt;/em&gt; get linked in because by now &lt;tt class="docutils literal"&gt;memcpy&lt;/tt&gt; is on the undefined list.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The algorithm used by the linker to resolve symbols between objects and libraries is pretty simple. As long as you keep it in mind, linker errors and related problems should be easy to understand. If you still run into problematic situations you're not sure how to resolve, this article mentioned two tools that can be very useful in debugging such problems: one is &lt;tt class="docutils literal"&gt;nm&lt;/tt&gt;, which shows the symbol table of an object or a whole library. The other is the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-###&lt;/span&gt;&lt;/tt&gt; flag that gcc accepts and as a result shows the full commands it passes to the underlying tools.&lt;/p&gt;
&lt;/div&gt;

    </content><category term="misc"></category><category term="Linkers and loaders"></category></entry><entry><title>How statically linked programs run on Linux</title><link href="https://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux" rel="alternate"></link><published>2012-08-13T04:44:58-07:00</published><updated>2023-06-30T23:16:27-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2012-08-13:/2012/08/13/how-statically-linked-programs-run-on-linux</id><summary type="html">
        &lt;p&gt;In this article I want to explore what happens when a statically linked program gets executed on Linux. By &lt;em&gt;statically linked&lt;/em&gt; I mean a program that does not require any shared objects to run, even the ubiquitous &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;. In reality, most programs one encounters on Linux aren't statically linked, and …&lt;/p&gt;</summary><content type="html">
        &lt;p&gt;In this article I want to explore what happens when a statically linked program gets executed on Linux. By &lt;em&gt;statically linked&lt;/em&gt; I mean a program that does not require any shared objects to run, even the ubiquitous &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;. In reality, most programs one encounters on Linux aren't statically linked, and do require one or more shared objects to run. However, the running sequence of such programs is more involved, which is why I want to present statically linked programs first. It will serve as a good basis for understanding, allowing me to explore most of the mechanisms involved with less details getting in the way. In a future article I will cover the dynamic linking process in detail.&lt;/p&gt;
&lt;div class="section" id="the-linux-kernel"&gt;
&lt;h3&gt;The Linux kernel&lt;/h3&gt;
&lt;p&gt;Program execution begins in the &lt;a class="reference external" href="http://www.kernel.org/"&gt;Linux kernel&lt;/a&gt;. To run a program, a process will call a function from the &lt;tt class="docutils literal"&gt;exec&lt;/tt&gt; &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Execve"&gt;family&lt;/a&gt;. The functions in this family are all very similar, differing only in small details regarding the manner of passing arguments and environment variables to the invoked program. What they all end up doing is issuing the &lt;tt class="docutils literal"&gt;sys_execve&lt;/tt&gt; &lt;a class="reference external" href="http://en.wikipedia.org/wiki/System_call"&gt;system call&lt;/a&gt; to the Linux kernel.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;sys_execve&lt;/tt&gt; does a lot of work to prepare the new program for execution. Explaining it all is far beyond the scope of this article - a good book on  kernel internals can be helpful to understand the details &lt;a class="footnote-reference" href="#id5" id="id1"&gt;[1]&lt;/a&gt;. I'll just focus on the stuff useful for our current discussion.&lt;/p&gt;
&lt;p&gt;As part of its job, the kernel must read the program's executable file from disk into memory and prepare it for execution. The kernel knows how to handle a lot of binary file formats, and tries to open the file with different handlers until it succeeds (this happens in the function &lt;tt class="docutils literal"&gt;search_binary_handler&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;fs/exec.c&lt;/tt&gt;). We're only interested in ELF here, however; for this format the action happens in function &lt;tt class="docutils literal"&gt;load_elf_binary&lt;/tt&gt; (in &lt;tt class="docutils literal"&gt;fs/binfmt_elf.c&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;The kernel reads the ELF header of the program, and looks for a &lt;tt class="docutils literal"&gt;PT_INTERP&lt;/tt&gt; segment to see if an interpreter was specified. Here the statically linked vs. dynamically linked distinction kicks in. For statically linked programs, there is no &lt;tt class="docutils literal"&gt;PT_INTERP&lt;/tt&gt; segment. This is the scenario this article covers.&lt;/p&gt;
&lt;p&gt;The kernel then goes on mapping the program's segments into memory, according to the information contained in the ELF program headers. Finally, it passes the execution, by directly modifying the IP register, to the entry address read from the ELF header of the program (&lt;tt class="docutils literal"&gt;e_entry&lt;/tt&gt;). Arguments are passed to the program on the stack (the code responsible for this is in &lt;tt class="docutils literal"&gt;create_elf_tables&lt;/tt&gt;). Here's the stack layout when the program is called, for x64:&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/2012/08/stack_for_start.png" /&gt;
&lt;p&gt;At the &lt;a class="reference external" href="https://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/"&gt;top of the stack&lt;/a&gt; is &lt;tt class="docutils literal"&gt;argc&lt;/tt&gt;, the amount of command-line arguments. It is followed by all the arguments themselves (each a &lt;tt class="docutils literal"&gt;char*&lt;/tt&gt;), terminated by a zero pointer. Then, the environment variables are listed (also a &lt;tt class="docutils literal"&gt;char*&lt;/tt&gt; each), terminated by a zero pointer. The observant reader will notice that this argument layout is not what one usually expects in &lt;tt class="docutils literal"&gt;main&lt;/tt&gt;. This is because &lt;tt class="docutils literal"&gt;main&lt;/tt&gt; is not really the entry point of the program, as the rest of the article shows.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="program-entry-point"&gt;
&lt;h3&gt;Program entry point&lt;/h3&gt;
&lt;p&gt;So, the Linux kernel reads the program's entry address from the ELF header. Let's now explore how this address gets there.&lt;/p&gt;
&lt;p&gt;Unless you're doing something very funky, the final program binary image is probably being created by the system linker - &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt;. By default, &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt; looks for a special symbol called &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; in one of the object files linked into the program, and sets the entry point to the address of that symbol. This will be simplest to demonstrate with an example written in assembly (the following is NASM syntax):&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;section    .text
    ; The _start symbol must be declared for the linker (ld)
    global _start

_start:
    ; Execute sys_exit call. Argument: status -&amp;gt; ebx
    mov     eax, 1
    mov     ebx, 42
    int     0x80
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a very basic program that simply returns &lt;tt class="docutils literal"&gt;42&lt;/tt&gt;. Note that it has the &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; symbol defined. Let's build it, examine the ELF header and its disassembly:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ nasm -f elf64 nasm_rc.asm -o nasm_rc.o
$ ld -o nasm_rc64 nasm_rc.o
$ readelf -h nasm_rc64
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  ...
  Entry point address:               0x400080
  ...
$ objdump -d nasm_rc64

nasm_rc64:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 &amp;lt;_start&amp;gt;:
  400080:     b8 01 00 00 00          mov    $0x1,%eax
  400085:     bb 2a 00 00 00          mov    $0x2a,%ebx
  40008a:     cd 80                   int    $0x80
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the entry point address in the ELF header was set to &lt;tt class="docutils literal"&gt;0x400080&lt;/tt&gt;, which also happens to be the address of &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;ld&lt;/tt&gt; looks for &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; by default, but this behavior can be modified by either the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--entry&lt;/span&gt;&lt;/tt&gt; command-line flag, or by providing an &lt;tt class="docutils literal"&gt;ENTRY&lt;/tt&gt; command in a custom &lt;a class="reference external" href="http://sourceware.org/binutils/docs/ld/Scripts.html#Scripts"&gt;linker script&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-entry-point-in-c-code"&gt;
&lt;h3&gt;The entry point in C code&lt;/h3&gt;
&lt;p&gt;We're usually not writing our code in assembly, however. For C/C++ the situation is different, because the entry point familiar to users is the &lt;tt class="docutils literal"&gt;main&lt;/tt&gt; function and not the &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; symbol. Now it's time to explain how these two are related.&lt;/p&gt;
&lt;p&gt;Let's start with this simple C program which is functionally equivalent to the assembly shown above:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;main&lt;/span&gt;() {
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007f7f"&gt;42&lt;/span&gt;;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I will compile this code into an object file and then attempt to link it with &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt;, like I did with the assembly:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc -c c_rc.c
$ ld -o c_rc c_rc.o
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Whoops, &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt; can't find the entry point. It tries to guess using a default, but it won't work - the program will segfault when run. &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt; obviously needs some additional object files where it will find the entry point. But which object files are these? Luckily, we can use &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; to find out. &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; can act as a full compilation driver, invoking &lt;tt class="docutils literal"&gt;ld&lt;/tt&gt; as needed. Let's now use &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; to link our object file into a program. Note that the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-static&lt;/span&gt;&lt;/tt&gt; flag is passed to force static linking of the C library and the &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; runtime library:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ gcc -o c_rc -static c_rc.o
$ c_rc; echo $?
42
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works. So how does &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; manage to do the linking correctly? We can pass the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-Wl,-verbose&lt;/span&gt;&lt;/tt&gt; flag to &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; which will spill the list of objects and libraries it passed to the linker. Doing this, we'll see additional object files like &lt;tt class="docutils literal"&gt;crt1.o&lt;/tt&gt; and the whole &lt;tt class="docutils literal"&gt;libc.a&lt;/tt&gt; static library (which has objects with telling names like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;libc-start.o&lt;/span&gt;&lt;/tt&gt;). C code does not live in a vacuum. To run, it requires some support libraries such as the gcc runtime and &lt;tt class="docutils literal"&gt;libc&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Since it obviously linked and ran correctly, the program we built with &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; should have a &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; symbol at the right place. Let's check &lt;a class="footnote-reference" href="#id6" id="id2"&gt;[2]&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -h c_rc
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00
  Class:                             ELF64
  ...
  Entry point address:               0x4003c0
  ...

$ objdump -d c_rc | grep -A15 &amp;quot;&amp;lt;_start&amp;quot;
00000000004003c0 &amp;lt;_start&amp;gt;:
  4003c0:     31 ed                   xor    %ebp,%ebp
  4003c2:     49 89 d1                mov    %rdx,%r9
  4003c5:     5e                      pop    %rsi
  4003c6:     48 89 e2                mov    %rsp,%rdx
  4003c9:     48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  4003cd:     50                      push   %rax
  4003ce:     54                      push   %rsp
  4003cf:     49 c7 c0 20 0f 40 00    mov    $0x400f20,%r8
  4003d6:     48 c7 c1 90 0e 40 00    mov    $0x400e90,%rcx
  4003dd:     48 c7 c7 d4 04 40 00    mov    $0x4004d4,%rdi
  4003e4:     e8 f7 00 00 00          callq  4004e0 &amp;lt;__libc_start_main&amp;gt;
  4003e9:     f4                      hlt
  4003ea:     90                      nop
  4003eb:     90                      nop
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Indeed, &lt;tt class="docutils literal"&gt;0x4003c0&lt;/tt&gt; is the address of &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; and it's the program entry point. However, what is all that code at &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt;? Where does it come from, and what does it mean?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="decoding-the-start-sequence-of-c-code"&gt;
&lt;h3&gt;Decoding the start sequence of C code&lt;/h3&gt;
&lt;p&gt;The startup code shown above comes from glibc - &lt;a class="reference external" href="http://www.gnu.org/software/libc/"&gt;the GNU C library&lt;/a&gt;, where for x64 ELF it lives in the file &lt;tt class="docutils literal"&gt;sysdeps/x86_64/start.S&lt;/tt&gt; &lt;a class="footnote-reference" href="#id7" id="id3"&gt;[3]&lt;/a&gt;. Its goal is to prepare the arguments for a function named &lt;tt class="docutils literal"&gt;__libc_start_main&lt;/tt&gt; and call it. This function is also part of glibc and lives in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;csu/libc-start.c&lt;/span&gt;&lt;/tt&gt;. Here is its signature, formatted for clarity, with added comments to explain what each argument means:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; __libc_start_main(
         &lt;span style="color: #007f00"&gt;/* Pointer to the program&amp;#39;s main function */&lt;/span&gt;
         (&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; (*main) (&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt;, &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;**, &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt;**),
         &lt;span style="color: #007f00"&gt;/* argc and argv */&lt;/span&gt;
         &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; argc, &lt;span style="color: #00007f; font-weight: bold"&gt;char&lt;/span&gt; **argv,
         &lt;span style="color: #007f00"&gt;/* Pointers to initialization and finalization functions */&lt;/span&gt;
         __typeof (main) init, &lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; (*fini) (&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;),
         &lt;span style="color: #007f00"&gt;/* Finalization function for the dynamic linker */&lt;/span&gt;
         &lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; (*rtld_fini) (&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;),
         &lt;span style="color: #007f00"&gt;/* End of stack */&lt;/span&gt;
         &lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt;* stack_end)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Anyway, with this signature and the &lt;a class="reference external" href="http://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI"&gt;AMD64 ABI&lt;/a&gt; in hand, we can map the arguments passed to &lt;tt class="docutils literal"&gt;__libc_start_main&lt;/tt&gt; from &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;main:      rdi &amp;lt;-- $0x4004d4
argc:      rsi &amp;lt;-- [RSP]
argv:      rdx &amp;lt;-- [RSP + 0x8]
init:      rcx &amp;lt;-- $0x400e90
fini:      r8  &amp;lt;-- $0x400f20
rdld_fini: r9  &amp;lt;-- rdx on entry
stack_end: on stack &amp;lt;-- RSP
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You'll also notice that the stack is aligned to 16 bytes and some garbage is pushed on top of it (&lt;tt class="docutils literal"&gt;rax&lt;/tt&gt;) before pushing &lt;tt class="docutils literal"&gt;rsp&lt;/tt&gt; itself. This is to conform to the AMD64 ABI. Also note the &lt;tt class="docutils literal"&gt;hlt&lt;/tt&gt; instruction at address &lt;tt class="docutils literal"&gt;0x4003e9&lt;/tt&gt;. It's a safeguard in case &lt;tt class="docutils literal"&gt;__libc_start_main&lt;/tt&gt; did not exit (as we'll see, it should). &lt;tt class="docutils literal"&gt;hlt&lt;/tt&gt; can't be executed in user mode, so this will raise an exception and crash the process.&lt;/p&gt;
&lt;p&gt;Examining the disassembly, it's easy to verify that &lt;tt class="docutils literal"&gt;0x4004d4&lt;/tt&gt; is indeed &lt;tt class="docutils literal"&gt;main&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;0x400e90&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;__libc_csu_init&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;0x400f20&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;__libc_csu_fini&lt;/tt&gt;. There's another argument the kernel passes &lt;tt class="docutils literal"&gt;_start&lt;/tt&gt; - a finish function for shared libraries to use (in &lt;tt class="docutils literal"&gt;rdx&lt;/tt&gt;). We'll ignore it in this article.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-c-library-start-function"&gt;
&lt;h3&gt;The C library start function&lt;/h3&gt;
&lt;p&gt;Now that we understood how it's being called, what does &lt;tt class="docutils literal"&gt;__libc_start_main&lt;/tt&gt; actually &lt;em&gt;do&lt;/em&gt;? Ignoring some details that are probably too specialized to be interesting in the scope of this article, here's a list of things that it does for a statically linked program:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Figure out where the environment variables are on the stack.&lt;/li&gt;
&lt;li&gt;Prepare the &lt;a class="reference external" href="http://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html"&gt;auxiliary vector&lt;/a&gt;, if required.&lt;/li&gt;
&lt;li&gt;Initialize thread-specific functionality (pthreads, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Thread-local_storage"&gt;TLS&lt;/a&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Perform some security-related bookkeeping (this is not really a separate step, but is trickled all through the function).&lt;/li&gt;
&lt;li&gt;Initialize libc itself.&lt;/li&gt;
&lt;li&gt;Call the program initialization function through the passed pointer (&lt;tt class="docutils literal"&gt;init&lt;/tt&gt;).&lt;/li&gt;
&lt;li&gt;Register the program finalization function (&lt;tt class="docutils literal"&gt;fini&lt;/tt&gt;) for execution on exit.&lt;/li&gt;
&lt;li&gt;Call &lt;tt class="docutils literal"&gt;main(argc, argv, envp)&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Call &lt;tt class="docutils literal"&gt;exit&lt;/tt&gt; with the result of &lt;tt class="docutils literal"&gt;main&lt;/tt&gt; as the exit code.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="digression-init-and-fini"&gt;
&lt;h3&gt;Digression: init and fini&lt;/h3&gt;
&lt;p&gt;Some programming environments (most notably C++, to construct and destruct static and global objects) require running custom code before and after &lt;tt class="docutils literal"&gt;main&lt;/tt&gt;. This is implemented by means of cooperation between the compiler/linker and the C library. For example, the &lt;tt class="docutils literal"&gt;__libc_csu_init&lt;/tt&gt; (which, as you can see above, is called before the user's &lt;tt class="docutils literal"&gt;main&lt;/tt&gt;) calls into special code that's inserted by the linker. The same goes for &lt;tt class="docutils literal"&gt;__libc_csu_fini&lt;/tt&gt; and finalization.&lt;/p&gt;
&lt;p&gt;You can also ask the compiler to register your function to be executed as one of the constructors or destructors. For example &lt;a class="footnote-reference" href="#id8" id="id4"&gt;[4]&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #007f00"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;main&lt;/span&gt;() {
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007f7f"&gt;43&lt;/span&gt;;
}

__attribute__((constructor))
&lt;span style="color: #00007f; font-weight: bold"&gt;void&lt;/span&gt; myconstructor() {
    printf(&lt;span style="color: #7f007f"&gt;&amp;quot;myconstructor\n&amp;quot;&lt;/span&gt;);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;myconstructor&lt;/tt&gt; will run &lt;em&gt;before main&lt;/em&gt;. The linker places its address in a special array of constructors located in the &lt;tt class="docutils literal"&gt;.ctors&lt;/tt&gt; section. &lt;tt class="docutils literal"&gt;__libc_csu_init&lt;/tt&gt; goes over this array and calls all functions listed in it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This article demonstrates how a statically linked program is set up to actually run on Linux. In my opinion, this is a very interesting topic to study because it demonstrates how several large components of the Linux eco-system cooperate to enable the program execution process. In this case, the Linux kernel, the compiler and linker, and the C library are involved. In a future article I will present the more complex case of a dynamically linked program, where another agent joins the game - the dynamic linker. Stay tuned.&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/hline.jpg" style="width: 320px; height: 5px;" /&gt;
&lt;table class="docutils footnote" frame="void" id="id5" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Or just read the source, if you're brave.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id6" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Note that due to our static linking of the C runtime into &lt;tt class="docutils literal"&gt;c_rc&lt;/tt&gt;, it's quite large (800 KB on my 64-bit Ubuntu system). Therefore we can't just easily look at the disassembly and have to use some &lt;tt class="docutils literal"&gt;grep&lt;/tt&gt;-fu.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id7" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;This is true for glibc 2.16.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id8" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id4"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Note that the constructor executes &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt;. Is this safe? If you look at the initialization sequence of &lt;tt class="docutils literal"&gt;__libc_start_main&lt;/tt&gt;, you'll see that the C library is initialized before the user's constructors are called, so yes, it's safe.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

    </content><category term="misc"></category><category term="Assembly"></category><category term="C &amp; C++"></category><category term="Linkers and loaders"></category><category term="Linux"></category></entry><entry><title>Position Independent Code (PIC) in shared libraries on x64</title><link href="https://eli.thegreenplace.net/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64" rel="alternate"></link><published>2011-11-11T15:10:11-08:00</published><updated>2023-06-30T23:16:27-07:00</updated><author><name>Eli Bendersky</name></author><id>tag:eli.thegreenplace.net,2011-11-11:/2011/11/11/position-independent-code-pic-in-shared-libraries-on-x64</id><summary type="html">
        &lt;p&gt;&lt;a class="reference external" href="https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/"&gt;The previous article&lt;/a&gt; explained how position independent code (PIC) works, with code compiled for the x86 architecture as an example. I promised to cover PIC on x64 &lt;a class="footnote-reference" href="#id8" id="id1"&gt;[1]&lt;/a&gt; in a separate article, so here we are. This article will go into much less detail, since it assumes an understanding of …&lt;/p&gt;</summary><content type="html">
        &lt;p&gt;&lt;a class="reference external" href="https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/"&gt;The previous article&lt;/a&gt; explained how position independent code (PIC) works, with code compiled for the x86 architecture as an example. I promised to cover PIC on x64 &lt;a class="footnote-reference" href="#id8" id="id1"&gt;[1]&lt;/a&gt; in a separate article, so here we are. This article will go into much less detail, since it assumes an understanding of how PIC works in theory. In general, the idea is similar for both platforms, but some details differ because of unique features of each architecture.&lt;/p&gt;
&lt;div class="section" id="rip-relative-addressing"&gt;
&lt;h3&gt;RIP-relative addressing&lt;/h3&gt;
&lt;p&gt;On x86, while function references (with the &lt;tt class="docutils literal"&gt;call&lt;/tt&gt; instruction) use relative offsets from the instruction pointer, data references (with the &lt;tt class="docutils literal"&gt;mov&lt;/tt&gt; instruction) only support absolute addresses. As we've seen in the previous article, this makes PIC code somewhat less efficient, since PIC by its nature requires making all offsets IP-relative; absolute addresses and position independence don't go well together.&lt;/p&gt;
&lt;p&gt;x64 fixes that, with a new &amp;quot;RIP-relative addressing mode&amp;quot;, which is the default for all 64-bit &lt;tt class="docutils literal"&gt;mov&lt;/tt&gt; instructions that reference memory (it's used for other instructions as well, such as &lt;tt class="docutils literal"&gt;lea&lt;/tt&gt;). A quote from the &amp;quot;Intel Architecture Manual vol 2a&amp;quot;:&lt;/p&gt;
&lt;blockquote&gt;
A new addressing form, RIP-relative (relative instruction-pointer) addressing, is implemented in 64-bit mode. An effective address is formed by adding displacement to the 64-bit RIP of the next instruction.&lt;/blockquote&gt;
&lt;p&gt;The displacement used in RIP-relative mode is 32 bits in size. Since it should be useful for both positive and negative offsets, roughly +/- 2GB is the maximal offset from RIP supported by this addressing mode.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="x64-pic-with-data-references-an-example"&gt;
&lt;h3&gt;x64 PIC with data references - an example&lt;/h3&gt;
&lt;p&gt;For easier comparison, I will use the same C source as in the data reference example of the previous article:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; myglob = &lt;span style="color: #007f7f"&gt;42&lt;/span&gt;;

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;ml_func&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; a, &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; b)
{
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; myglob + a + b;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's look at the disassembly of &lt;tt class="docutils literal"&gt;ml_func&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;00000000000005ec &amp;lt;ml_func&amp;gt;:
 5ec:   55                      push   rbp
 5ed:   48 89 e5                mov    rbp,rsp
 5f0:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
 5f3:   89 75 f8                mov    DWORD PTR [rbp-0x8],esi
 5f6:   48 8b 05 db 09 20 00    mov    rax,QWORD PTR [rip+0x2009db]
 5fd:   8b 00                   mov    eax,DWORD PTR [rax]
 5ff:   03 45 fc                add    eax,DWORD PTR [rbp-0x4]
 602:   03 45 f8                add    eax,DWORD PTR [rbp-0x8]
 605:   c9                      leave
 606:   c3                      ret
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The most interesting instruction here is at &lt;tt class="docutils literal"&gt;0x5f6&lt;/tt&gt;: it places the address of &lt;tt class="docutils literal"&gt;myglobal&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;rax&lt;/tt&gt;, by referencing an entry in the GOT. As we can see, it uses RIP relative addressing. Since it's relative to the address of the next instruction, what we actually get is &lt;tt class="docutils literal"&gt;0x5fd + 0x2009db = 0x200fd8&lt;/tt&gt;. So the GOT entry holding the address of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; is at &lt;tt class="docutils literal"&gt;0x200fd8&lt;/tt&gt;. Let's check if it makes sense:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -S libmlpic_dataonly.so
There are 35 section headers, starting at offset 0x13a8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align

[...]
  [20] .got              PROGBITS         0000000000200fc8  00000fc8
       0000000000000020  0000000000000008  WA       0     0     8
[...]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;GOT starts at &lt;tt class="docutils literal"&gt;0x200fc8&lt;/tt&gt;, so &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; is in its third entry. We can also see the relocation inserted for the GOT reference to &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -r libmlpic_dataonly.so

Relocation section &amp;#39;.rela.dyn&amp;#39; at offset 0x450 contains 5 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
[...]
000000200fd8  000500000006 R_X86_64_GLOB_DAT 0000000000201010 myglob + 0
[...]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Indeed, a relocation entry for &lt;tt class="docutils literal"&gt;0x200fd8&lt;/tt&gt; telling the dynamic linker to place the address of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; into it once the final address of this symbol is known.&lt;/p&gt;
&lt;p&gt;So it should be quite clear how the address of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; is obtained in the code. The next instruction in the disassembly (at &lt;tt class="docutils literal"&gt;0x5fd&lt;/tt&gt;) then dereferences the address to get the value of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;eax&lt;/tt&gt; &lt;a class="footnote-reference" href="#id9" id="id2"&gt;[2]&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="x64-pic-with-function-calls-an-example"&gt;
&lt;h3&gt;x64 PIC with function calls - an example&lt;/h3&gt;
&lt;p&gt;Now let's see how function calls work with PIC code on x64. Once again, we'll use the same example from the previous article:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; myglob = &lt;span style="color: #007f7f"&gt;42&lt;/span&gt;;

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;ml_util_func&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; a)
{
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; a + &lt;span style="color: #007f7f"&gt;1&lt;/span&gt;;
}

&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #00007f"&gt;ml_func&lt;/span&gt;(&lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; a, &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; b)
{
    &lt;span style="color: #00007f; font-weight: bold"&gt;int&lt;/span&gt; c = b + ml_util_func(a);
    myglob += c;
    &lt;span style="color: #00007f; font-weight: bold"&gt;return&lt;/span&gt; b + myglob;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Disassembling &lt;tt class="docutils literal"&gt;ml_func&lt;/tt&gt;, we get:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;000000000000064b &amp;lt;ml_func&amp;gt;:
 64b:   55                      push   rbp
 64c:   48 89 e5                mov    rbp,rsp
 64f:   48 83 ec 20             sub    rsp,0x20
 653:   89 7d ec                mov    DWORD PTR [rbp-0x14],edi
 656:   89 75 e8                mov    DWORD PTR [rbp-0x18],esi
 659:   8b 45 ec                mov    eax,DWORD PTR [rbp-0x14]
 65c:   89 c7                   mov    edi,eax
 65e:   e8 fd fe ff ff          call   560 &amp;lt;ml_util_func@plt&amp;gt;
 [... snip more code ...]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The call is, as before, to &lt;tt class="docutils literal"&gt;ml_util_func&amp;#64;plt&lt;/tt&gt;. Let's see what's there:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;0000000000000560 &amp;lt;ml_util_func@plt&amp;gt;:
 560:   ff 25 a2 0a 20 00       jmp    QWORD PTR [rip+0x200aa2]
 566:   68 01 00 00 00          push   0x1
 56b:   e9 d0 ff ff ff          jmp    540 &amp;lt;_init+0x18&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, the GOT entry holding the actual address of &lt;tt class="docutils literal"&gt;ml_util_func&lt;/tt&gt; is at &lt;tt class="docutils literal"&gt;0x200aa2 + 0x566 = 0x201008&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;And there's a relocation for it, as expected:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -r libmlpic.so

Relocation section &amp;#39;.rela.dyn&amp;#39; at offset 0x480 contains 5 entries:
[...]

Relocation section &amp;#39;.rela.plt&amp;#39; at offset 0x4f8 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
[...]
000000201008  000600000007 R_X86_64_JUMP_SLO 000000000000063c ml_util_func + 0
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="performance-implications"&gt;
&lt;h3&gt;Performance implications&lt;/h3&gt;
&lt;p&gt;In both examples, it can be seen that PIC on x64 requires less instructions than on x86. On x86, the GOT address is loaded into some base register (&lt;tt class="docutils literal"&gt;ebx&lt;/tt&gt; by convention) in two steps - first the address of the instruction is obtained with a special function call, and then the offset to GOT is added. Both steps aren't required on x64, since the relative offset to GOT is known to the linker and can simply be encoded in the instruction itself with RIP relative addressing.&lt;/p&gt;
&lt;p&gt;When calling a function, there's also no need to prepare the GOT address in &lt;tt class="docutils literal"&gt;ebx&lt;/tt&gt; for the trampoline, as the x86 code does, since the trampoline just accesses its GOT entry directly through RIP-relative addressing.&lt;/p&gt;
&lt;p&gt;So PIC on x64 still requires extra instructions when compared to non-PIC code, but the additional cost is smaller. The indirect cost of tying down a register to use as the GOT pointer (which is painful on x86) is also gone, since no such register is needed with RIP-relative addressing &lt;a class="footnote-reference" href="#id10" id="id3"&gt;[3]&lt;/a&gt;. All in all, x64 PIC results in a much smaller performance hit than on x86, making it much more attractive. So attractive, in fact, that it's the default method for writing shared libraries for this architecture.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="extra-credit-non-pic-code-on-x64"&gt;
&lt;h3&gt;Extra credit: Non-PIC code on x64&lt;/h3&gt;
&lt;p&gt;Not only does &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt; encourage you to use PIC for shared libraries on x64, it requires it by default. For instance, if we compile the first example without &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-fpic&lt;/span&gt;&lt;/tt&gt; &lt;a class="footnote-reference" href="#id11" id="id4"&gt;[4]&lt;/a&gt; and then try to link it into a shared library (with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-shared&lt;/span&gt;&lt;/tt&gt;), we'll get an error from the linker, something like this:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;/usr/bin/ld: ml_nopic_dataonly.o: relocation R_X86_64_PC32 against symbol `myglob&amp;#39; can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What's going on? Let's look at the disassembly of &lt;tt class="docutils literal"&gt;ml_nopic_dataonly.o&lt;/tt&gt; &lt;a class="footnote-reference" href="#id12" id="id5"&gt;[5]&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;0000000000000000 &amp;lt;ml_func&amp;gt;:
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
   7:   89 75 f8                mov    DWORD PTR [rbp-0x8],esi
   a:   8b 05 00 00 00 00       mov    eax,DWORD PTR [rip+0x0]
  10:   03 45 fc                add    eax,DWORD PTR [rbp-0x4]
  13:   03 45 f8                add    eax,DWORD PTR [rbp-0x8]
  16:   c9                      leave
  17:   c3                      ret
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note how &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; is accessed here, in instruction at address &lt;tt class="docutils literal"&gt;0xa&lt;/tt&gt;. It expects the linker to patch in a relocation to the actual location of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; into the operand of the instruction (so no GOT redirection is required):&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -r ml_nopic_dataonly.o

Relocation section &amp;#39;.rela.text&amp;#39; at offset 0xb38 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000000c  000f00000002 R_X86_64_PC32     0000000000000000 myglob - 4
[...]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is the &lt;tt class="docutils literal"&gt;R_X86_64_PC32&lt;/tt&gt; relocation the linker was complaining about. It just can't link an object with such relocation into a shared library. Why? Because the displacement of the &lt;tt class="docutils literal"&gt;mov&lt;/tt&gt; (the part that's added to &lt;tt class="docutils literal"&gt;rip&lt;/tt&gt;) must fit in 32 bits, and when a code gets into a shared library, we just can't know in advance that 32 bits will be enough. After all, this is a full 64-bit architecture, with a vast address space. The symbol may eventually be found in some shared library that's farther away from the reference than 32 bits will allow to reference. This makes &lt;tt class="docutils literal"&gt;R_X86_64_PC32&lt;/tt&gt; an invalid relocation for shared libraries on x64.&lt;/p&gt;
&lt;p&gt;But can we still somehow create non-PIC code on x64? Yes! We should be instructing the compiler to use the &amp;quot;large code model&amp;quot;, by adding the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-mcmodel=large&lt;/span&gt;&lt;/tt&gt; flag. The topic of code models is interesting, but explaining it would just take us too far from the real goal of this article &lt;a class="footnote-reference" href="#id13" id="id6"&gt;[6]&lt;/a&gt;. So I'll just say briefly that a code model is a kind of agreement between the programmer and the compiler, where the programmer makes a certain promise to the compiler about the size of offsets the program will be using. In exchange, the compiler can generate better code.&lt;/p&gt;
&lt;p&gt;It turns out that to make the compiler generate non-PIC code on x64 that actually pleases the linker, only the large code model is suitable, because it's the least restrictive. Remember how I explained why the simple relocation isn't good enough on x64, for fear of an offset which will get farther than 32 bits away during linking? Well, the large code model basically gives up on all offset assumptions and uses the largest 64-bit offsets for all its data references. This makes load-time relocations always safe, and enables non-PIC code generation on x64. Let's see the disassembly of the first example compiled without &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-fpic&lt;/span&gt;&lt;/tt&gt; and with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-mcmodel=large&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;0000000000000000 &amp;lt;ml_func&amp;gt;:
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
   4:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
   7:   89 75 f8                mov    DWORD PTR [rbp-0x8],esi
   a:   48 b8 00 00 00 00 00    mov    rax,0x0
  11:   00 00 00
  14:   8b 00                   mov    eax,DWORD PTR [rax]
  16:   03 45 fc                add    eax,DWORD PTR [rbp-0x4]
  19:   03 45 f8                add    eax,DWORD PTR [rbp-0x8]
  1c:   c9                      leave
  1d:   c3                      ret
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The instruction at address &lt;tt class="docutils literal"&gt;0xa&lt;/tt&gt; places the address of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;rax&lt;/tt&gt;. Note that its argument is currently 0, which tells us to expect a relocation. Note also that it has a full 64-bit address argument. Moreover, the argument is absolute and not RIP-relative &lt;a class="footnote-reference" href="#id14" id="id7"&gt;[7]&lt;/a&gt;. Note also that two instructions are actually required here to get the &lt;em&gt;value&lt;/em&gt; of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; into &lt;tt class="docutils literal"&gt;eax&lt;/tt&gt;. This is one reason why the large code model is less efficient than the alternatives.&lt;/p&gt;
&lt;p&gt;Now let's see the relocations:&lt;/p&gt;
&lt;div class="highlight" style="background: #ffffff"&gt;&lt;pre style="line-height: 125%"&gt;$ readelf -r ml_nopic_dataonly.o

Relocation section &amp;#39;.rela.text&amp;#39; at offset 0xb40 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000000c  000f00000001 R_X86_64_64       0000000000000000 myglob + 0
[...]
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note the relocation type has changed to &lt;tt class="docutils literal"&gt;R_X86_64_64&lt;/tt&gt;, which is an absolute relocation that can have a 64-bit value. It's acceptable by the linker, which will now gladly agree to link this object file into a shared library.&lt;/p&gt;
&lt;p&gt;Some judgmental thinking may bring you to ponder why the compiler generated code that isn't suitable for load-time relocation by default. The answer to this is simple. Don't forget that code also tends to get directly linked into executables, which don't require load-time relocations at all. Therefore, by default the compiler assumes the small code model to generate the most efficient code. If you know your code is going to get into a shared library, and you don't want PIC, then just tell it to use the large code model explicitly. I think &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt;'s behavior makes sense here.&lt;/p&gt;
&lt;p&gt;Another thing to think about is why there are no problems with PIC code using the small code model. The reason is that the GOT is always located in the same shared library as the code that references it, and unless a single shared library is big enough for a 32-bit address space, there should be no problems addressing the PIC with 32-bit RIP-relative offsets. Such huge shared libraries are unlikely, but in case you're working on one, the AMD64 ABI has a &amp;quot;large PIC code model&amp;quot; for this purpose.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This article complements its predecessor by showing how PIC works on the x64 architecture. This architecture has a new addressing mode that helps PIC code be faster, and thus makes it more desirable for shared libraries than on x86, where the cost is higher. Since x64 is currently the most popular architecture used in servers, desktops and laptops, this is important to know. Therefore, I tried to focus on additional aspects of compiling code into shared libraries, such as non-PIC code. If you have any questions and/or suggestions on future directions to explore, please let me know in the comments or by email.&lt;/p&gt;
&lt;img class="align-center" src="https://eli.thegreenplace.net/images/hline.jpg" style="width: 320px; height: 5px;" /&gt;
&lt;table class="docutils footnote" frame="void" id="id8" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;As always, I'm using x64 as a convenient short name for the architecture known as x86-64, AMD64 or Intel 64.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id9" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Into &lt;tt class="docutils literal"&gt;eax&lt;/tt&gt; and not &lt;tt class="docutils literal"&gt;rax&lt;/tt&gt; because the type of &lt;tt class="docutils literal"&gt;myglob&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;int&lt;/tt&gt;, which is still 32-bit on x64.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id10" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;By the way, it would be much less &amp;quot;painful&amp;quot; to tie down a register on x64, since it has twice as many GPRs as x86.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id11" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id4"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;It also happens if we explicitly specify we don't want PIC by passing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-fno-pic&lt;/span&gt;&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;gcc&lt;/tt&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id12" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id5"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Note that unlike other disassembly listings we've been looking at in this and the previous article, this is an object file, not a shared library or executable. Therefore it will contain some relocations for the linker.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id13" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id6"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;For some good information on this subject, take a look at the AMD64 ABI, and &lt;tt class="docutils literal"&gt;man gcc&lt;/tt&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id14" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id7"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Some assemblers call this instruction &lt;tt class="docutils literal"&gt;movabs&lt;/tt&gt; to distinguish it from the other &lt;tt class="docutils literal"&gt;mov&lt;/tt&gt; instructions that accept a relative argument. The Intel architecture manual, however, keeps naming it just &lt;tt class="docutils literal"&gt;mov&lt;/tt&gt;. Its opcode format is &lt;tt class="docutils literal"&gt;REX.W + B8 + rd&lt;/tt&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

    </content><category term="misc"></category><category term="Assembly"></category><category term="C &amp; C++"></category><category term="Linkers and loaders"></category><category term="Linux"></category></entry></feed>