-
Notifications
You must be signed in to change notification settings - Fork 0
/
Partitions.html
223 lines (207 loc) · 12.6 KB
/
Partitions.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Partitions — lld 11 documentation</title>
<link rel="stylesheet" href="_static/llvm.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="lld 11.0.0 Release Notes" href="ReleaseNotes.html" />
<link rel="prev" title="Windows support" href="windows_support.html" />
<style type="text/css">
table.right { float: right; margin-left: 20px; }
table.right td { border: 1px solid #ccc; }
</style>
</head><body>
<div class="logo">
<a href="index.html"><img src="_static/logo.png" alt="LLVM Documentation"/></a>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="ReleaseNotes.html" title="lld 11.0.0 Release Notes"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="windows_support.html" title="Windows support"
accesskey="P">previous</a> |</li>
<li><a href="index.html">lld Home</a> | </li>
</ul>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Partitions</a><ul>
<li><a class="reference internal" href="#usage">Usage</a></li>
<li><a class="reference internal" href="#restrictions">Restrictions</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="windows_support.html"
title="previous chapter">Windows support</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="ReleaseNotes.html"
title="next chapter">lld 11.0.0 Release Notes</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/Partitions.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="partitions">
<h1>Partitions<a class="headerlink" href="#partitions" title="Permalink to this headline">¶</a></h1>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">This feature is currently experimental, and its interface is subject
to change.</p>
</div>
<p>LLD’s partitioning feature allows a program (which may be an executable
or a shared library) to be split into multiple pieces, or partitions. A
partitioned program consists of a main partition together with a number of
loadable partitions. The loadable partitions depend on the main partition
in a similar way to a regular ELF shared object dependency, but unlike a
shared object, the main partition and the loadable partitions share a virtual
address space at link time, and each loadable partition is assigned a fixed
offset from the main partition. This allows the loadable partitions to refer
to code and data in the main partition directly without the binary size and
performance overhead of PLTs, GOTs or symbol table entries.</p>
<div class="section" id="usage">
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h2>
<p>A program that uses the partitioning feature must decide which symbols are
going to be used as the “entry points” for each partition. An entry point
could, for example, be the equivalent of the partition’s <code class="docutils literal notranslate"><span class="pre">main</span></code> function, or
there could be a group of functions that expose the functionality implemented
by the partition. The intent is that in order to use a loadable partition,
the program will use <code class="docutils literal notranslate"><span class="pre">dlopen</span></code>/<code class="docutils literal notranslate"><span class="pre">dlsym</span></code> or similar functions to dynamically
load the partition at its assigned address, look up an entry point by name
and call it. Note, however, that the standard <code class="docutils literal notranslate"><span class="pre">dlopen</span></code> function does not
allow specifying a load address. On Android, the <code class="docutils literal notranslate"><span class="pre">android_dlopen_ext</span></code>
function may be used together with the <code class="docutils literal notranslate"><span class="pre">ANDROID_DLEXT_RESERVED_ADDRESS</span></code>
flag to load a shared object at a specific address.</p>
<p>Once the entry points have been decided, the translation unit(s)
containing the entry points should be compiled using the Clang compiler flag
<code class="docutils literal notranslate"><span class="pre">-fsymbol-partition=<soname></span></code>, where <code class="docutils literal notranslate"><span class="pre"><soname></span></code> is the intended soname
of the partition. The resulting object files are passed to the linker in
the usual way.</p>
<p>The linker will then use these entry points to automatically split the program
into partitions according to which sections of the program are reachable from
which entry points, similarly to how <code class="docutils literal notranslate"><span class="pre">--gc-sections</span></code> removes unused parts of
a program. Any sections that are only reachable from a loadable partition’s
entry point are assigned to that partition, while all other sections are
assigned to the main partition, including sections only reachable from
loadable partitions.</p>
<p>The following diagram illustrates how sections are assigned to partitions. Each
section is colored according to its assigned partition.</p>
<img alt="_images/partitions.svg" src="_images/partitions.svg" /><p>The result of linking a program that uses partitions is essentially an
ELF file with all of the partitions concatenated together. This file is
referred to as a combined output file. To extract a partition from the
combined output file, the <code class="docutils literal notranslate"><span class="pre">llvm-objcopy</span></code> tool should be used together
with the flag <code class="docutils literal notranslate"><span class="pre">--extract-main-partition</span></code> to extract the main partition, or
<code class="docutils literal notranslate"><span class="pre">-extract-partition=<soname></span></code> to extract one of the loadable partitions.
An example command sequence is shown below:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile the main program.</span>
clang -ffunction-sections -fdata-sections -c main.c
<span class="c1"># Compile a feature to be placed in a loadable partition.</span>
<span class="c1"># Note that this is likely to be a separate build step to the main partition.</span>
clang -ffunction-sections -fdata-sections -fsymbol-partition<span class="o">=</span>libfeature.so -c feature.c
<span class="c1"># Link the combined output file.</span>
clang main.o feature.o -fuse-ld<span class="o">=</span>lld -shared -o libcombined.so -Wl,-soname,libmain.so -Wl,--gc-sections
<span class="c1"># Extract the partitions.</span>
llvm-objcopy libcombined.so libmain.so --extract-main-partition
llvm-objcopy libcombined.so libfeature.so --extract-partition<span class="o">=</span>libfeature.so
</pre></div>
</div>
<p>In order to allow a program to discover the names of its loadable partitions
and the locations of their reserved regions, the linker creates a partition
index, which is an array of structs with the following definition:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">partition_index_entry</span> <span class="p">{</span>
<span class="kt">int32_t</span> <span class="n">name_offset</span><span class="p">;</span>
<span class="kt">int32_t</span> <span class="n">addr_offset</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">size</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">name_offset</span></code> field is a relative pointer to a null-terminated string
containing the soname of the partition, the <code class="docutils literal notranslate"><span class="pre">addr_offset</span></code> field is a
relative pointer to its load address and the <code class="docutils literal notranslate"><span class="pre">size</span></code> field contains the
size of the region reserved for the partition. To derive an absolute pointer
from the relative pointer fields in this data structure, the address of the
field should be added to the value stored in the field.</p>
<p>The program may discover the location of the partition index using the
linker-defined symbols <code class="docutils literal notranslate"><span class="pre">__part_index_begin</span></code> and <code class="docutils literal notranslate"><span class="pre">__part_index_end</span></code>.</p>
</div>
<div class="section" id="restrictions">
<h2>Restrictions<a class="headerlink" href="#restrictions" title="Permalink to this headline">¶</a></h2>
<p>This feature is currently only supported in the ELF linker.</p>
<p>The partitioning feature may not currently be used together with the
<code class="docutils literal notranslate"><span class="pre">SECTIONS</span></code> or <code class="docutils literal notranslate"><span class="pre">PHDRS</span></code> linker script features, nor may it be used with the
<code class="docutils literal notranslate"><span class="pre">--section-start</span></code>, <code class="docutils literal notranslate"><span class="pre">-Ttext</span></code>, <code class="docutils literal notranslate"><span class="pre">-Tdata</span></code> or <code class="docutils literal notranslate"><span class="pre">-Tbss</span></code> flags. All of these
features assume a single set of output sections and/or program headers, which
makes their semantics ambiguous in the presence of more than one partition.</p>
<p>The partitioning feature may not currently be used on the MIPS architecture
because it is unclear whether the MIPS multi-GOT ABI is compatible with
partitions.</p>
<p>The current implementation only supports creating up to 254 partitions due
to implementation limitations. This limit may be relaxed in the future.</p>
</div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="ReleaseNotes.html" title="lld 11.0.0 Release Notes"
>next</a> |</li>
<li class="right" >
<a href="windows_support.html" title="Windows support"
>previous</a> |</li>
<li><a href="index.html">lld Home</a> | </li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2011-2020, LLVM Project.
Last updated on 2020-02-14.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.5.
</div>
</body>
</html>