1lari(1) User Commands lari(1)
2
3
4
6 lari - link analysis of runtime interfaces
7
9 lari [-bCDsVv] [-a | -i | -o] file | directory...
10
11
12 lari [-CDosv] [-m [-d mapdir]] file
13
14
16 The lari utility analyzes the interface requirements of dynamic ELF
17 objects. Two basic modes of operation are available. The first mode
18 displays runtime interface information. The second mode generates
19 interface definitions.
20
21
22 Dynamic objects offer symbolic definitions that represent the interface
23 that the object provides for external consumers. At runtime, bindings
24 are established from the symbolic references of one object to the sym‐
25 bolic definitions of another object. lari analyzes both the interface
26 definitions and runtime bindings of the specified objects.
27
28
29 When displaying runtime interface information, lari can analyze a num‐
30 ber of files and/or directories. lari analyzes each file that is speci‐
31 fied on the command line. lari recursively descends into each directory
32 that is specified on the command line, processing each file that is
33 found.
34
35
36 When generating interface definitions, lari can only process a single
37 file specified on the command line.
38
39
40 Without the -D option, lari processes files as dynamic ELF objects by
41 using ldd(1). This processing uses the following options:
42
43 -r and -e LD_DEBUG=files,bindings,detail
44
45
46
47
48 These options provide information on all bindings that are established
49 as part of loading the object. Notice that by using ldd, the specified
50 object is not executed, and hence no user controlled loading of
51 objects, by dlopen(3C) for example, occurs. To capture all binding
52 information from an executing process, the following environment vari‐
53 ables can be passed directly to the runtime linker, ld.so.1(1):
54
55 LD_DEBUG=files,bindings,detail LD_DEBUG_OUTPUT=lari.dbg
56 LD_BIND_NOW=yes
57
58
59
60
61 The resulting debug output, lari.dbg.pid, can be processed by lari
62 using the -D option. Note: lari attempts to analyze each object that
63 has been processed using the path name defined in the debug output.
64 Each object must therefore be accessible to lari for a complete, accu‐
65 rate analysis to be provided. The debug output file must be generated
66 in the C locale.
67
68
69 When displaying interface information, lari analyzes the interfaces of
70 the processed dynamic objects and, by default, displays any interesting
71 information. See Interesting Information under EXTENDED DESCRIPTION.
72 The information that is displayed is also suitable for piping to other
73 tools. This capability can aid developers in analyzing process bindings
74 or debugging complex binding scenarios.
75
76
77 The generation of interface definitions by lari can be used to refine
78 the interface requirements of the dynamic objects that are processed.
79 When creating a dynamic object, you should define an explicit, ver‐
80 sioned interface. This definition controls the symbol definitions that
81 are available to external users. In addition, this definition fre‐
82 quently reduces the overall runtime execution cost of the object.
83 Interface definitions can be assigned to an object during its creation
84 by the link-editor using the -M option and the associated mapfile
85 directives. See the Linker and Libraries Guide for more details on
86 using mapfiles to version objects. An initial version of these mapfiles
87 can be created by lari.
88
90 The following options are supported.
91
92 -a Displays all interface information for the objects ana‐
93 lyzed. Note: The output from this option can be substan‐
94 tial, but is often useful for piping to other analysis
95 tools.
96
97
98 -b Limits the interface information to those symbols that
99 have been explicitly bound to. Note: Symbols defined as
100 protected might have been bound to from within the defin‐
101 ing object. This binding is satisfied at link-edit time
102 and is therefore not visible to the runtime environment.
103 Protected symbols are displayed with this option.
104
105
106 -C Demangles C++ symbol names. This option is useful for aug‐
107 menting runtime interface information. When generating
108 interface definitions, demangled names are added to the
109 mapfiles as comments.
110
111
112 -d mapdir Defines the directory, mapdir, in which mapfiles are cre‐
113 ated. By default, the current working directory is used.
114
115
116 -D Interprets any input files as debugging information rather
117 than as dynamic objects.
118
119
120 -i Displays interesting interface binding information. This
121 mode is the default if no other output controlling option
122 is supplied. See Interesting Information under EXTENDED
123 DESCRIPTION.
124
125
126 -m Creates mapfiles for each dynamic object that is pro‐
127 cessed. These mapfiles reflect the interface requirements
128 of each object as required by the input file being pro‐
129 cessed.
130
131
132 -o Limits the interface information to those symbols that are
133 deemed an overhead. When creating mapfiles, any overhead
134 symbols are itemized as local symbols. See Overhead Infor‐
135 mation under EXTENDED DESCRIPTION.
136
137
138 -s Saves the bindings information produced from ldd(1) for
139 further analysis. See FILES.
140
141
142 -V Appends interesting symbol visibilities. Symbols that are
143 defined as singleton or are defined protected are identi‐
144 fied with this option.
145
146
147 -v Ignores any objects that are already versioned. Versioned
148 objects have had their interfaces defined, but can con‐
149 tribute to the interface information displayed. For exam‐
150 ple, a versioned shared object might reveal overhead sym‐
151 bols for a particular process. Shared objects are fre‐
152 quently designed for use by multiple processes, and thus
153 the interfaces these objects provide can extend beyond the
154 requirements of any one process. The -v option therefore,
155 can reduce noise when displaying interface information.
156
157
158
159 The runtime interface information produced from lari has the following
160 format:
161
162 [information]: symbol-name [demangled-name]: object-name
163
164
165
166
167 Each line describes the interface symbol, symbol-name, together with
168 the object, object-name, in which the symbol is defined. If the symbol
169 represents a function, the symbol name is followed by (). If the symbol
170 represents a data object, the symbol name is followed by the symbols
171 size, enclosed within []. If the -C option is used, the symbol name is
172 accompanied by the symbols demangled name, demangled-name. The informa‐
173 tion field provides one or more of the following tokens that describe
174 the symbol's use:
175
176 cnt:bnd Two decimal values indicate the symbol count, cnt, and the
177 number of bindings to this object, bnd. The symbol count is
178 the number of occurrences of this symbol definition that
179 have been found in the objects that are analyzed. A count
180 that is greater than 1 indicates multiple instances of a
181 symbol definition. The number of bindings indicate the num‐
182 ber of objects that have been bound to this symbol defini‐
183 tion by the runtime linker.
184
185
186 E This symbol definition has been bound to from an external
187 object.
188
189
190 S This symbol definition has been bound to from the same
191 object.
192
193
194 D This symbol definition has been directly bound to.
195
196
197 I This symbol definition provides for an interposer. An
198 object that explicitly identifies itself as an interposor
199 defines all global symbols as interposers. See the -z inter‐
200 pose option of ld(1), and the LD_PRELOAD variable of
201 ld.so.1(1). Individual symbols within a dynamic executable
202 can be defined as interposers by using the INTERPOSE mapfile
203 directive.
204
205
206 C This symbol definition is the reference data of a copy-relo‐
207 cation.
208
209
210 F This symbol definition resides in a filtee.
211
212
213 P This symbol is defined as protected. This symbol might have
214 an internal binding from the object in which the symbol is
215 declared. Any internal bindings with this attribute can not
216 be interposed upon by another symbol definition.
217
218
219 A This symbol definition is the address of a procedure linkage
220 table entry within a dynamic executable.
221
222
223 U This symbol lookup originated from a user request, for exam‐
224 ple, dlsym(3C).
225
226
227 R This symbol definition is acting as a filter, and provides
228 for redirection to a filtee.
229
230
231 r A binding to this symbol was rejected at some point during a
232 symbol search. A rejection can occur when a direct binding
233 request finds a symbol that has been tagged to prevent
234 direct binding. In this scenario, the symbol search is
235 repeated using a default search model. The binding can still
236 resolve to the original, rejected symbol. A rejection can
237 also occur when a non-default symbol search finds a symbol
238 identified as a singleton. Again, the symbol search is
239 repeated using a default search model.
240
241
242 N This symbol definition explicitly prohibits directly binding
243 to the definition.
244
245
246
247 See the Linker and Libraries Guide for more details of these symbol
248 classifications.
249
251 Interesting Information
252 By default, or specifically using the -i option, lari filters any run‐
253 time interface information to present interesting events. This filter‐
254 ing is carried out mainly to reduce the amount of information that can
255 be generated from large applications. In addition, this information is
256 intended to be the focus in debugging complex binding scenarios, and
257 often highlights problem areas. However, classifying what information
258 is interesting for any particular application is an inexact science.
259 You are still free to use the -a option and to search the binding
260 information for events that are unique to the application being inves‐
261 tigated.
262
263
264 When an interesting symbol definition is discovered, all other defini‐
265 tions of the same symbol are output.
266
267
268 The focus of interesting interface information is the existence of mul‐
269 tiple definitions of a symbol. In this case, one symbol typically
270 interposes on one or more other symbol definitions. This interposition
271 is seen when the binding count, bnd, of one definition is non-zero,
272 while the binding count of all other definitions is zero. Interposition
273 that results from the compilation environment, or the linking environ‐
274 ment, is not characterized as interesting. Examples of these interposi‐
275 tion occurrences include copy relocations ([C]) and the binding to pro‐
276 cedure linkage addresses ([A]).
277
278
279 Interposition is often desirable. The intent is to overload, or
280 replace, the symbolic definition from a shared object. Interpositioning
281 objects can be explicitly tagged ([I]), using the -z interpose option
282 of ld(1). These objects can safely interpose on symbols, no matter what
283 order the objects are loaded in a process. However, be cautious when
284 non-explicit interposition is employed, as this interposition is a con‐
285 sequence of the load-order of the objects that make up the process.
286
287
288 User-created, multiply-defined symbols are output from lari as inter‐
289 esting. In this example, two definitions of interpose1() exist, but
290 only the definition in main is referenced:
291
292 [2:1E]: interpose1(): ./main
293 [2:0]: interpose1(): ./libA.so
294
295
296
297
298 Interposition can also be an undesirable and surprising event, caused
299 by an unexpected symbol name clash. A symptom of this interposition
300 might be that a function is never called although you know a reference
301 to the function exists. This scenario can be identified as a multiply
302 defined symbol, as covered in the previous example. However, a more
303 surprising scenario is often encountered when an object both defines
304 and references a specific symbol.
305
306
307 An example of this scenario is if two dynamic objects define and refer‐
308 ence the same function, interpose2(). Any reference to this symbol
309 binds to the first dynamic object loaded with the process. In this
310 case, the definition of interpose2() in object libA.so interposes on,
311 and hides, the definition of interpose2() in object libB.so. The output
312 from lari might be:
313
314 [2:2ES]: interpose2(): ./libA.so
315 [2:0]: interpose2(): ./libB.so
316
317
318
319
320 Multiply defined symbols can also be bound to separately. Separate
321 bindings can be the case when direct bindings are in effect ([D]), or
322 because a symbol has protected visibility ([P]). Although separate
323 bindings can be explicitly established, instances can exist that are
324 unexpected and surprising. Directly bound symbols, and symbols with
325 protected visibility, are output as interesting information.
326
327 Overhead Information
328 When using the -o option, lari displays symbol definitions that might
329 be considered overhead.
330
331
332 Global symbols that are not referenced are considered an overhead. The
333 symbol information that is provided within the object unnecessarily
334 adds to the size of the object's text segment. In addition, the symbol
335 information can increase the processing required to search for other
336 symbolic references within the object at runtime.
337
338
339 Global symbols that are only referenced from the same object have the
340 same characteristics. The runtime search for a symbolic reference, that
341 results in binding to the same object that made the reference, is an
342 additional overhead.
343
344
345 Both of these symbol definitions are candidates for reduction to local
346 scope by defining the object's interface. Interface definitions can be
347 assigned to a file during its creation by the link-editor using the -M
348 option and the associated mapfile directives. See the Linker and
349 Libraries Guide for more details on mapfiles. Use lari with the -m
350 option to create initial versions of these mapfiles.
351
352
353 If lari is used to generate mapfiles, versioned shared objects will
354 have mapfiles created indicating that their overhead symbols should be
355 reduced to locals. This model allows lari to generate mapfiles for com‐
356 parison with existing interface definitions. Use the -v option to
357 ignore versioned shared objects when creating mapfiles.
358
359
360 Copy-relocations are also viewed as an overhead and generally should be
361 avoided. The size of the copied data is a definition of its interface.
362 This definition restricts the ability to change the data size in newer
363 versions of the shared object in which the data is defined. This
364 restriction, plus the cost of processing a copy relocation, can be
365 avoided by referencing data using a functional interface. The output
366 from lari for a copy relocation might be:
367
368 [2:1EC]: __iob[0x140]: ./main
369 [2:0]: __iob[0x140]: ./libA.so.1
370
371
372
373
374 Notice that a number of small copy relocations, such as __iob used in
375 the previous example, exist because of historic programming interac‐
376 tions with system libraries.
377
378
379 Another example of overhead information is the binding of a dynamic
380 object to the procedure linkage table entry of a dynamic executable. If
381 a dynamic executable references an external function, a procedure link‐
382 age table entry is created. This structure allows the reference binding
383 to be deferred until the function call is actually made. If a dynamic
384 object takes the address of the same referenced function, the dynamic
385 object binds to the dynamic executables procedure linkage table entry.
386 An example of this type of event reveals the following:
387
388 [2:1EA]: foo(): ./main
389 [2:1E]: foo(): ./libA.so
390
391
392
393
394 A small number of bindings of this type are typically not cause for
395 concern. However, a large number of these bindings, perhaps from a
396 jump-table programming technique, can contribute to start up overhead.
397 Address relocation bindings of this type require relocation processing
398 at application start up, rather than the deferred relocation processing
399 used when calling functions directly. Use of this address also requires
400 an indirection at runtime.
401
403 Example 1 Analyzing a case of multiple bindings
404
405
406 The following example shows the analysis of a process in which multiple
407 symbol definitions exist. The shared objects libX.so and libY.so both
408 call the function interpose(). This function exists in both the appli‐
409 cation main, and the shared object libA.so. Because of interposition,
410 both references bind to the definition of interpose() in main.
411
412
413
414 The shared objects libX.so and libY.so also both call the function
415 foo(). This function exists in the application main, and the shared
416 objects libA.so, libX.so, and libY.so. Because both libX.so and libY.so
417 were built with direct bindings enabled, each object binds to its own
418 definition.
419
420
421 example% lari ./main
422 [3:0]: foo(): ./libA.so
423 [3:1SD]: foo(): ./libX.so
424 [3:1SD]: foo(): ./libY.so
425 [2:0]: interpose(): ./libA.so
426 [2:2EP]: interpose(): ./main
427
428
429
430
431 To analyze binding information more thoroughly, the bindings data can
432 be saved for further inspection. For example, the previous output indi‐
433 cates that the function interpose() was called from two objects exter‐
434 nal to main. Inspection of the binding output reveals where the refer‐
435 ences to this function originated.
436
437
438 example% lari -s ./main
439 lari: ./main: bindings information saved as: /usr/tmp/lari.dbg.main
440 .....
441 example% fgrep foo /usr/tmp/lari.dbg.main
442 binding file=./libX.so to file=./main: symbol `interpose'
443 binding file=./libY.so to file=./main: symbol `interpose'
444
445
446
447
448 Note: The bindings output is typically more extensive than shown here,
449 as the output is accompanied with process identifier, address and other
450 bindings information.
451
452
453 Example 2 Generating an interface definition
454
455
456 The following example creates interface definitions for an application
457 and its dependency, while ignoring any versioned system libraries. The
458 application main makes reference to the interfaces one(), two(), and
459 three() in foo.so:
460
461
462 example% lari -omv ./main
463 example% cat mapfile-foo.so
464 #
465 # Interface Definition mapfile for:
466 # Dynamic Object: ./foo.so
467 # Process: ./main
468 #
469
470 foo.so {
471 global:
472 one;
473 three;
474 two;
475 local:
476 _one;
477 _three;
478 _two;
479 *;
480 };
481
482
483
485 $TMPDIR/lari.dbg.file Binding output produced by ldd(1).
486
487
489 See attributes(5) for descriptions of the following attributes:
490
491
492
493
494 ┌─────────────────────────────┬─────────────────────────────┐
495 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
496 ├─────────────────────────────┼─────────────────────────────┤
497 │Availability │SUNWtoo │
498 ├─────────────────────────────┼─────────────────────────────┤
499 │Interface Stability │See below. │
500 └─────────────────────────────┴─────────────────────────────┘
501
502
503 The human readable output is Uncommitted. The options are Committed.
504
506 ld(1), ldd(1), ld.so.1(1), dlopen(3C), dlsym(3C), attributes(5)
507
508
509 Linker and Libraries Guide
510
511
512
513SunOS 5.11 28 Nov 2007 lari(1)