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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
|
<table class="head">
<tr>
<td class="head-ltitle">LINK(5)</td>
<td class="head-vol">File Formats Manual</td>
<td class="head-rtitle">LINK(5)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">link</code> — <span class="Nd">dynamic
loader and link editor interface</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
<<a class="In">sys/types.h</a>></code>
<br/>
<code class="In">#include <<a class="In">nlist.h</a>></code>
<br/>
<code class="In">#include <<a class="In">link.h</a>></code></p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The include file
<code class="In"><<a class="In">link.h</a>></code> declares several
structures that are present in dynamically linked programs and libraries.
The structures define the interface between several components of the
link-editor and loader mechanism. The layout of a number of these structures
within the binaries resembles the a.out format in many places as it serves
such similar functions as symbol definitions (including the accompanying
string table) and relocation records needed to resolve references to
external entities. It also records a number of data structures unique to the
dynamic loading and linking process. These include references to other
objects that are required to complete the link-editing process and
indirection tables to facilitate
<a class="permalink" href="#Position"><i class="Em" id="Position">Position
Independent Code</i></a> (PIC for short) to improve sharing of code pages
among different processes. The collection of data structures described here
will be referred to as the
<a class="permalink" href="#Run-time"><i class="Em" id="Run-time">Run-time
Relocation Section (RRS)</i></a> and is embedded in the standard text and
data segments of the dynamically linked program or shared object image as
the existing <a class="Xr">a.out(5)</a> format offers no room for it
elsewhere.</p>
<p class="Pp">Several utilities cooperate to ensure that the task of getting a
program ready to run can complete successfully in a way that optimizes the
use of system resources. The compiler emits PIC code from which shared
libraries can be built by <a class="Xr">ld(1)</a>. The compiler also
includes size information of any initialized data items through the .size
assembler directive. PIC code differs from conventional code in that it
accesses data variables through an indirection table, the Global Offset
Table, by convention accessible by the reserved name
<code class="Dv">_GLOBAL_OFFSET_TABLE_</code>. The exact mechanism used for
this is machine dependent, usually a machine register is reserved for the
purpose. The rational behind this construct is to generate code that is
independent of the actual load address. Only the values contained in the
Global Offset Table may need updating at run-time depending on the load
addresses of the various shared objects in the address space.</p>
<p class="Pp">Likewise, procedure calls to globally defined functions are
redirected through the Procedure Linkage Table (PLT) residing in the data
segment of the core image. Again, this is done to avoid run-time
modifications to the text segment.</p>
<p class="Pp" id="_DYNAMIC">The linker-editor allocates the Global Offset Table
and Procedure Linkage Table when combining PIC object files into an image
suitable for mapping into the process address space. It also collects all
symbols that may be needed by the run-time link-editor and stores these
along with the image's text and data bits. Another reserved symbol,
<a class="permalink" href="#_DYNAMIC"><i class="Em">_DYNAMIC</i></a> is used
to indicate the presence of the run-time linker structures. Whenever
_DYNAMIC is relocated to 0, there is no need to invoke the run-time
link-editor. If this symbol is non-zero, it points at a data structure from
which the location of the necessary relocation- and symbol information can
be derived. This is most notably used by the start-up module,
<a class="permalink" href="#crt0"><i class="Em" id="crt0">crt0</i></a>. The
_DYNAMIC structure is conventionally located at the start of the data
segment of the image to which it pertains.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DATA_STRUCTURES"><a class="permalink" href="#DATA_STRUCTURES">DATA
STRUCTURES</a></h1>
<p class="Pp">The data structures supporting dynamic linking and run-time
relocation reside both in the text and data segments of the image they apply
to. The text segments contain read-only data such as symbols descriptions
and names, while the data segments contain the tables that need to be
modified by during the relocation process.</p>
<p class="Pp">The _DYNAMIC symbol references a <var class="Fa">_dynamic</var>
structure:</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct _dynamic {
int d_version;
struct so_debug *d_debug;
union {
struct section_dispatch_table *d_sdt;
} d_un;
struct ld_entry *d_entry;
};</pre>
</div>
<dl class="Bl-tag">
<dt id="LD_VERSION_SUN"><var class="Fa">d_version</var></dt>
<dd>This field provides for different versions of the dynamic linking
implementation. The current version numbers understood by
<a class="Xr">ld(1)</a> and <a class="Xr">ld.so(1)</a> are
<a class="permalink" href="#LD_VERSION_SUN"><i class="Em">LD_VERSION_SUN
(3)</i></a>, which is used by the SunOS 4.x releases, and
<a class="permalink" href="#LD_VERSION_BSD"><i class="Em" id="LD_VERSION_BSD">LD_VERSION_BSD
(8)</i></a>, which has been in use since <span class="Ux">FreeBSD
1.1</span>.</dd>
<dt id="d_version"><var class="Fa">d_un</var></dt>
<dd>Refers to a
<a class="permalink" href="#d_version"><i class="Em">d_version</i></a>
dependent data structure.</dd>
<dt><var class="Fa">so_debug</var></dt>
<dd>this field provides debuggers with a hook to access symbol tables of
shared objects loaded as a result of the actions of the run-time
link-editor.</dd>
</dl>
<p class="Pp">The <var class="Fa">section_dispatch_table</var> structure is the
main “dispatcher” table, containing offsets into the image's
segments where various symbol and relocation information is located.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct section_dispatch_table {
struct so_map *sdt_loaded;
long sdt_sods;
long sdt_filler1;
long sdt_got;
long sdt_plt;
long sdt_rel;
long sdt_hash;
long sdt_nzlist;
long sdt_filler2;
long sdt_buckets;
long sdt_strings;
long sdt_str_sz;
long sdt_text_sz;
long sdt_plt_sz;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">sdt_loaded</var></dt>
<dd>A pointer to the first link map loaded (see below). This field is set by
<code class="Nm">ld.so</code></dd>
<dt id="this"><var class="Fa">sdt_sods</var></dt>
<dd>The start of a (linked) list of shared object descriptors needed by
<a class="permalink" href="#this"><i class="Em">this</i></a> object.</dd>
<dt><var class="Fa">sdt_filler1</var></dt>
<dd>Deprecated (used by SunOS to specify library search rules).</dd>
<dt><var class="Fa">sdt_got</var></dt>
<dd>The location of the Global Offset Table within this image.</dd>
<dt><var class="Fa">sdt_plt</var></dt>
<dd>The location of the Procedure Linkage Table within this image.</dd>
<dt><var class="Fa">sdt_rel</var></dt>
<dd>The location of an array of <var class="Fa">relocation_info</var>
structures (see <a class="Xr">a.out(5)</a>) specifying run-time
relocations.</dd>
<dt><var class="Fa">sdt_hash</var></dt>
<dd>The location of the hash table for fast symbol lookup in this object's
symbol table.</dd>
<dt><var class="Fa">sdt_nzlist</var></dt>
<dd>The location of the symbol table.</dd>
<dt><var class="Fa">sdt_filler2</var></dt>
<dd>Currently unused.</dd>
<dt><var class="Fa">sdt_buckets</var></dt>
<dd>The number of buckets in <var class="Fa">sdt_hash</var></dd>
<dt><var class="Fa">sdt_strings</var></dt>
<dd>The location of the symbol string table that goes with
<var class="Fa">sdt_nzlist</var>.</dd>
<dt><var class="Fa">sdt_str_sz</var></dt>
<dd>The size of the string table.</dd>
<dt><var class="Fa">sdt_text_sz</var></dt>
<dd>The size of the object's text segment.</dd>
<dt><var class="Fa">sdt_plt_sz</var></dt>
<dd>The size of the Procedure Linkage Table.</dd>
</dl>
<p class="Pp">A <var class="Fa">sod</var> structure describes a shared object
that is needed to complete the link edit process of the object containing
it. A list of such objects (chained through <var class="Fa">sod_next</var>)
is pointed at by the <var class="Fa">sdt_sods</var> in the
section_dispatch_table structure.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct sod {
long sod_name;
u_int sod_library : 1,
sod_reserved : 31;
short sod_major;
short sod_minor;
long sod_next;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">sod_name</var></dt>
<dd>The offset in the text segment of a string describing this link
object.</dd>
<dt id="lib"><var class="Fa">sod_library</var></dt>
<dd>If set, <var class="Fa">sod_name</var> specifies a library that is to be
searched for by <code class="Nm">ld.so</code>. The path name is obtained
by searching a set of directories (see also <a class="Xr">ldconfig(8)</a>)
for a shared object matching
<a class="permalink" href="#lib"><i class="Em">lib<sod_name>.so.n.m</i></a>.
If not set, <var class="Fa">sod_name</var> should point at a full path
name for the desired shared object.</dd>
<dt><var class="Fa">sod_major</var></dt>
<dd>Specifies the major version number of the shared object to load.</dd>
<dt><var class="Fa">sod_minor</var></dt>
<dd>Specifies the preferred minor version number of the shared object to
load.</dd>
</dl>
<p class="Pp" id="link">The run-time link-editor maintains a list of structures
called <a class="permalink" href="#link"><i class="Em">link maps</i></a> to
keep track of all shared objects loaded into a process' address space. These
structures are only used at run-time and do not occur within the text or
data segment of an executable or shared library.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct so_map {
caddr_t som_addr;
char *som_path;
struct so_map *som_next;
struct sod *som_sod;
caddr_t som_sodbase;
u_int som_write : 1;
struct _dynamic *som_dynamic;
caddr_t som_spd;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">som_addr</var></dt>
<dd>The address at which the shared object associated with this link map has
been loaded.</dd>
<dt><var class="Fa">som_path</var></dt>
<dd>The full path name of the loaded object.</dd>
<dt><var class="Fa">som_next</var></dt>
<dd>Pointer to the next link map.</dd>
<dt><var class="Fa">som_sod</var></dt>
<dd>The <var class="Fa">sod</var> structure that was responsible for loading
this shared object.</dd>
<dt><var class="Fa">som_sodbase</var></dt>
<dd>Tossed out in later versions of the run-time linker.</dd>
<dt><var class="Fa">som_write</var></dt>
<dd>Set if (some portion of) this object's text segment is currently
writable.</dd>
<dt><var class="Fa">som_dynamic</var></dt>
<dd>Pointer to this object's <var class="Fa">_dynamic</var> structure.</dd>
<dt><var class="Fa">som_spd</var></dt>
<dd>Hook for attaching private data maintained by the run-time
link-editor.</dd>
</dl>
<p class="Pp">Symbol description with size. This is simply an
<var class="Fa">nlist</var> structure with one field
(<var class="Fa">nz_size</var>) added. Used to convey size information on
items in the data segment of shared objects. An array of these lives in the
shared object's text segment and is addressed by the
<var class="Fa">sdt_nzlist</var> field of
<var class="Fa">section_dispatch_table</var>.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct nzlist {
struct nlist nlist;
u_long nz_size;
#define nz_un nlist.n_un
#define nz_strx nlist.n_un.n_strx
#define nz_name nlist.n_un.n_name
#define nz_type nlist.n_type
#define nz_value nlist.n_value
#define nz_desc nlist.n_desc
#define nz_other nlist.n_other
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">nlist</var></dt>
<dd>(see <a class="Xr">nlist(3)</a>).</dd>
<dt><var class="Fa">nz_size</var></dt>
<dd>The size of the data represented by this symbol.</dd>
</dl>
<p class="Pp">A hash table is included within the text segment of shared object
to facilitate quick lookup of symbols during run-time link-editing. The
<var class="Fa">sdt_hash</var> field of the
<var class="Fa">section_dispatch_table</var> structure points at an array of
<var class="Fa">rrs_hash</var> structures:</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct rrs_hash {
int rh_symbolnum; /* symbol number */
int rh_next; /* next hash entry */
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">rh_symbolnum</var></dt>
<dd>The index of the symbol in the shared object's symbol table (as given by
the <var class="Fa">ld_symbols</var> field).</dd>
<dt><var class="Fa">rh_next</var></dt>
<dd>In case of collisions, this field is the offset of the next entry in this
hash table bucket. It is zero for the last bucket element.</dd>
</dl>
The <var class="Fa">rt_symbol</var> structure is used to keep track of run-time
allocated commons and data items copied from shared objects. These items are
kept on linked list and is exported through the <var class="Fa">dd_cc</var>
field in the <var class="Fa">so_debug</var> structure (see below) for use by
debuggers.
<div class="Bd Pp Bd-indent Li">
<pre>struct rt_symbol {
struct nzlist *rt_sp;
struct rt_symbol *rt_next;
struct rt_symbol *rt_link;
caddr_t rt_srcaddr;
struct so_map *rt_smp;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">rt_sp</var></dt>
<dd>The symbol description.</dd>
<dt><var class="Fa">rt_next</var></dt>
<dd>Virtual address of next rt_symbol.</dd>
<dt><var class="Fa">rt_link</var></dt>
<dd>Next in hash bucket. Used internally by
<code class="Nm">ld.so</code>.</dd>
<dt><var class="Fa">rt_srcaddr</var></dt>
<dd>Location of the source of initialized data within a shared object.</dd>
<dt><var class="Fa">rt_smp</var></dt>
<dd>The shared object which is the original source of the data that this
run-time symbol describes.</dd>
</dl>
<p class="Pp">The <var class="Fa">so_debug</var> structure is used by debuggers
to gain knowledge of any shared objects that have been loaded in the
process's address space as a result of run-time link-editing. Since the
run-time link-editor runs as a part of process initialization, a debugger
that wishes to access symbols from shared objects can only do so after the
link-editor has been called from crt0. A dynamically linked binary contains
a <var class="Fa">so_debug</var> structure which can be located by means of
the <var class="Fa">d_debug</var> field in
<var class="Fa">_dynamic</var>.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct so_debug {
int dd_version;
int dd_in_debugger;
int dd_sym_loaded;
char *dd_bpt_addr;
int dd_bpt_shadow;
struct rt_symbol *dd_cc;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">dd_version</var></dt>
<dd>Version number of this interface.</dd>
<dt><var class="Fa">dd_in_debugger</var></dt>
<dd>Set by the debugger to indicate to the run-time linker that the program is
run under control of a debugger.</dd>
<dt><var class="Fa">dd_sym_loaded</var></dt>
<dd>Set by the run-time linker whenever it adds symbols by loading shared
objects.</dd>
<dt><var class="Fa">dd_bpt_addr</var></dt>
<dd>The address where a breakpoint will be set by the run-time linker to
divert control to the debugger. This address is determined by the start-up
module, <span class="Pa">crt0.o</span>, to be some convenient place before
the call to _main.</dd>
<dt><var class="Fa">dd_bpt_shadow</var></dt>
<dd>Contains the original instruction that was at
<var class="Fa">dd_bpt_addr</var>. The debugger is expected to put this
instruction back before continuing the program.</dd>
<dt><var class="Fa">dd_cc</var></dt>
<dd>A pointer to the linked list of run-time allocated symbols that the
debugger may be interested in.</dd>
</dl>
<p class="Pp" id="ld_entry">The
<a class="permalink" href="#ld_entry"><i class="Em">ld_entry</i></a>
structure defines a set of service routines within
<code class="Nm">ld.so</code>.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct ld_entry {
void *(*dlopen)(char *, int);
int (*dlclose)(void *);
void *(*dlsym)(void *, char *);
char *(*dlerror)(void);
};</pre>
</div>
<p class="Pp">The <var class="Fa">crt_ldso</var> structure defines the interface
between the start-up code in crt0 and <code class="Nm">ld.so</code>.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct crt_ldso {
int crt_ba;
int crt_dzfd;
int crt_ldfd;
struct _dynamic *crt_dp;
char **crt_ep;
caddr_t crt_bp;
char *crt_prog;
char *crt_ldso;
struct ld_entry *crt_ldentry;
};
#define CRT_VERSION_SUN 1
#define CRT_VERSION_BSD_2 2
#define CRT_VERSION_BSD_3 3
#define CRT_VERSION_BSD_4 4</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">crt_ba</var></dt>
<dd>The virtual address at which <code class="Nm">ld.so</code> was loaded by
crt0.</dd>
<dt><var class="Fa">crt_dzfd</var></dt>
<dd>On SunOS systems, this field contains an open file descriptor to
“<span class="Pa">/dev/zero</span>” used to get demand paged
zeroed pages. On <span class="Ux">FreeBSD</span> systems it contains
-1.</dd>
<dt><var class="Fa">crt_ldfd</var></dt>
<dd>Contains an open file descriptor that was used by crt0 to load
<code class="Nm">ld.so</code>.</dd>
<dt><var class="Fa">crt_dp</var></dt>
<dd>A pointer to main's <var class="Fa">_dynamic</var> structure.</dd>
<dt><var class="Fa">crt_ep</var></dt>
<dd>A pointer to the environment strings.</dd>
<dt><var class="Fa">crt_bp</var></dt>
<dd>The address at which a breakpoint will be placed by the run-time linker if
the main program is run by a debugger. See
<var class="Fa">so_debug</var></dd>
<dt><var class="Fa">crt_prog</var></dt>
<dd>The name of the main program as determined by crt0 (CRT_VERSION_BSD3
only).</dd>
<dt><var class="Fa">crt_ldso</var></dt>
<dd>The path of the run-time linker as mapped by crt0 (CRT_VERSION_BSD4
only).</dd>
</dl>
<p class="Pp">The <var class="Fa">hints_header</var> and
<var class="Fa">hints_bucket</var> structures define the layout of the
library hints, normally found in
“<span class="Pa">/var/run/ld.so.hints</span>”, which is used
by <code class="Nm">ld.so</code> to quickly locate the shared object images
in the file system. The organization of the hints file is not unlike that of
an “a.out” object file, in that it contains a header
determining the offset and size of a table of fixed sized hash buckets and a
common string pool.</p>
<div class="Bd Pp Bd-indent Li">
<pre>struct hints_header {
long hh_magic;
#define HH_MAGIC 011421044151
long hh_version;
#define LD_HINTS_VERSION_1 1
long hh_hashtab;
long hh_nbucket;
long hh_strtab;
long hh_strtab_sz;
long hh_ehints;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">hh_magic</var></dt>
<dd>Hints file magic number.</dd>
<dt><var class="Fa">hh_version</var></dt>
<dd>Interface version number.</dd>
<dt><var class="Fa">hh_hashtab</var></dt>
<dd>Offset of hash table.</dd>
<dt><var class="Fa">hh_strtab</var></dt>
<dd>Offset of string table.</dd>
<dt><var class="Fa">hh_strtab_sz</var></dt>
<dd>Size of strings.</dd>
<dt><var class="Fa">hh_ehints</var></dt>
<dd>Maximum usable offset in hints file.</dd>
</dl>
<div class="Bd Pp Bd-indent Li">
<pre>/*
* Hash table element in hints file.
*/
struct hints_bucket {
int hi_namex;
int hi_pathx;
int hi_dewey[MAXDEWEY];
int hi_ndewey;
#define hi_major hi_dewey[0]
#define hi_minor hi_dewey[1]
int hi_next;
};</pre>
</div>
<dl class="Bl-tag">
<dt><var class="Fa">hi_namex</var></dt>
<dd>Index of the string identifying the library.</dd>
<dt><var class="Fa">hi_pathx</var></dt>
<dd>Index of the string representing the full path name of the library.</dd>
<dt><var class="Fa">hi_dewey</var></dt>
<dd>The version numbers of the shared library.</dd>
<dt><var class="Fa">hi_ndewey</var></dt>
<dd>The number of valid entries in <var class="Fa">hi_dewey</var>.</dd>
<dt><var class="Fa">hi_next</var></dt>
<dd>Next bucket in case of hashing collisions.</dd>
</dl>
</section>
<section class="Sh">
<h1 class="Sh" id="CAVEATS"><a class="permalink" href="#CAVEATS">CAVEATS</a></h1>
<p class="Pp">Only the (GNU) C compiler currently supports the creation of
shared libraries. Other programming languages cannot be used.</p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">October 23, 1993</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|