Print this page
smatch clean rtld
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/rtld/common/elf.c
+++ new/usr/src/cmd/sgs/rtld/common/elf.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 1988 AT&T
24 24 * All Rights Reserved
25 25 *
26 26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
27 27 */
28 28 /*
29 29 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
30 30 */
31 31
32 32 /*
33 33 * Object file dependent support for ELF objects.
34 34 */
35 35
36 36 #include <stdio.h>
37 37 #include <sys/procfs.h>
38 38 #include <sys/mman.h>
39 39 #include <sys/debug.h>
40 40 #include <string.h>
41 41 #include <limits.h>
42 42 #include <dlfcn.h>
43 43 #include <debug.h>
44 44 #include <conv.h>
45 45 #include "_rtld.h"
46 46 #include "_audit.h"
47 47 #include "_elf.h"
48 48 #include "_inline_gen.h"
49 49 #include "_inline_reloc.h"
50 50 #include "msg.h"
51 51
52 52 /*
53 53 * Default and secure dependency search paths.
54 54 */
55 55 static Spath_defn _elf_def_dirs[] = {
56 56 #if defined(_ELF64)
57 57 { MSG_ORIG(MSG_PTH_LIB_64), MSG_PTH_LIB_64_SIZE },
58 58 { MSG_ORIG(MSG_PTH_USRLIB_64), MSG_PTH_USRLIB_64_SIZE },
59 59 #else
60 60 { MSG_ORIG(MSG_PTH_LIB), MSG_PTH_LIB_SIZE },
61 61 { MSG_ORIG(MSG_PTH_USRLIB), MSG_PTH_USRLIB_SIZE },
62 62 #endif
63 63 { 0, 0 }
64 64 };
65 65
66 66 static Spath_defn _elf_sec_dirs[] = {
67 67 #if defined(_ELF64)
68 68 { MSG_ORIG(MSG_PTH_LIBSE_64), MSG_PTH_LIBSE_64_SIZE },
69 69 { MSG_ORIG(MSG_PTH_USRLIBSE_64), MSG_PTH_USRLIBSE_64_SIZE },
70 70 #else
71 71 { MSG_ORIG(MSG_PTH_LIBSE), MSG_PTH_LIBSE_SIZE },
72 72 { MSG_ORIG(MSG_PTH_USRLIBSE), MSG_PTH_USRLIBSE_SIZE },
73 73 #endif
74 74 { 0, 0 }
75 75 };
76 76
77 77 Alist *elf_def_dirs = NULL;
78 78 Alist *elf_sec_dirs = NULL;
79 79
80 80 /*
81 81 * Defines for local functions.
82 82 */
83 83 static void elf_dladdr(ulong_t, Rt_map *, Dl_info *, void **, int);
84 84 static Addr elf_entry_point(void);
85 85 static int elf_fix_name(const char *, Rt_map *, Alist **, Aliste, uint_t);
86 86 static Alist **elf_get_def_dirs(void);
87 87 static Alist **elf_get_sec_dirs(void);
88 88 static char *elf_get_so(const char *, const char *, size_t, size_t);
89 89 static int elf_needed(Lm_list *, Aliste, Rt_map *, int *);
90 90
91 91 /*
92 92 * Functions and data accessed through indirect pointers.
93 93 */
94 94 Fct elf_fct = {
95 95 elf_verify,
96 96 elf_new_lmp,
97 97 elf_entry_point,
98 98 elf_needed,
99 99 lookup_sym,
100 100 elf_reloc,
101 101 elf_get_def_dirs,
102 102 elf_get_sec_dirs,
103 103 elf_fix_name,
104 104 elf_get_so,
105 105 elf_dladdr,
106 106 dlsym_handle
107 107 };
108 108
109 109 /*
110 110 * Default and secure dependency search paths.
111 111 */
112 112 static Alist **
113 113 elf_get_def_dirs()
114 114 {
115 115 if (elf_def_dirs == NULL)
116 116 set_dirs(&elf_def_dirs, _elf_def_dirs, LA_SER_DEFAULT);
117 117 return (&elf_def_dirs);
118 118 }
119 119
120 120 static Alist **
121 121 elf_get_sec_dirs()
122 122 {
123 123 if (elf_sec_dirs == NULL)
124 124 set_dirs(&elf_sec_dirs, _elf_sec_dirs, LA_SER_SECURE);
125 125 return (&elf_sec_dirs);
126 126 }
127 127
128 128 /*
129 129 * Redefine NEEDED name if necessary.
130 130 */
131 131 static int
132 132 elf_fix_name(const char *name, Rt_map *clmp, Alist **alpp, Aliste alni,
133 133 uint_t orig)
134 134 {
135 135 /*
136 136 * For ABI compliance, if we are asked for ld.so.1, then really give
137 137 * them libsys.so.1 (the SONAME of libsys.so.1 is ld.so.1).
138 138 */
139 139 if (((*name == '/') &&
140 140 /* BEGIN CSTYLED */
141 141 #if defined(_ELF64)
142 142 (strcmp(name, MSG_ORIG(MSG_PTH_RTLD_64)) == 0)) ||
143 143 #else
144 144 (strcmp(name, MSG_ORIG(MSG_PTH_RTLD)) == 0)) ||
145 145 #endif
146 146 (strcmp(name, MSG_ORIG(MSG_FIL_RTLD)) == 0)) {
147 147 /* END CSTYLED */
148 148 Pdesc *pdp;
149 149
150 150 DBG_CALL(Dbg_file_fixname(LIST(clmp), name,
151 151 MSG_ORIG(MSG_PTH_LIBSYS)));
152 152 if ((pdp = alist_append(alpp, NULL, sizeof (Pdesc),
153 153 alni)) == NULL)
154 154 return (0);
155 155
156 156 pdp->pd_pname = (char *)MSG_ORIG(MSG_PTH_LIBSYS);
157 157 pdp->pd_plen = MSG_PTH_LIBSYS_SIZE;
158 158 pdp->pd_flags = PD_FLG_PNSLASH;
159 159
160 160 return (1);
161 161 }
162 162
163 163 return (expand_paths(clmp, name, alpp, alni, orig, 0));
164 164 }
165 165
166 166 /*
167 167 * Determine whether this object requires capabilities.
168 168 */
169 169 inline static int
170 170 elf_cap_check(Fdesc *fdp, Ehdr *ehdr, Rej_desc *rej)
171 171 {
172 172 Phdr *phdr;
173 173 Cap *cap = NULL;
174 174 Dyn *dyn = NULL;
175 175 char *str = NULL;
176 176 Addr base;
177 177 uint_t cnt, dyncnt;
178 178
179 179 /*
180 180 * If this is a shared object, the base address of the shared object is
181 181 * added to all address values defined within the object. Otherwise, if
182 182 * this is an executable, all object addresses are used as is.
183 183 */
184 184 if (ehdr->e_type == ET_EXEC)
185 185 base = 0;
186 186 else
187 187 base = (Addr)ehdr;
188 188
189 189 /* LINTED */
190 190 phdr = (Phdr *)((char *)ehdr + ehdr->e_phoff);
191 191 for (cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
192 192 if (phdr->p_type == PT_DYNAMIC) {
193 193 /* LINTED */
194 194 dyn = (Dyn *)((uintptr_t)phdr->p_vaddr + base);
195 195 dyncnt = phdr->p_filesz / sizeof (Dyn);
196 196 } else if (phdr->p_type == PT_SUNWCAP) {
197 197 /* LINTED */
198 198 cap = (Cap *)((uintptr_t)phdr->p_vaddr + base);
199 199 }
200 200 }
201 201
202 202 if (cap) {
203 203 /*
204 204 * From the .dynamic section, determine the associated string
205 205 * table. Required for CA_SUNW_MACH and CA_SUNW_PLAT
206 206 * processing.
207 207 */
208 208 while (dyn && dyncnt) {
209 209 if (dyn->d_tag == DT_NULL) {
210 210 break;
211 211 } else if (dyn->d_tag == DT_STRTAB) {
212 212 str = (char *)(dyn->d_un.d_ptr + base);
213 213 break;
214 214 }
215 215 dyn++, dyncnt--;
216 216 }
217 217 }
218 218
219 219 /*
220 220 * Establish any alternative capabilities, and validate this object
221 221 * if it defines it's own capabilities information.
222 222 */
223 223 return (cap_check_fdesc(fdp, cap, str, rej));
224 224 }
225 225
226 226 /*
227 227 * Determine if we have been given an ELF file and if so determine if the file
228 228 * is compatible. Returns 1 if true, else 0 and sets the reject descriptor
229 229 * with associated error information.
230 230 */
231 231 Fct *
232 232 elf_verify(caddr_t addr, size_t size, Fdesc *fdp, const char *name,
233 233 Rej_desc *rej)
234 234 {
235 235 Ehdr *ehdr;
236 236 char *caddr = (char *)addr;
237 237
238 238 /*
239 239 * Determine if we're an elf file. If not simply return, we don't set
240 240 * any rejection information as this test allows use to scroll through
241 241 * the objects we support (ELF, AOUT).
242 242 */
243 243 if (size < sizeof (Ehdr) ||
244 244 caddr[EI_MAG0] != ELFMAG0 ||
245 245 caddr[EI_MAG1] != ELFMAG1 ||
246 246 caddr[EI_MAG2] != ELFMAG2 ||
247 247 caddr[EI_MAG3] != ELFMAG3) {
248 248 return (NULL);
249 249 }
250 250
251 251 /*
252 252 * Check class and encoding.
253 253 */
254 254 /* LINTED */
255 255 ehdr = (Ehdr *)addr;
256 256 if (ehdr->e_ident[EI_CLASS] != M_CLASS) {
257 257 rej->rej_type = SGS_REJ_CLASS;
258 258 rej->rej_info = (uint_t)ehdr->e_ident[EI_CLASS];
259 259 return (NULL);
260 260 }
261 261 if (ehdr->e_ident[EI_DATA] != M_DATA) {
262 262 rej->rej_type = SGS_REJ_DATA;
263 263 rej->rej_info = (uint_t)ehdr->e_ident[EI_DATA];
264 264 return (NULL);
265 265 }
266 266 if ((ehdr->e_type != ET_REL) && (ehdr->e_type != ET_EXEC) &&
267 267 (ehdr->e_type != ET_DYN)) {
268 268 rej->rej_type = SGS_REJ_TYPE;
269 269 rej->rej_info = (uint_t)ehdr->e_type;
270 270 return (NULL);
271 271 }
272 272
273 273 /*
274 274 * Verify ELF version.
275 275 */
276 276 if (ehdr->e_version > EV_CURRENT) {
277 277 rej->rej_type = SGS_REJ_VERSION;
278 278 rej->rej_info = (uint_t)ehdr->e_version;
279 279 return (NULL);
280 280 }
281 281
282 282 /*
283 283 * Verify machine specific flags.
284 284 */
285 285 if (elf_mach_flags_check(rej, ehdr) == 0)
286 286 return (NULL);
287 287
288 288 /*
289 289 * Verify any capability requirements. Note, if this object is a shared
290 290 * object that is explicitly defined on the ldd(1) command line, and it
291 291 * contains an incompatible capabilities requirement, then inform the
292 292 * user, but continue processing.
293 293 */
294 294 if (elf_cap_check(fdp, ehdr, rej) == 0) {
295 295 Rt_map *lmp = lml_main.lm_head;
296 296
297 297 if ((lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) && lmp &&
298 298 (FLAGS1(lmp) & FL1_RT_LDDSTUB) && (NEXT(lmp) == NULL)) {
299 299 /* LINTED */
300 300 (void) printf(MSG_INTL(ldd_warn[rej->rej_type]), name,
301 301 rej->rej_str);
302 302 return (&elf_fct);
303 303 }
304 304 return (NULL);
305 305 }
306 306 return (&elf_fct);
307 307 }
308 308
309 309 /*
310 310 * The runtime linker employs lazy loading to provide the libraries needed for
311 311 * debugging, preloading .o's and dldump(). As these are seldom used, the
312 312 * standard startup of ld.so.1 doesn't initialize all the information necessary
313 313 * to perform plt relocation on ld.so.1's link-map. The first time lazy loading
314 314 * is called we get here to perform these initializations:
315 315 *
316 316 * - elf_needed() is called to establish any ld.so.1 dependencies. These
317 317 * dependencies should all be lazy loaded, so this routine is typically a
318 318 * no-op. However, we call elf_needed() for completeness, in case any
319 319 * NEEDED initialization is required.
320 320 *
321 321 * - For intel, ld.so.1's JMPSLOT relocations need relative updates. These
322 322 * are by default skipped thus delaying all relative relocation processing
323 323 * on every invocation of ld.so.1.
324 324 */
325 325 int
326 326 elf_rtld_load()
327 327 {
328 328 Lm_list *lml = &lml_rtld;
329 329 Rt_map *lmp = lml->lm_head;
330 330
331 331 if (lml->lm_flags & LML_FLG_PLTREL)
332 332 return (1);
333 333
334 334 if (elf_needed(lml, ALIST_OFF_DATA, lmp, NULL) == 0)
335 335 return (0);
336 336
337 337 #if defined(__i386)
338 338 /*
339 339 * This is a kludge to give ld.so.1 a performance benefit on i386.
340 340 * It's based around two factors.
341 341 *
342 342 * - JMPSLOT relocations (PLT's) actually need a relative relocation
343 343 * applied to the GOT entry so that they can find PLT0.
344 344 *
345 345 * - ld.so.1 does not exercise *any* PLT's before it has made a call
346 346 * to elf_lazy_load(). This is because all dynamic dependencies
347 347 * are recorded as lazy dependencies.
348 348 */
349 349 (void) elf_reloc_relative_count((ulong_t)JMPREL(lmp),
350 350 (ulong_t)(PLTRELSZ(lmp) / RELENT(lmp)), (ulong_t)RELENT(lmp),
351 351 (ulong_t)ADDR(lmp), lmp, NULL, 0);
352 352 #endif
353 353 lml->lm_flags |= LML_FLG_PLTREL;
354 354 return (1);
355 355 }
356 356
357 357 /*
358 358 * Lazy load an object.
359 359 */
360 360 Rt_map *
361 361 elf_lazy_load(Rt_map *clmp, Slookup *slp, uint_t ndx, const char *sym,
362 362 uint_t flags, Grp_hdl **hdl, int *in_nfavl)
363 363 {
364 364 Alist *palp = NULL;
365 365 Rt_map *nlmp;
366 366 Dyninfo *dip = &DYNINFO(clmp)[ndx], *pdip;
367 367 const char *name;
368 368 Lm_list *lml = LIST(clmp);
369 369 Aliste lmco;
370 370
371 371 /*
372 372 * If this dependency should be ignored, or has already been processed,
373 373 * we're done.
374 374 */
375 375 if (((nlmp = (Rt_map *)dip->di_info) != NULL) ||
376 376 (dip->di_flags & (FLG_DI_IGNORE | FLG_DI_LDD_DONE)))
377 377 return (nlmp);
378 378
379 379 /*
380 380 * If we're running under ldd(1), indicate that this dependency has been
381 381 * processed (see test above). It doesn't matter whether the object is
382 382 * successfully loaded or not, this flag simply ensures that we don't
383 383 * repeatedly attempt to load an object that has already failed to load.
384 384 * To do so would create multiple failure diagnostics for the same
385 385 * object under ldd(1).
386 386 */
387 387 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
388 388 dip->di_flags |= FLG_DI_LDD_DONE;
389 389
390 390 /*
391 391 * Determine the initial dependency name.
392 392 */
393 393 name = dip->di_name;
394 394 DBG_CALL(Dbg_file_lazyload(clmp, name, sym));
395 395
396 396 /*
397 397 * If this object needs to establish its own group, make sure a handle
398 398 * is created.
399 399 */
400 400 if (dip->di_flags & FLG_DI_GROUP)
401 401 flags |= (FLG_RT_SETGROUP | FLG_RT_PUBHDL);
402 402
403 403 /*
404 404 * Lazy dependencies are identified as DT_NEEDED entries with a
405 405 * DF_P1_LAZYLOAD flag in the previous DT_POSFLAG_1 element. The
406 406 * dynamic information element that corresponds to the DT_POSFLAG_1
407 407 * entry is free, and thus used to store the present entrance
408 408 * identifier. This identifier is used to prevent multiple attempts to
409 409 * load a failed lazy loadable dependency within the same runtime linker
410 410 * operation. However, future attempts to reload this dependency are
411 411 * still possible.
412 412 */
413 413 if (ndx && (pdip = dip - 1) && (pdip->di_flags & FLG_DI_POSFLAG1))
414 414 pdip->di_info = (void *)slp->sl_id;
415 415
416 416 /*
417 417 * Expand the requested name if necessary.
418 418 */
419 419 if (elf_fix_name(name, clmp, &palp, AL_CNT_NEEDED, 0) == 0)
420 420 return (NULL);
421 421
422 422 /*
423 423 * Establish a link-map control list for this request.
424 424 */
425 425 if ((lmco = create_cntl(lml, 0)) == NULL) {
426 426 remove_alist(&palp, 1);
427 427 return (NULL);
428 428 }
429 429
430 430 /*
431 431 * Load the associated object.
432 432 */
433 433 dip->di_info = nlmp =
434 434 load_one(lml, lmco, palp, clmp, MODE(clmp), flags, hdl, in_nfavl);
435 435
436 436 /*
437 437 * Remove any expanded pathname infrastructure. Reduce the pending lazy
438 438 * dependency count of the caller, together with the link-map lists
439 439 * count of objects that still have lazy dependencies pending.
440 440 */
441 441 remove_alist(&palp, 1);
442 442 if (--LAZY(clmp) == 0)
443 443 LIST(clmp)->lm_lazy--;
444 444
445 445 /*
446 446 * Finish processing the objects associated with this request, and
447 447 * create an association between the caller and this dependency.
448 448 */
449 449 if (nlmp && ((bind_one(clmp, nlmp, BND_NEEDED) == 0) ||
450 450 ((nlmp = analyze_lmc(lml, lmco, nlmp, clmp, in_nfavl)) == NULL) ||
451 451 (relocate_lmc(lml, lmco, clmp, nlmp, in_nfavl) == 0)))
452 452 dip->di_info = nlmp = NULL;
453 453
454 454 /*
455 455 * If this lazyload has failed, and we've created a new link-map
456 456 * control list to which this request has added objects, then remove
457 457 * all the objects that have been associated to this request.
458 458 */
459 459 if ((nlmp == NULL) && (lmco != ALIST_OFF_DATA))
460 460 remove_lmc(lml, clmp, lmco, name);
461 461
462 462 /*
463 463 * Remove any temporary link-map control list.
464 464 */
465 465 if (lmco != ALIST_OFF_DATA)
466 466 remove_cntl(lml, lmco);
467 467
468 468 /*
469 469 * If this lazy loading failed, record the fact, and bump the lazy
470 470 * counts.
471 471 */
472 472 if (nlmp == NULL) {
473 473 dip->di_flags |= FLG_DI_LAZYFAIL;
474 474 if (LAZY(clmp)++ == 0)
475 475 LIST(clmp)->lm_lazy++;
476 476 }
477 477
478 478 return (nlmp);
479 479 }
480 480
481 481 /*
482 482 * Return the entry point of the ELF executable.
483 483 */
484 484 static Addr
485 485 elf_entry_point(void)
486 486 {
487 487 Rt_map *lmp = lml_main.lm_head;
488 488 Ehdr *ehdr = (Ehdr *)ADDR(lmp);
489 489 Addr addr = (Addr)(ehdr->e_entry);
490 490
491 491 if ((FLAGS(lmp) & FLG_RT_FIXED) == 0)
492 492 addr += ADDR(lmp);
493 493
494 494 return (addr);
495 495 }
496 496
497 497 /*
498 498 * Determine if a dependency requires a particular version and if so verify
499 499 * that the version exists in the dependency.
500 500 */
501 501 int
502 502 elf_verify_vers(const char *name, Rt_map *clmp, Rt_map *nlmp)
503 503 {
504 504 Verneed *vnd = VERNEED(clmp);
505 505 int _num, num = VERNEEDNUM(clmp);
506 506 char *cstrs = (char *)STRTAB(clmp);
507 507 Lm_list *lml = LIST(clmp);
508 508
509 509 /*
510 510 * Traverse the callers version needed information and determine if any
511 511 * specific versions are required from the dependency.
512 512 */
513 513 DBG_CALL(Dbg_ver_need_title(LIST(clmp), NAME(clmp)));
514 514 for (_num = 1; _num <= num; _num++,
515 515 vnd = (Verneed *)((Xword)vnd + vnd->vn_next)) {
516 516 Half cnt = vnd->vn_cnt;
517 517 Vernaux *vnap;
518 518 char *nstrs, *need;
519 519
520 520 /*
521 521 * Determine if a needed entry matches this dependency.
522 522 */
523 523 need = (char *)(cstrs + vnd->vn_file);
524 524 if (strcmp(name, need) != 0)
525 525 continue;
526 526
527 527 if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) &&
528 528 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0))
529 529 (void) printf(MSG_INTL(MSG_LDD_VER_FIND), name);
530 530
531 531 /*
532 532 * Validate that each version required actually exists in the
533 533 * dependency.
534 534 */
535 535 nstrs = (char *)STRTAB(nlmp);
536 536
537 537 for (vnap = (Vernaux *)((Xword)vnd + vnd->vn_aux); cnt;
538 538 cnt--, vnap = (Vernaux *)((Xword)vnap + vnap->vna_next)) {
539 539 char *version, *define;
540 540 Verdef *vdf = VERDEF(nlmp);
541 541 ulong_t _num, num = VERDEFNUM(nlmp);
542 542 int found = 0;
543 543
544 544 /*
545 545 * Skip validation of versions that are marked
546 546 * INFO. This optimization is used for versions
547 547 * that are inherited by another version. Verification
548 548 * of the inheriting version is sufficient.
549 549 *
550 550 * Such versions are recorded in the object for the
551 551 * benefit of VERSYM entries that refer to them. This
552 552 * provides a purely diagnostic benefit.
553 553 */
554 554 if (vnap->vna_flags & VER_FLG_INFO)
555 555 continue;
556 556
557 557 version = (char *)(cstrs + vnap->vna_name);
558 558 DBG_CALL(Dbg_ver_need_entry(lml, 0, need, version));
559 559
560 560 for (_num = 1; _num <= num; _num++,
561 561 vdf = (Verdef *)((Xword)vdf + vdf->vd_next)) {
562 562 Verdaux *vdap;
563 563
564 564 if (vnap->vna_hash != vdf->vd_hash)
565 565 continue;
566 566
567 567 vdap = (Verdaux *)((Xword)vdf + vdf->vd_aux);
568 568 define = (char *)(nstrs + vdap->vda_name);
569 569 if (strcmp(version, define) != 0)
570 570 continue;
571 571
572 572 found++;
573 573 break;
574 574 }
575 575
576 576 /*
577 577 * If we're being traced print out any matched version
578 578 * when the verbose (-v) option is in effect. Always
579 579 * print any unmatched versions.
580 580 */
581 581 if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
582 582 /* BEGIN CSTYLED */
583 583 if (found) {
584 584 if (!(lml->lm_flags & LML_FLG_TRC_VERBOSE))
585 585 continue;
586 586
587 587 (void) printf(MSG_ORIG(MSG_LDD_VER_FOUND),
588 588 need, version, NAME(nlmp));
589 589 } else {
590 590 if (rtld_flags & RT_FL_SILENCERR)
591 591 continue;
592 592
593 593 (void) printf(MSG_INTL(MSG_LDD_VER_NFOUND),
594 594 need, version);
595 595 }
596 596 /* END CSTYLED */
597 597 continue;
598 598 }
599 599
600 600 /*
601 601 * If the version hasn't been found then this is a
602 602 * candidate for a fatal error condition. Weak
603 603 * version definition requirements are silently
604 604 * ignored. Also, if the image inspected for a version
605 605 * definition has no versioning recorded at all then
606 606 * silently ignore this (this provides better backward
607 607 * compatibility to old images created prior to
608 608 * versioning being available). Both of these skipped
609 609 * diagnostics are available under tracing (see above).
610 610 */
611 611 if ((found == 0) && (num != 0) &&
612 612 (!(vnap->vna_flags & VER_FLG_WEAK))) {
613 613 eprintf(lml, ERR_FATAL,
614 614 MSG_INTL(MSG_VER_NFOUND), need, version,
615 615 NAME(clmp));
616 616 return (0);
617 617 }
618 618 }
619 619 }
620 620 DBG_CALL(Dbg_ver_need_done(lml));
621 621 return (1);
622 622 }
623 623
624 624 /*
625 625 * Search through the dynamic section for DT_NEEDED entries and perform one
626 626 * of two functions. If only the first argument is specified then load the
627 627 * defined shared object, otherwise add the link map representing the defined
628 628 * link map the the dlopen list.
629 629 */
630 630 static int
631 631 elf_needed(Lm_list *lml, Aliste lmco, Rt_map *clmp, int *in_nfavl)
632 632 {
633 633 Alist *palp = NULL;
634 634 Dyn *dyn;
635 635 Dyninfo *dip;
636 636 Word lmflags = lml->lm_flags;
637 637
638 638 /*
639 639 * A DYNINFO() structure is created during link-map generation that
640 640 * parallels the DYN() information, and defines any flags that
641 641 * influence a dependencies loading.
642 642 */
643 643 for (dyn = DYN(clmp), dip = DYNINFO(clmp);
644 644 !(dip->di_flags & FLG_DI_IGNORE); dyn++, dip++) {
645 645 uint_t flags = 0, silent = 0;
646 646 const char *name = dip->di_name;
647 647 Rt_map *nlmp = NULL;
648 648
649 649 if ((dip->di_flags & FLG_DI_NEEDED) == 0)
650 650 continue;
651 651
652 652 /*
653 653 * Skip any deferred dependencies, unless ldd(1) has forced
654 654 * their processing. By default, deferred dependencies are
655 655 * only processed when an explicit binding to an individual
656 656 * deferred reference is made.
657 657 */
658 658 if ((dip->di_flags & FLG_DI_DEFERRED) &&
659 659 ((rtld_flags & RT_FL_DEFERRED) == 0))
660 660 continue;
661 661
662 662 /*
663 663 * NOTE, libc.so.1 can't be lazy loaded. Although a lazy
664 664 * position flag won't be produced when a RTLDINFO .dynamic
665 665 * entry is found (introduced with the UPM in Solaris 10), it
666 666 * was possible to mark libc for lazy loading on previous
667 667 * releases. To reduce the overhead of testing for this
668 668 * occurrence, only carry out this check for the first object
669 669 * on the link-map list (there aren't many applications built
670 670 * without libc).
671 671 */
672 672 if ((dip->di_flags & FLG_DI_LAZY) && (lml->lm_head == clmp) &&
673 673 (strcmp(name, MSG_ORIG(MSG_FIL_LIBC)) == 0))
674 674 dip->di_flags &= ~FLG_DI_LAZY;
675 675
676 676 /*
677 677 * Don't bring in lazy loaded objects yet unless we've been
678 678 * asked to attempt to load all available objects (crle(1) sets
679 679 * LD_FLAGS=loadavail). Even under RTLD_NOW we don't process
680 680 * this - RTLD_NOW will cause relocation processing which in
681 681 * turn might trigger lazy loading, but its possible that the
682 682 * object has a lazy loaded file with no bindings (i.e., it
683 683 * should never have been a dependency in the first place).
684 684 */
685 685 if (dip->di_flags & FLG_DI_LAZY) {
686 686 if ((lmflags & LML_FLG_LOADAVAIL) == 0) {
687 687 LAZY(clmp)++;
688 688 continue;
689 689 }
690 690
691 691 /*
692 692 * Silence any error messages - see description under
693 693 * elf_lookup_filtee().
694 694 */
695 695 if ((rtld_flags & RT_FL_SILENCERR) == 0) {
696 696 rtld_flags |= RT_FL_SILENCERR;
697 697 silent = 1;
698 698 }
699 699 }
700 700
701 701 DBG_CALL(Dbg_file_needed(clmp, name));
702 702
703 703 /*
704 704 * If we're running under ldd(1), indicate that this dependency
705 705 * has been processed. It doesn't matter whether the object is
706 706 * successfully loaded or not, this flag simply ensures that we
707 707 * don't repeatedly attempt to load an object that has already
708 708 * failed to load. To do so would create multiple failure
709 709 * diagnostics for the same object under ldd(1).
710 710 */
711 711 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
712 712 dip->di_flags |= FLG_DI_LDD_DONE;
713 713
714 714 /*
715 715 * Identify any group permission requirements.
716 716 */
717 717 if (dip->di_flags & FLG_DI_GROUP)
718 718 flags = (FLG_RT_SETGROUP | FLG_RT_PUBHDL);
719 719
720 720 /*
721 721 * Establish the objects name, load it and establish a binding
722 722 * with the caller.
723 723 */
724 724 if ((elf_fix_name(name, clmp, &palp, AL_CNT_NEEDED, 0) == 0) ||
725 725 ((nlmp = load_one(lml, lmco, palp, clmp, MODE(clmp),
726 726 flags, 0, in_nfavl)) == NULL) ||
727 727 (bind_one(clmp, nlmp, BND_NEEDED) == 0))
728 728 nlmp = NULL;
729 729
730 730 /*
731 731 * Clean up any infrastructure, including the removal of the
732 732 * error suppression state, if it had been previously set in
733 733 * this routine.
734 734 */
735 735 remove_alist(&palp, 0);
736 736
737 737 if (silent)
738 738 rtld_flags &= ~RT_FL_SILENCERR;
739 739
740 740 if ((dip->di_info = (void *)nlmp) == NULL) {
741 741 /*
742 742 * If the object could not be mapped, continue if error
743 743 * suppression is established or we're here with ldd(1).
744 744 */
745 745 if ((MODE(clmp) & RTLD_CONFGEN) || (lmflags &
746 746 (LML_FLG_LOADAVAIL | LML_FLG_TRC_ENABLE)))
747 747 continue;
748 748 else {
749 749 remove_alist(&palp, 1);
750 750 return (0);
751 751 }
752 752 }
753 753 }
754 754
755 755 if (LAZY(clmp))
756 756 lml->lm_lazy++;
757 757
758 758 remove_alist(&palp, 1);
759 759 return (1);
760 760 }
761 761
762 762 /*
763 763 * A null symbol interpretor. Used if a filter has no associated filtees.
764 764 */
765 765 /* ARGSUSED0 */
766 766 static int
767 767 elf_null_find_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
768 768 {
769 769 return (0);
770 770 }
771 771
772 772 /*
773 773 * Disable filtee use.
774 774 */
775 775 static void
776 776 elf_disable_filtee(Rt_map *lmp, Dyninfo *dip)
777 777 {
778 778 if ((dip->di_flags & FLG_DI_SYMFLTR) == 0) {
779 779 /*
780 780 * If this is an object filter, null out the reference name.
781 781 */
782 782 if (OBJFLTRNDX(lmp) != FLTR_DISABLED) {
783 783 REFNAME(lmp) = NULL;
784 784 OBJFLTRNDX(lmp) = FLTR_DISABLED;
785 785
786 786 /*
787 787 * Indicate that this filtee is no longer available.
788 788 */
789 789 if (dip->di_flags & FLG_DI_STDFLTR)
790 790 SYMINTP(lmp) = elf_null_find_sym;
791 791
792 792 }
793 793 } else if (dip->di_flags & FLG_DI_STDFLTR) {
794 794 /*
795 795 * Indicate that this standard filtee is no longer available.
796 796 */
797 797 if (SYMSFLTRCNT(lmp))
798 798 SYMSFLTRCNT(lmp)--;
799 799 } else {
800 800 /*
801 801 * Indicate that this auxiliary filtee is no longer available.
802 802 */
803 803 if (SYMAFLTRCNT(lmp))
804 804 SYMAFLTRCNT(lmp)--;
805 805 }
806 806 dip->di_flags &= ~MSK_DI_FILTER;
807 807 }
808 808
809 809 /*
810 810 * Find symbol interpreter - filters.
811 811 * This function is called when the symbols from a shared object should
812 812 * be resolved from the shared objects filtees instead of from within itself.
813 813 *
814 814 * A symbol name of 0 is used to trigger filtee loading.
815 815 */
816 816 static int
817 817 _elf_lookup_filtee(Slookup *slp, Sresult *srp, uint_t *binfo, uint_t ndx,
818 818 int *in_nfavl)
819 819 {
820 820 const char *name = slp->sl_name, *filtees;
821 821 Rt_map *clmp = slp->sl_cmap;
822 822 Rt_map *ilmp = slp->sl_imap;
823 823 Pdesc *pdp;
824 824 int any;
825 825 Dyninfo *dip = &DYNINFO(ilmp)[ndx];
826 826 Lm_list *lml = LIST(ilmp);
827 827 Aliste idx;
828 828
829 829 /*
830 830 * Indicate that the filter has been used. If a binding already exists
831 831 * to the caller, indicate that this object is referenced. This insures
832 832 * we don't generate false unreferenced diagnostics from ldd -u/U or
833 833 * debugging. Don't create a binding regardless, as this filter may
834 834 * have been dlopen()'ed.
835 835 */
836 836 if (name && (ilmp != clmp)) {
837 837 Word tracing = (LIST(clmp)->lm_flags &
838 838 (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED));
839 839
840 840 if (tracing || DBG_ENABLED) {
841 841 Bnd_desc *bdp;
842 842 Aliste idx;
843 843
844 844 FLAGS1(ilmp) |= FL1_RT_USED;
845 845
846 846 if ((tracing & LML_FLG_TRC_UNREF) || DBG_ENABLED) {
847 847 for (APLIST_TRAVERSE(CALLERS(ilmp), idx, bdp)) {
848 848 if (bdp->b_caller == clmp) {
849 849 bdp->b_flags |= BND_REFER;
850 850 break;
851 851 }
852 852 }
853 853 }
854 854 }
855 855 }
856 856
857 857 /*
858 858 * If this is the first call to process this filter, establish the
859 859 * filtee list. If a configuration file exists, determine if any
860 860 * filtee associations for this filter, and its filtee reference, are
861 861 * defined. Otherwise, process the filtee reference. Any token
862 862 * expansion is also completed at this point (i.e., $PLATFORM).
863 863 */
864 864 filtees = dip->di_name;
865 865 if (dip->di_info == NULL) {
866 866 if (rtld_flags2 & RT_FL2_FLTCFG) {
867 867 elf_config_flt(lml, PATHNAME(ilmp), filtees,
868 868 (Alist **)&dip->di_info, AL_CNT_FILTEES);
869 869 }
870 870 if (dip->di_info == NULL) {
871 871 DBG_CALL(Dbg_file_filter(lml, NAME(ilmp), filtees, 0));
872 872 if ((lml->lm_flags &
873 873 (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) &&
874 874 ((FLAGS1(ilmp) & FL1_RT_LDDSTUB) == 0))
875 875 (void) printf(MSG_INTL(MSG_LDD_FIL_FILTER),
876 876 NAME(ilmp), filtees);
877 877
878 878 if (expand_paths(ilmp, filtees, (Alist **)&dip->di_info,
879 879 AL_CNT_FILTEES, 0, 0) == 0) {
880 880 elf_disable_filtee(ilmp, dip);
881 881 return (0);
882 882 }
883 883 }
884 884 }
885 885
886 886 /*
887 887 * Traverse the filtee list, dlopen()'ing any objects specified and
888 888 * using their group handle to lookup the symbol.
889 889 */
890 890 any = 0;
891 891 for (ALIST_TRAVERSE((Alist *)dip->di_info, idx, pdp)) {
892 892 int mode;
893 893 Grp_hdl *ghp;
894 894 Rt_map *nlmp = NULL;
895 895
896 896 if (pdp->pd_plen == 0)
897 897 continue;
898 898
899 899 /*
900 900 * Establish the mode of the filtee from the filter. As filtees
901 901 * are loaded via a dlopen(), make sure that RTLD_GROUP is set
902 902 * and the filtees aren't global. It would be nice to have
903 903 * RTLD_FIRST used here also, but as filters got out long before
904 904 * RTLD_FIRST was introduced it's a little too late now.
905 905 */
906 906 mode = MODE(ilmp) | RTLD_GROUP;
907 907 mode &= ~RTLD_GLOBAL;
908 908
909 909 /*
910 910 * Insure that any auxiliary filter can locate symbols from its
911 911 * caller.
912 912 */
913 913 if (dip->di_flags & FLG_DI_AUXFLTR)
914 914 mode |= RTLD_PARENT;
915 915
916 916 /*
917 917 * Process any capability directory. Establish a new link-map
918 918 * control list from which to analyze any newly added objects.
919 919 */
920 920 if ((pdp->pd_info == NULL) && (pdp->pd_flags & PD_TKN_CAP)) {
921 921 const char *dir = pdp->pd_pname;
922 922 Aliste lmco;
923 923
924 924 /*
925 925 * Establish a link-map control list for this request.
926 926 */
927 927 if ((lmco = create_cntl(lml, 0)) == NULL)
928 928 return (NULL);
929 929
930 930 /*
931 931 * Determine the capability filtees. If none can be
932 932 * found, provide suitable diagnostics.
933 933 */
934 934 DBG_CALL(Dbg_cap_filter(lml, dir, ilmp));
935 935 if (cap_filtees((Alist **)&dip->di_info, idx, dir,
936 936 lmco, ilmp, clmp, filtees, mode,
937 937 (FLG_RT_PUBHDL | FLG_RT_CAP), in_nfavl) == 0) {
938 938 if ((lml->lm_flags & LML_FLG_TRC_ENABLE) &&
939 939 (dip->di_flags & FLG_DI_AUXFLTR) &&
940 940 (rtld_flags & RT_FL_WARNFLTR)) {
941 941 (void) printf(
942 942 MSG_INTL(MSG_LDD_CAP_NFOUND), dir);
943 943 }
944 944 DBG_CALL(Dbg_cap_filter(lml, dir, 0));
945 945 }
946 946
947 947 /*
948 948 * Re-establish the originating path name descriptor,
949 949 * as the expansion of capabilities filtees may have
950 950 * re-allocated the controlling Alist. Mark this
951 951 * original pathname descriptor as unused so that the
952 952 * descriptor isn't revisited for processing. Any real
953 953 * capabilities filtees have been added as new pathname
954 954 * descriptors following this descriptor.
955 955 */
956 956 pdp = alist_item((Alist *)dip->di_info, idx);
957 957 pdp->pd_flags &= ~PD_TKN_CAP;
958 958 pdp->pd_plen = 0;
959 959
960 960 /*
961 961 * Now that any capability objects have been processed,
962 962 * remove any temporary link-map control list.
963 963 */
964 964 if (lmco != ALIST_OFF_DATA)
965 965 remove_cntl(lml, lmco);
966 966 }
967 967
968 968 if (pdp->pd_plen == 0)
969 969 continue;
970 970
971 971 /*
972 972 * Process an individual filtee.
973 973 */
974 974 if (pdp->pd_info == NULL) {
975 975 const char *filtee = pdp->pd_pname;
976 976 int audit = 0;
977 977
978 978 DBG_CALL(Dbg_file_filtee(lml, NAME(ilmp), filtee, 0));
979 979
980 980 ghp = NULL;
981 981
982 982 /*
983 983 * Determine if the reference link map is already
984 984 * loaded. As an optimization compare the filtee with
985 985 * our interpretor. The most common filter is
986 986 * libdl.so.1, which is a filter on ld.so.1.
987 987 */
988 988 #if defined(_ELF64)
989 989 if (strcmp(filtee, MSG_ORIG(MSG_PTH_RTLD_64)) == 0) {
990 990 #else
991 991 if (strcmp(filtee, MSG_ORIG(MSG_PTH_RTLD)) == 0) {
992 992 #endif
993 993 uint_t hflags, rdflags, cdflags;
994 994
995 995 /*
996 996 * Establish any flags for the handle (Grp_hdl).
997 997 *
998 998 * - This is a special, public, ld.so.1
999 999 * handle.
1000 1000 * - Only the first object on this handle
1001 1001 * can supply symbols.
1002 1002 * - This handle provides a filtee.
1003 1003 *
1004 1004 * Essentially, this handle allows a caller to
1005 1005 * reference the dl*() family of interfaces from
1006 1006 * ld.so.1.
1007 1007 */
1008 1008 hflags = (GPH_PUBLIC | GPH_LDSO |
1009 1009 GPH_FIRST | GPH_FILTEE);
1010 1010
1011 1011 /*
1012 1012 * Establish the flags for the referenced
1013 1013 * dependency descriptor (Grp_desc).
1014 1014 *
1015 1015 * - ld.so.1 is available for dlsym().
1016 1016 * - ld.so.1 is available to relocate
1017 1017 * against.
1018 1018 * - There's no need to add an dependencies
1019 1019 * to this handle.
1020 1020 */
1021 1021 rdflags = (GPD_DLSYM | GPD_RELOC);
1022 1022
1023 1023 /*
1024 1024 * Establish the flags for this callers
1025 1025 * dependency descriptor (Grp_desc).
1026 1026 *
1027 1027 * - The explicit creation of a handle
1028 1028 * creates a descriptor for the referenced
1029 1029 * object and the parent (caller).
1030 1030 */
1031 1031 cdflags = GPD_PARENT;
1032 1032
1033 1033 nlmp = lml_rtld.lm_head;
1034 1034 if ((ghp = hdl_create(&lml_rtld, nlmp, ilmp,
1035 1035 hflags, rdflags, cdflags)) == NULL)
1036 1036 nlmp = NULL;
1037 1037
1038 1038 /*
1039 1039 * Establish the filter handle to prevent any
1040 1040 * recursion.
1041 1041 */
1042 1042 if (nlmp && ghp)
1043 1043 pdp->pd_info = (void *)ghp;
1044 1044
1045 1045 /*
1046 1046 * Audit the filter/filtee established. Ignore
1047 1047 * any return from the auditor, as we can't
1048 1048 * allow ignore filtering to ld.so.1, otherwise
1049 1049 * nothing is going to work.
1050 1050 */
1051 1051 if (nlmp && ((lml->lm_tflags | AFLAGS(ilmp)) &
1052 1052 LML_TFLG_AUD_OBJFILTER))
1053 1053 (void) audit_objfilter(ilmp, filtees,
1054 1054 nlmp, 0);
1055 1055
1056 1056 } else {
1057 1057 Rej_desc rej = { 0 };
1058 1058 Fdesc fd = { 0 };
1059 1059 Aliste lmco;
1060 1060
1061 1061 /*
1062 1062 * Trace the inspection of this file, determine
1063 1063 * any auditor substitution, and seed the file
1064 1064 * descriptor with the originating name.
1065 1065 */
1066 1066 if (load_trace(lml, pdp, clmp, &fd) == NULL)
1067 1067 continue;
1068 1068
1069 1069 /*
1070 1070 * Establish a link-map control list for this
1071 1071 * request.
1072 1072 */
1073 1073 if ((lmco = create_cntl(lml, 0)) == NULL)
1074 1074 return (NULL);
1075 1075
1076 1076 /*
1077 1077 * Locate and load the filtee.
1078 1078 */
1079 1079 if ((nlmp = load_path(lml, lmco, ilmp, mode,
1080 1080 FLG_RT_PUBHDL, &ghp, &fd, &rej,
1081 1081 in_nfavl)) == NULL)
1082 1082 file_notfound(LIST(ilmp), filtee, ilmp,
1083 1083 FLG_RT_PUBHDL, &rej);
1084 1084
1085 1085 filtee = pdp->pd_pname;
1086 1086
1087 1087 /*
1088 1088 * Establish the filter handle to prevent any
1089 1089 * recursion.
1090 1090 */
1091 1091 if (nlmp && ghp) {
1092 1092 ghp->gh_flags |= GPH_FILTEE;
1093 1093 pdp->pd_info = (void *)ghp;
1094 1094
1095 1095 FLAGS1(nlmp) |= FL1_RT_USED;
1096 1096 }
1097 1097
1098 1098 /*
1099 1099 * Audit the filter/filtee established. A
1100 1100 * return of 0 indicates the auditor wishes to
1101 1101 * ignore this filtee.
1102 1102 */
1103 1103 if (nlmp && ((lml->lm_tflags | FLAGS1(ilmp)) &
1104 1104 LML_TFLG_AUD_OBJFILTER)) {
1105 1105 if (audit_objfilter(ilmp, filtees,
1106 1106 nlmp, 0) == 0) {
1107 1107 audit = 1;
1108 1108 nlmp = NULL;
1109 1109 }
1110 1110 }
1111 1111
1112 1112 /*
1113 1113 * Finish processing the objects associated with
1114 1114 * this request. Create an association between
1115 1115 * this object and the originating filter to
1116 1116 * provide sufficient information to tear down
1117 1117 * this filtee if necessary.
1118 1118 */
1119 1119 if (nlmp && ghp && (((nlmp = analyze_lmc(lml,
1120 1120 lmco, nlmp, clmp, in_nfavl)) == NULL) ||
1121 1121 (relocate_lmc(lml, lmco, ilmp, nlmp,
1122 1122 in_nfavl) == 0)))
1123 1123 nlmp = NULL;
1124 1124
1125 1125 /*
1126 1126 * If the filtee has been successfully
1127 1127 * processed, then create an association
1128 1128 * between the filter and filtee. This
1129 1129 * association provides sufficient information
1130 1130 * to tear down the filter and filtee if
1131 1131 * necessary.
1132 1132 */
1133 1133 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
1134 1134 if (nlmp && ghp && (hdl_add(ghp, ilmp,
1135 1135 GPD_FILTER, NULL) == NULL))
1136 1136 nlmp = NULL;
1137 1137
1138 1138 /*
1139 1139 * Generate a diagnostic if the filtee couldn't
1140 1140 * be loaded.
1141 1141 */
1142 1142 if (nlmp == NULL)
1143 1143 DBG_CALL(Dbg_file_filtee(lml, 0, filtee,
1144 1144 audit));
1145 1145
1146 1146 /*
1147 1147 * If this filtee loading has failed, and we've
1148 1148 * created a new link-map control list to which
1149 1149 * this request has added objects, then remove
1150 1150 * all the objects that have been associated to
1151 1151 * this request.
1152 1152 */
1153 1153 if ((nlmp == NULL) && (lmco != ALIST_OFF_DATA))
1154 1154 remove_lmc(lml, clmp, lmco, name);
1155 1155
1156 1156 /*
1157 1157 * Remove any temporary link-map control list.
1158 1158 */
1159 1159 if (lmco != ALIST_OFF_DATA)
1160 1160 remove_cntl(lml, lmco);
1161 1161 }
1162 1162
1163 1163 /*
1164 1164 * If the filtee couldn't be loaded, null out the
1165 1165 * path name descriptor entry, and continue the search.
1166 1166 * Otherwise, the group handle is retained for future
1167 1167 * symbol searches.
1168 1168 */
1169 1169 if (nlmp == NULL) {
1170 1170 pdp->pd_info = NULL;
1171 1171 pdp->pd_plen = 0;
1172 1172 continue;
1173 1173 }
1174 1174 }
1175 1175
1176 1176 ghp = (Grp_hdl *)pdp->pd_info;
1177 1177
1178 1178 /*
1179 1179 * If name is NULL, we're here to trigger filtee loading.
1180 1180 * Skip the symbol lookup so that we'll continue looking for
1181 1181 * additional filtees.
1182 1182 */
1183 1183 if (name) {
1184 1184 Grp_desc *gdp;
1185 1185 int ret = 0;
1186 1186 Aliste idx;
1187 1187 Slookup sl = *slp;
1188 1188
1189 1189 sl.sl_flags |= (LKUP_FIRST | LKUP_DLSYM);
1190 1190 any++;
1191 1191
1192 1192 /*
1193 1193 * Look for the symbol in the handles dependencies.
1194 1194 */
1195 1195 for (ALIST_TRAVERSE(ghp->gh_depends, idx, gdp)) {
1196 1196 if ((gdp->gd_flags & GPD_DLSYM) == 0)
1197 1197 continue;
1198 1198
1199 1199 /*
1200 1200 * If our parent is a dependency don't look at
1201 1201 * it (otherwise we are in a recursive loop).
1202 1202 * This situation can occur with auxiliary
1203 1203 * filters if the filtee has a dependency on the
1204 1204 * filter. This dependency isn't necessary as
1205 1205 * auxiliary filters are opened RTLD_PARENT, but
1206 1206 * users may still unknowingly add an explicit
1207 1207 * dependency to the parent.
1208 1208 */
1209 1209 if ((sl.sl_imap = gdp->gd_depend) == ilmp)
1210 1210 continue;
1211 1211
1212 1212 if (((ret = SYMINTP(sl.sl_imap)(&sl, srp, binfo,
1213 1213 in_nfavl)) != 0) ||
1214 1214 (ghp->gh_flags & GPH_FIRST))
1215 1215 break;
1216 1216 }
1217 1217
1218 1218 /*
1219 1219 * If a symbol has been found, indicate the binding
1220 1220 * and return the symbol.
1221 1221 */
1222 1222 if (ret) {
1223 1223 *binfo |= DBG_BINFO_FILTEE;
1224 1224 return (1);
1225 1225 }
1226 1226 }
1227 1227
1228 1228 /*
1229 1229 * If this object is tagged to terminate filtee processing we're
1230 1230 * done.
1231 1231 */
1232 1232 if (FLAGS1(ghp->gh_ownlmp) & FL1_RT_ENDFILTE)
1233 1233 break;
1234 1234 }
1235 1235
1236 1236 /*
1237 1237 * If we're just here to trigger filtee loading then we're done.
1238 1238 */
1239 1239 if (name == NULL)
1240 1240 return (0);
1241 1241
1242 1242 /*
1243 1243 * If no filtees have been found for a filter, clean up any path name
1244 1244 * descriptors and disable their search completely. For auxiliary
1245 1245 * filters we can reselect the symbol search function so that we never
1246 1246 * enter this routine again for this object. For standard filters we
1247 1247 * use the null symbol routine.
1248 1248 */
1249 1249 if (any == 0) {
1250 1250 remove_alist((Alist **)&(dip->di_info), 1);
1251 1251 elf_disable_filtee(ilmp, dip);
1252 1252 }
1253 1253
1254 1254 return (0);
1255 1255 }
1256 1256
1257 1257 /*
1258 1258 * Focal point for disabling error messages for auxiliary filters. As an
1259 1259 * auxiliary filter allows for filtee use, but provides a fallback should a
1260 1260 * filtee not exist (or fail to load), any errors generated as a consequence of
1261 1261 * trying to load the filtees are typically suppressed. Setting RT_FL_SILENCERR
1262 1262 * suppresses errors generated by eprintf(), but ensures a debug diagnostic is
1263 1263 * produced. ldd(1) employs printf(), and here the selection of whether to
1264 1264 * print a diagnostic in regards to auxiliary filters is a little more complex.
1265 1265 *
1266 1266 * - The determination of whether to produce an ldd message, or a fatal
1267 1267 * error message is driven by LML_FLG_TRC_ENABLE.
1268 1268 * - More detailed ldd messages may also be driven off of LML_FLG_TRC_WARN,
1269 1269 * (ldd -d/-r), LML_FLG_TRC_VERBOSE (ldd -v), LML_FLG_TRC_SEARCH (ldd -s),
1270 1270 * and LML_FLG_TRC_UNREF/LML_FLG_TRC_UNUSED (ldd -U/-u).
1271 1271 * - If the calling object is lddstub, then several classes of message are
1272 1272 * suppressed. The user isn't trying to diagnose lddstub, this is simply
1273 1273 * a stub executable employed to preload a user specified library against.
1274 1274 * - If RT_FL_SILENCERR is in effect then any generic ldd() messages should
1275 1275 * be suppressed. All detailed ldd messages should still be produced.
1276 1276 */
1277 1277 int
1278 1278 elf_lookup_filtee(Slookup *slp, Sresult *srp, uint_t *binfo, uint_t ndx,
1279 1279 int *in_nfavl)
1280 1280 {
1281 1281 Dyninfo *dip = &DYNINFO(slp->sl_imap)[ndx];
1282 1282 int ret, silent = 0;
1283 1283
1284 1284 /*
1285 1285 * Make sure this entry is still acting as a filter. We may have tried
1286 1286 * to process this previously, and disabled it if the filtee couldn't
1287 1287 * be processed. However, other entries may provide different filtees
1288 1288 * that are yet to be completed.
1289 1289 */
1290 1290 if (dip->di_flags == 0)
1291 1291 return (0);
1292 1292
1293 1293 /*
1294 1294 * Indicate whether an error message is required should this filtee not
1295 1295 * be found, based on the type of filter.
1296 1296 */
1297 1297 if ((dip->di_flags & FLG_DI_AUXFLTR) &&
1298 1298 ((rtld_flags & (RT_FL_WARNFLTR | RT_FL_SILENCERR)) == 0)) {
1299 1299 rtld_flags |= RT_FL_SILENCERR;
1300 1300 silent = 1;
1301 1301 }
1302 1302
1303 1303 ret = _elf_lookup_filtee(slp, srp, binfo, ndx, in_nfavl);
1304 1304
1305 1305 if (silent)
1306 1306 rtld_flags &= ~RT_FL_SILENCERR;
1307 1307
1308 1308 return (ret);
1309 1309 }
1310 1310
1311 1311 /*
1312 1312 * Compute the elf hash value (as defined in the ELF access library).
1313 1313 * The form of the hash table is:
1314 1314 *
1315 1315 * |--------------|
1316 1316 * | # of buckets |
1317 1317 * |--------------|
1318 1318 * | # of chains |
1319 1319 * |--------------|
1320 1320 * | bucket[] |
1321 1321 * |--------------|
1322 1322 * | chain[] |
1323 1323 * |--------------|
1324 1324 */
1325 1325 ulong_t
1326 1326 elf_hash(const char *name)
1327 1327 {
1328 1328 uint_t hval = 0;
1329 1329
1330 1330 while (*name) {
1331 1331 uint_t g;
1332 1332 hval = (hval << 4) + *name++;
1333 1333 if ((g = (hval & 0xf0000000)) != 0)
1334 1334 hval ^= g >> 24;
1335 1335 hval &= ~g;
1336 1336 }
1337 1337 return ((ulong_t)hval);
1338 1338 }
1339 1339
1340 1340 /*
1341 1341 * Look up a symbol. The callers lookup information is passed in the Slookup
1342 1342 * structure, and any resultant binding information is returned in the Sresult
1343 1343 * structure.
1344 1344 */
1345 1345 int
1346 1346 elf_find_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
1347 1347 {
1348 1348 const char *name = slp->sl_name;
1349 1349 Rt_map *ilmp = slp->sl_imap;
1350 1350 ulong_t hash = slp->sl_hash;
1351 1351 uint_t ndx, hashoff, buckets, *chainptr;
1352 1352 Sym *sym, *symtabptr;
1353 1353 char *strtabptr, *strtabname;
1354 1354 uint_t flags1;
1355 1355 Syminfo *sip;
1356 1356
1357 1357 /*
1358 1358 * If we're only here to establish a symbols index, skip the diagnostic
1359 1359 * used to trace a symbol search.
1360 1360 */
1361 1361 if ((slp->sl_flags & LKUP_SYMNDX) == 0)
1362 1362 DBG_CALL(Dbg_syms_lookup(ilmp, name, MSG_ORIG(MSG_STR_ELF)));
1363 1363
1364 1364 if (HASH(ilmp) == NULL)
1365 1365 return (0);
1366 1366
1367 1367 buckets = HASH(ilmp)[0];
1368 1368 /* LINTED */
1369 1369 hashoff = ((uint_t)hash % buckets) + 2;
1370 1370
1371 1371 /*
1372 1372 * Get the first symbol from the hash chain and initialize the string
1373 1373 * and symbol table pointers.
1374 1374 */
1375 1375 if ((ndx = HASH(ilmp)[hashoff]) == 0)
1376 1376 return (0);
1377 1377
1378 1378 chainptr = HASH(ilmp) + 2 + buckets;
1379 1379 strtabptr = STRTAB(ilmp);
1380 1380 symtabptr = SYMTAB(ilmp);
1381 1381
1382 1382 while (ndx) {
1383 1383 sym = symtabptr + ndx;
1384 1384 strtabname = strtabptr + sym->st_name;
1385 1385
1386 1386 /*
1387 1387 * Compare the symbol found with the name required. If the
1388 1388 * names don't match continue with the next hash entry.
1389 1389 */
1390 1390 if ((*strtabname++ != *name) || strcmp(strtabname, &name[1])) {
1391 1391 hashoff = ndx + buckets + 2;
1392 1392 if ((ndx = chainptr[ndx]) != 0)
1393 1393 continue;
1394 1394 return (0);
1395 1395 }
1396 1396
1397 1397 /*
1398 1398 * Symbols that are defined as hidden within an object usually
1399 1399 * have any references from within the same object bound at
1400 1400 * link-edit time, thus ld.so.1 is not involved. However, if
1401 1401 * these are capabilities symbols, then references to them must
1402 1402 * be resolved at runtime. A hidden symbol can only be bound
1403 1403 * to by the object that defines the symbol.
1404 1404 */
1405 1405 if ((sym->st_shndx != SHN_UNDEF) &&
1406 1406 (ELF_ST_VISIBILITY(sym->st_other) == STV_HIDDEN) &&
1407 1407 (slp->sl_cmap != ilmp))
1408 1408 return (0);
1409 1409
1410 1410 /*
1411 1411 * The Solaris ld does not put DT_VERSYM in the dynamic
1412 1412 * section, but the GNU ld does. The GNU runtime linker
1413 1413 * interprets the top bit of the 16-bit Versym value
1414 1414 * (0x8000) as the "hidden" bit. If this bit is set,
1415 1415 * the linker is supposed to act as if that symbol does
1416 1416 * not exist. The hidden bit supports their versioning
1417 1417 * scheme, which allows multiple incompatible functions
1418 1418 * with the same name to exist at different versions
1419 1419 * within an object. The Solaris linker does not support this
1420 1420 * mechanism, or the model of interface evolution that
1421 1421 * it allows, but we honor the hidden bit in GNU ld
1422 1422 * produced objects in order to interoperate with them.
1423 1423 */
1424 1424 if (VERSYM(ilmp) && (VERSYM(ilmp)[ndx] & 0x8000)) {
1425 1425 DBG_CALL(Dbg_syms_ignore_gnuver(ilmp, name,
1426 1426 ndx, VERSYM(ilmp)[ndx]));
1427 1427 return (0);
1428 1428 }
1429 1429
1430 1430 /*
1431 1431 * If we're only here to establish a symbol's index, we're done.
1432 1432 */
1433 1433 if (slp->sl_flags & LKUP_SYMNDX) {
1434 1434 srp->sr_dmap = ilmp;
1435 1435 srp->sr_sym = sym;
1436 1436 return (1);
1437 1437 }
1438 1438
1439 1439 /*
1440 1440 * If we find a match and the symbol is defined, capture the
1441 1441 * symbol pointer and the link map in which it was found.
1442 1442 */
1443 1443 if (sym->st_shndx != SHN_UNDEF) {
1444 1444 srp->sr_dmap = ilmp;
1445 1445 srp->sr_sym = sym;
1446 1446 *binfo |= DBG_BINFO_FOUND;
1447 1447
1448 1448 if ((FLAGS(ilmp) & FLG_RT_OBJINTPO) ||
1449 1449 ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
1450 1450 is_sym_interposer(ilmp, sym)))
1451 1451 *binfo |= DBG_BINFO_INTERPOSE;
1452 1452 break;
1453 1453
1454 1454 /*
1455 1455 * If we find a match and the symbol is undefined, the
1456 1456 * symbol type is a function, and the value of the symbol
1457 1457 * is non zero, then this is a special case. This allows
1458 1458 * the resolution of a function address to the plt[] entry.
1459 1459 * See SPARC ABI, Dynamic Linking, Function Addresses for
1460 1460 * more details.
1461 1461 */
1462 1462 } else if ((slp->sl_flags & LKUP_SPEC) &&
1463 1463 (FLAGS(ilmp) & FLG_RT_ISMAIN) && (sym->st_value != 0) &&
1464 1464 (ELF_ST_TYPE(sym->st_info) == STT_FUNC)) {
1465 1465 srp->sr_dmap = ilmp;
1466 1466 srp->sr_sym = sym;
1467 1467 *binfo |= (DBG_BINFO_FOUND | DBG_BINFO_PLTADDR);
1468 1468
1469 1469 if ((FLAGS(ilmp) & FLG_RT_OBJINTPO) ||
1470 1470 ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
1471 1471 is_sym_interposer(ilmp, sym)))
1472 1472 *binfo |= DBG_BINFO_INTERPOSE;
1473 1473 return (1);
1474 1474 }
1475 1475
1476 1476 /*
1477 1477 * Undefined symbol.
1478 1478 */
1479 1479 return (0);
1480 1480 }
1481 1481
1482 1482 /*
1483 1483 * We've found a match. Determine if the defining object contains
1484 1484 * symbol binding information.
1485 1485 */
1486 1486 if ((sip = SYMINFO(ilmp)) != NULL)
1487 1487 sip += ndx;
1488 1488
1489 1489 /*
1490 1490 * If this definition is a singleton, and we haven't followed a default
1491 1491 * symbol search knowing that we're looking for a singleton (presumably
1492 1492 * because the symbol definition has been changed since the referring
1493 1493 * object was built), then reject this binding so that the caller can
1494 1494 * fall back to a standard symbol search.
1495 1495 */
1496 1496 if ((ELF_ST_VISIBILITY(sym->st_other) == STV_SINGLETON) &&
1497 1497 (((slp->sl_flags & LKUP_STANDARD) == 0) ||
1498 1498 (((slp->sl_flags & LKUP_SINGLETON) == 0) &&
1499 1499 (LIST(ilmp)->lm_flags & LML_FLG_GROUPSEXIST)))) {
1500 1500 DBG_CALL(Dbg_bind_reject(slp->sl_cmap, ilmp, name,
1501 1501 DBG_BNDREJ_SINGLE));
1502 1502 *binfo |= BINFO_REJSINGLE;
1503 1503 *binfo &= ~DBG_BINFO_MSK;
1504 1504 return (0);
1505 1505 }
1506 1506
1507 1507 /*
1508 1508 * If this is a direct binding request, but the symbol definition has
1509 1509 * disabled directly binding to it (presumably because the symbol
1510 1510 * definition has been changed since the referring object was built),
1511 1511 * reject this binding so that the caller can fall back to a standard
1512 1512 * symbol search.
1513 1513 */
1514 1514 if (sip && (slp->sl_flags & LKUP_DIRECT) &&
1515 1515 (sip->si_flags & SYMINFO_FLG_NOEXTDIRECT)) {
1516 1516 DBG_CALL(Dbg_bind_reject(slp->sl_cmap, ilmp, name,
1517 1517 DBG_BNDREJ_DIRECT));
1518 1518 *binfo |= BINFO_REJDIRECT;
1519 1519 *binfo &= ~DBG_BINFO_MSK;
1520 1520 return (0);
1521 1521 }
1522 1522
1523 1523 /*
1524 1524 * If this is a binding request within an RTLD_GROUP family, and the
1525 1525 * symbol has disabled directly binding to it, reject this binding so
1526 1526 * that the caller can fall back to a standard symbol search.
1527 1527 *
1528 1528 * Effectively, an RTLD_GROUP family achieves what can now be
1529 1529 * established with direct bindings. However, various symbols have
1530 1530 * been tagged as inappropriate for direct binding to (ie. libc:malloc).
1531 1531 *
1532 1532 * A symbol marked as no-direct cannot be used within a group without
1533 1533 * first ensuring that the symbol has not been interposed upon outside
1534 1534 * of the group. A common example occurs when users implement their own
1535 1535 * version of malloc() in the executable. Such a malloc() interposes on
1536 1536 * the libc:malloc, and this interposition must be honored within the
1537 1537 * group as well.
1538 1538 *
1539 1539 * Following any rejection, LKUP_WORLD is established as a means of
1540 1540 * overriding this test as we return to a standard search.
1541 1541 */
1542 1542 if (sip && (sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) &&
1543 1543 ((MODE(slp->sl_cmap) & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP) &&
1544 1544 ((slp->sl_flags & LKUP_WORLD) == 0)) {
1545 1545 DBG_CALL(Dbg_bind_reject(slp->sl_cmap, ilmp, name,
1546 1546 DBG_BNDREJ_GROUP));
1547 1547 *binfo |= BINFO_REJGROUP;
1548 1548 *binfo &= ~DBG_BINFO_MSK;
1549 1549 return (0);
1550 1550 }
1551 1551
1552 1552 /*
1553 1553 * If this symbol is associated with capabilities, then each of the
1554 1554 * capabilities instances needs to be compared against the system
1555 1555 * capabilities. The best instance will be chosen to satisfy this
1556 1556 * binding.
1557 1557 */
1558 1558 if (CAP(ilmp) && CAPINFO(ilmp) && ELF_C_GROUP(CAPINFO(ilmp)[ndx]) &&
1559 1559 (cap_match(srp, ndx, symtabptr, strtabptr) == 0))
1560 1560 return (0);
1561 1561
1562 1562 /*
1563 1563 * Determine whether this object is acting as a filter.
1564 1564 */
1565 1565 if (((flags1 = FLAGS1(ilmp)) & MSK_RT_FILTER) == 0)
1566 1566 return (1);
1567 1567
1568 1568 /*
1569 1569 * Determine if this object offers per-symbol filtering, and if so,
1570 1570 * whether this symbol references a filtee.
1571 1571 */
1572 1572 if (sip && (flags1 & (FL1_RT_SYMSFLTR | FL1_RT_SYMAFLTR))) {
1573 1573 /*
1574 1574 * If this is a standard filter reference, and no standard
1575 1575 * filtees remain to be inspected, we're done. If this is an
1576 1576 * auxiliary filter reference, and no auxiliary filtees remain,
1577 1577 * we'll fall through in case any object filtering is available.
1578 1578 */
1579 1579 if ((sip->si_flags & SYMINFO_FLG_FILTER) &&
1580 1580 (SYMSFLTRCNT(ilmp) == 0))
1581 1581 return (0);
1582 1582
1583 1583 if ((sip->si_flags & SYMINFO_FLG_FILTER) ||
1584 1584 ((sip->si_flags & SYMINFO_FLG_AUXILIARY) &&
1585 1585 SYMAFLTRCNT(ilmp))) {
1586 1586 Sresult sr;
1587 1587
1588 1588 /*
1589 1589 * Initialize a local symbol result descriptor, using
1590 1590 * the original symbol name.
1591 1591 */
1592 1592 SRESULT_INIT(sr, slp->sl_name);
1593 1593
1594 1594 /*
1595 1595 * This symbol has an associated filtee. Lookup the
1596 1596 * symbol in the filtee, and if it is found return it.
1597 1597 * If the symbol doesn't exist, and this is a standard
1598 1598 * filter, return an error, otherwise fall through to
1599 1599 * catch any object filtering that may be available.
1600 1600 */
1601 1601 if (elf_lookup_filtee(slp, &sr, binfo, sip->si_boundto,
1602 1602 in_nfavl)) {
1603 1603 *srp = sr;
1604 1604 return (1);
1605 1605 }
1606 1606 if (sip->si_flags & SYMINFO_FLG_FILTER)
1607 1607 return (0);
1608 1608 }
1609 1609 }
1610 1610
1611 1611 /*
1612 1612 * Determine if this object provides global filtering.
1613 1613 */
1614 1614 if (flags1 & (FL1_RT_OBJSFLTR | FL1_RT_OBJAFLTR)) {
1615 1615 if (OBJFLTRNDX(ilmp) != FLTR_DISABLED) {
1616 1616 Sresult sr;
1617 1617
1618 1618 /*
1619 1619 * Initialize a local symbol result descriptor, using
1620 1620 * the original symbol name.
1621 1621 */
1622 1622 SRESULT_INIT(sr, slp->sl_name);
1623 1623
1624 1624 /*
1625 1625 * This object has an associated filtee. Lookup the
1626 1626 * symbol in the filtee, and if it is found return it.
1627 1627 * If the symbol doesn't exist, and this is a standard
1628 1628 * filter, return and error, otherwise return the symbol
1629 1629 * within the filter itself.
1630 1630 */
1631 1631 if (elf_lookup_filtee(slp, &sr, binfo, OBJFLTRNDX(ilmp),
1632 1632 in_nfavl)) {
1633 1633 *srp = sr;
1634 1634 return (1);
1635 1635 }
1636 1636 }
1637 1637
1638 1638 if (flags1 & FL1_RT_OBJSFLTR)
1639 1639 return (0);
1640 1640 }
1641 1641 return (1);
1642 1642 }
1643 1643
1644 1644 /*
1645 1645 * Create a new Rt_map structure for an ELF object and initialize
1646 1646 * all values.
1647 1647 */
1648 1648 Rt_map *
1649 1649 elf_new_lmp(Lm_list *lml, Aliste lmco, Fdesc *fdp, Addr addr, size_t msize,
1650 1650 void *odyn, Rt_map *clmp, int *in_nfavl)
1651 1651 {
1652 1652 const char *name = fdp->fd_nname;
1653 1653 Rt_map *lmp;
1654 1654 Ehdr *ehdr = (Ehdr *)addr;
1655 1655 Phdr *phdr, *tphdr = NULL, *dphdr = NULL, *uphdr = NULL;
1656 1656 Dyn *dyn = (Dyn *)odyn;
1657 1657 Cap *cap = NULL;
1658 1658 int ndx;
1659 1659 Addr base, fltr = 0, audit = 0, cfile = 0, crle = 0;
1660 1660 Xword rpath = 0;
1661 1661 size_t lmsz, rtsz, epsz, dynsz = 0;
1662 1662 uint_t dyncnt = 0;
1663 1663
1664 1664 DBG_CALL(Dbg_file_elf(lml, name, addr, msize, lml->lm_lmidstr, lmco));
1665 1665
1666 1666 /*
1667 1667 * If this is a shared object, the base address of the shared object is
1668 1668 * added to all address values defined within the object. Otherwise, if
1669 1669 * this is an executable, all object addresses are used as is.
1670 1670 */
1671 1671 if (ehdr->e_type == ET_EXEC)
1672 1672 base = 0;
1673 1673 else
1674 1674 base = addr;
1675 1675
1676 1676 /*
1677 1677 * Traverse the program header table, picking off required items. This
1678 1678 * traversal also provides for the sizing of the PT_DYNAMIC section.
1679 1679 */
1680 1680 phdr = (Phdr *)((uintptr_t)ehdr + ehdr->e_phoff);
1681 1681 for (ndx = 0; ndx < (int)ehdr->e_phnum; ndx++,
1682 1682 phdr = (Phdr *)((uintptr_t)phdr + ehdr->e_phentsize)) {
1683 1683 switch (phdr->p_type) {
1684 1684 case PT_DYNAMIC:
1685 1685 dphdr = phdr;
1686 1686 dyn = (Dyn *)((uintptr_t)phdr->p_vaddr + base);
1687 1687 break;
1688 1688 case PT_TLS:
1689 1689 tphdr = phdr;
1690 1690 break;
1691 1691 case PT_SUNWCAP:
1692 1692 cap = (Cap *)((uintptr_t)phdr->p_vaddr + base);
1693 1693 break;
1694 1694 case PT_SUNW_UNWIND:
1695 1695 case PT_SUNW_EH_FRAME:
1696 1696 uphdr = phdr;
1697 1697 break;
1698 1698 default:
1699 1699 break;
1700 1700 }
1701 1701 }
1702 1702
1703 1703 /*
1704 1704 * Determine the number of PT_DYNAMIC entries for the DYNINFO()
1705 1705 * allocation. Sadly, this is a little larger than we really need,
1706 1706 * as there are typically padding DT_NULL entries. However, adding
1707 1707 * this data to the initial link-map allocation is a win.
1708 1708 */
1709 1709 if (dyn) {
1710 1710 dyncnt = dphdr->p_filesz / sizeof (Dyn);
1711 1711 dynsz = dyncnt * sizeof (Dyninfo);
1712 1712 }
↓ open down ↓ |
1712 lines elided |
↑ open up ↑ |
1713 1713
1714 1714 /*
1715 1715 * Allocate space for the link-map, private elf information, and
1716 1716 * DYNINFO() data. Once these are allocated and initialized,
1717 1717 * remove_so(0, lmp) can be used to tear down the link-map allocation
1718 1718 * should any failures occur.
1719 1719 */
1720 1720 rtsz = S_DROUND(sizeof (Rt_map));
1721 1721 epsz = S_DROUND(sizeof (Rt_elfp));
1722 1722 lmsz = rtsz + epsz + dynsz;
1723 - if ((lmp = calloc(lmsz, 1)) == NULL)
1723 + if ((lmp = calloc(1, lmsz)) == NULL)
1724 1724 return (NULL);
1725 1725 ELFPRV(lmp) = (void *)((uintptr_t)lmp + rtsz);
1726 1726 DYNINFO(lmp) = (Dyninfo *)((uintptr_t)lmp + rtsz + epsz);
1727 1727 LMSIZE(lmp) = lmsz;
1728 1728
1729 1729 /*
1730 1730 * All fields not filled in were set to 0 by calloc.
1731 1731 */
1732 1732 NAME(lmp) = (char *)name;
1733 1733 ADDR(lmp) = addr;
1734 1734 MSIZE(lmp) = msize;
1735 1735 SYMINTP(lmp) = elf_find_sym;
1736 1736 FCT(lmp) = &elf_fct;
1737 1737 LIST(lmp) = lml;
1738 1738 OBJFLTRNDX(lmp) = FLTR_DISABLED;
1739 1739 SORTVAL(lmp) = -1;
1740 1740 DYN(lmp) = dyn;
1741 1741 DYNINFOCNT(lmp) = dyncnt;
1742 1742 PTUNWIND(lmp) = uphdr;
1743 1743
1744 1744 if (ehdr->e_type == ET_EXEC)
1745 1745 FLAGS(lmp) |= FLG_RT_FIXED;
1746 1746
1747 1747 /*
1748 1748 * Fill in rest of the link map entries with information from the file's
1749 1749 * dynamic structure.
1750 1750 */
1751 1751 if (dyn) {
1752 1752 Dyninfo *dip;
1753 1753 uint_t dynndx;
1754 1754 Xword pltpadsz = 0;
1755 1755 Rti_desc *rti;
1756 1756 Dyn *pdyn;
1757 1757 Word lmtflags = lml->lm_tflags;
1758 1758 int ignore = 0;
1759 1759
1760 1760 /*
1761 1761 * Note, we use DT_NULL to terminate processing, and the
1762 1762 * dynamic entry count as a fall back. Normally, a DT_NULL
1763 1763 * entry marks the end of the dynamic section. Any non-NULL
1764 1764 * items following the first DT_NULL are silently ignored.
1765 1765 * This situation should only occur through use of elfedit(1)
1766 1766 * or a similar tool.
1767 1767 */
1768 1768 for (dynndx = 0, pdyn = NULL, dip = DYNINFO(lmp);
1769 1769 dynndx < dyncnt; dynndx++, pdyn = dyn++, dip++) {
1770 1770
1771 1771 if (ignore) {
1772 1772 dip->di_flags |= FLG_DI_IGNORE;
1773 1773 continue;
1774 1774 }
1775 1775
1776 1776 switch ((Xword)dyn->d_tag) {
1777 1777 case DT_NULL:
1778 1778 dip->di_flags |= ignore = FLG_DI_IGNORE;
1779 1779 break;
1780 1780 case DT_POSFLAG_1:
1781 1781 dip->di_flags |= FLG_DI_POSFLAG1;
1782 1782 break;
1783 1783 case DT_NEEDED:
1784 1784 case DT_USED:
1785 1785 dip->di_flags |= FLG_DI_NEEDED;
1786 1786
1787 1787 /* BEGIN CSTYLED */
1788 1788 if (pdyn && (pdyn->d_tag == DT_POSFLAG_1)) {
1789 1789 /*
1790 1790 * Identify any non-deferred lazy load for
1791 1791 * future processing, unless LD_NOLAZYLOAD
1792 1792 * has been set.
1793 1793 */
1794 1794 if ((pdyn->d_un.d_val & DF_P1_LAZYLOAD) &&
1795 1795 ((lmtflags & LML_TFLG_NOLAZYLD) == 0))
1796 1796 dip->di_flags |= FLG_DI_LAZY;
1797 1797
1798 1798 /*
1799 1799 * Identify any group permission
1800 1800 * requirements.
1801 1801 */
1802 1802 if (pdyn->d_un.d_val & DF_P1_GROUPPERM)
1803 1803 dip->di_flags |= FLG_DI_GROUP;
1804 1804
1805 1805 /*
1806 1806 * Identify any deferred dependencies.
1807 1807 */
1808 1808 if (pdyn->d_un.d_val & DF_P1_DEFERRED)
1809 1809 dip->di_flags |= FLG_DI_DEFERRED;
1810 1810 }
1811 1811 /* END CSTYLED */
1812 1812 break;
1813 1813 case DT_SYMTAB:
1814 1814 SYMTAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
1815 1815 break;
1816 1816 case DT_SUNW_SYMTAB:
1817 1817 SUNWSYMTAB(lmp) =
1818 1818 (void *)(dyn->d_un.d_ptr + base);
1819 1819 break;
1820 1820 case DT_SUNW_SYMSZ:
1821 1821 SUNWSYMSZ(lmp) = dyn->d_un.d_val;
1822 1822 break;
1823 1823 case DT_STRTAB:
1824 1824 STRTAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
1825 1825 break;
1826 1826 case DT_SYMENT:
1827 1827 SYMENT(lmp) = dyn->d_un.d_val;
1828 1828 break;
1829 1829 case DT_FEATURE_1:
1830 1830 if (dyn->d_un.d_val & DTF_1_CONFEXP)
1831 1831 crle = 1;
1832 1832 break;
1833 1833 case DT_MOVESZ:
1834 1834 MOVESZ(lmp) = dyn->d_un.d_val;
1835 1835 FLAGS(lmp) |= FLG_RT_MOVE;
1836 1836 break;
1837 1837 case DT_MOVEENT:
1838 1838 MOVEENT(lmp) = dyn->d_un.d_val;
1839 1839 break;
1840 1840 case DT_MOVETAB:
1841 1841 MOVETAB(lmp) = (void *)(dyn->d_un.d_ptr + base);
1842 1842 break;
1843 1843 case DT_REL:
1844 1844 case DT_RELA:
1845 1845 /*
1846 1846 * At this time, ld.so. can only handle one
1847 1847 * type of relocation per object.
1848 1848 */
1849 1849 REL(lmp) = (void *)(dyn->d_un.d_ptr + base);
1850 1850 break;
1851 1851 case DT_RELSZ:
1852 1852 case DT_RELASZ:
1853 1853 RELSZ(lmp) = dyn->d_un.d_val;
1854 1854 break;
1855 1855 case DT_RELENT:
1856 1856 case DT_RELAENT:
1857 1857 RELENT(lmp) = dyn->d_un.d_val;
1858 1858 break;
1859 1859 case DT_RELCOUNT:
1860 1860 case DT_RELACOUNT:
1861 1861 RELACOUNT(lmp) = (uint_t)dyn->d_un.d_val;
1862 1862 break;
1863 1863 case DT_HASH:
1864 1864 HASH(lmp) = (uint_t *)(dyn->d_un.d_ptr + base);
1865 1865 break;
1866 1866 case DT_PLTGOT:
1867 1867 PLTGOT(lmp) =
1868 1868 (uint_t *)(dyn->d_un.d_ptr + base);
1869 1869 break;
1870 1870 case DT_PLTRELSZ:
1871 1871 PLTRELSZ(lmp) = dyn->d_un.d_val;
1872 1872 break;
1873 1873 case DT_JMPREL:
1874 1874 JMPREL(lmp) = (void *)(dyn->d_un.d_ptr + base);
1875 1875 break;
1876 1876 case DT_INIT:
1877 1877 if (dyn->d_un.d_ptr != NULL)
1878 1878 INIT(lmp) =
1879 1879 (void (*)())(dyn->d_un.d_ptr +
1880 1880 base);
1881 1881 break;
1882 1882 case DT_FINI:
1883 1883 if (dyn->d_un.d_ptr != NULL)
1884 1884 FINI(lmp) =
1885 1885 (void (*)())(dyn->d_un.d_ptr +
1886 1886 base);
1887 1887 break;
1888 1888 case DT_INIT_ARRAY:
1889 1889 INITARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
1890 1890 base);
1891 1891 break;
1892 1892 case DT_INIT_ARRAYSZ:
1893 1893 INITARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
1894 1894 break;
1895 1895 case DT_FINI_ARRAY:
1896 1896 FINIARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
1897 1897 base);
1898 1898 break;
1899 1899 case DT_FINI_ARRAYSZ:
1900 1900 FINIARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
1901 1901 break;
1902 1902 case DT_PREINIT_ARRAY:
1903 1903 PREINITARRAY(lmp) = (Addr *)(dyn->d_un.d_ptr +
1904 1904 base);
1905 1905 break;
1906 1906 case DT_PREINIT_ARRAYSZ:
1907 1907 PREINITARRAYSZ(lmp) = (uint_t)dyn->d_un.d_val;
1908 1908 break;
1909 1909 case DT_RPATH:
1910 1910 case DT_RUNPATH:
1911 1911 rpath = dyn->d_un.d_val;
1912 1912 break;
1913 1913 case DT_FILTER:
1914 1914 dip->di_flags |= FLG_DI_STDFLTR;
1915 1915 fltr = dyn->d_un.d_val;
1916 1916 OBJFLTRNDX(lmp) = dynndx;
1917 1917 FLAGS1(lmp) |= FL1_RT_OBJSFLTR;
1918 1918 break;
1919 1919 case DT_AUXILIARY:
1920 1920 dip->di_flags |= FLG_DI_AUXFLTR;
1921 1921 if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
1922 1922 fltr = dyn->d_un.d_val;
1923 1923 OBJFLTRNDX(lmp) = dynndx;
1924 1924 }
1925 1925 FLAGS1(lmp) |= FL1_RT_OBJAFLTR;
1926 1926 break;
1927 1927 case DT_SUNW_FILTER:
1928 1928 dip->di_flags |=
1929 1929 (FLG_DI_STDFLTR | FLG_DI_SYMFLTR);
1930 1930 SYMSFLTRCNT(lmp)++;
1931 1931 FLAGS1(lmp) |= FL1_RT_SYMSFLTR;
1932 1932 break;
1933 1933 case DT_SUNW_AUXILIARY:
1934 1934 dip->di_flags |=
1935 1935 (FLG_DI_AUXFLTR | FLG_DI_SYMFLTR);
1936 1936 if (!(rtld_flags & RT_FL_NOAUXFLTR)) {
1937 1937 SYMAFLTRCNT(lmp)++;
1938 1938 }
1939 1939 FLAGS1(lmp) |= FL1_RT_SYMAFLTR;
1940 1940 break;
1941 1941 case DT_DEPAUDIT:
1942 1942 if (!(rtld_flags & RT_FL_NOAUDIT)) {
1943 1943 audit = dyn->d_un.d_val;
1944 1944 FLAGS1(lmp) |= FL1_RT_DEPAUD;
1945 1945 }
1946 1946 break;
1947 1947 case DT_CONFIG:
1948 1948 cfile = dyn->d_un.d_val;
1949 1949 break;
1950 1950 case DT_DEBUG:
1951 1951 /*
1952 1952 * DT_DEBUG entries are only created in
1953 1953 * dynamic objects that require an interpretor
1954 1954 * (ie. all dynamic executables and some shared
1955 1955 * objects), and provide for a hand-shake with
1956 1956 * old debuggers. This entry is initialized to
1957 1957 * zero by the link-editor. If a debugger is
1958 1958 * monitoring us, and has updated this entry,
1959 1959 * set the debugger monitor flag, and finish
1960 1960 * initializing the debugging structure. See
1961 1961 * setup(). Also, switch off any configuration
1962 1962 * object use as most debuggers can't handle
1963 1963 * fixed dynamic executables as dependencies.
1964 1964 */
1965 1965 if (dyn->d_un.d_ptr)
1966 1966 rtld_flags |=
1967 1967 (RT_FL_DEBUGGER | RT_FL_NOOBJALT);
1968 1968 dyn->d_un.d_ptr = (Addr)&r_debug;
1969 1969 break;
1970 1970 case DT_VERNEED:
1971 1971 VERNEED(lmp) = (Verneed *)(dyn->d_un.d_ptr +
1972 1972 base);
1973 1973 break;
1974 1974 case DT_VERNEEDNUM:
1975 1975 /* LINTED */
1976 1976 VERNEEDNUM(lmp) = (int)dyn->d_un.d_val;
1977 1977 break;
1978 1978 case DT_VERDEF:
1979 1979 VERDEF(lmp) = (Verdef *)(dyn->d_un.d_ptr +
1980 1980 base);
1981 1981 break;
1982 1982 case DT_VERDEFNUM:
1983 1983 /* LINTED */
1984 1984 VERDEFNUM(lmp) = (int)dyn->d_un.d_val;
1985 1985 break;
1986 1986 case DT_VERSYM:
1987 1987 /*
1988 1988 * The Solaris ld does not produce DT_VERSYM,
1989 1989 * but the GNU ld does, in order to support
1990 1990 * their style of versioning, which differs
1991 1991 * from ours in some ways, while using the
1992 1992 * same data structures. The presence of
1993 1993 * DT_VERSYM therefore means that GNU
1994 1994 * versioning rules apply to the given file.
1995 1995 * If DT_VERSYM is not present, then Solaris
1996 1996 * versioning rules apply.
1997 1997 */
1998 1998 VERSYM(lmp) = (Versym *)(dyn->d_un.d_ptr +
1999 1999 base);
2000 2000 break;
2001 2001 case DT_BIND_NOW:
2002 2002 if ((dyn->d_un.d_val & DF_BIND_NOW) &&
2003 2003 ((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
2004 2004 MODE(lmp) |= RTLD_NOW;
2005 2005 MODE(lmp) &= ~RTLD_LAZY;
2006 2006 }
2007 2007 break;
2008 2008 case DT_FLAGS:
2009 2009 FLAGS1(lmp) |= FL1_RT_DTFLAGS;
2010 2010 if (dyn->d_un.d_val & DF_SYMBOLIC)
2011 2011 FLAGS1(lmp) |= FL1_RT_SYMBOLIC;
2012 2012 if ((dyn->d_un.d_val & DF_BIND_NOW) &&
2013 2013 ((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
2014 2014 MODE(lmp) |= RTLD_NOW;
2015 2015 MODE(lmp) &= ~RTLD_LAZY;
2016 2016 }
2017 2017 /*
2018 2018 * Capture any static TLS use, and enforce that
2019 2019 * this object be non-deletable.
2020 2020 */
2021 2021 if (dyn->d_un.d_val & DF_STATIC_TLS) {
2022 2022 FLAGS1(lmp) |= FL1_RT_TLSSTAT;
2023 2023 MODE(lmp) |= RTLD_NODELETE;
2024 2024 }
2025 2025 break;
2026 2026 case DT_FLAGS_1:
2027 2027 if (dyn->d_un.d_val & DF_1_DISPRELPND)
2028 2028 FLAGS1(lmp) |= FL1_RT_DISPREL;
2029 2029 if (dyn->d_un.d_val & DF_1_GROUP)
2030 2030 FLAGS(lmp) |=
2031 2031 (FLG_RT_SETGROUP | FLG_RT_PUBHDL);
2032 2032 if ((dyn->d_un.d_val & DF_1_NOW) &&
2033 2033 ((rtld_flags2 & RT_FL2_BINDLAZY) == 0)) {
2034 2034 MODE(lmp) |= RTLD_NOW;
2035 2035 MODE(lmp) &= ~RTLD_LAZY;
2036 2036 }
2037 2037 if (dyn->d_un.d_val & DF_1_NODELETE)
2038 2038 MODE(lmp) |= RTLD_NODELETE;
2039 2039 if (dyn->d_un.d_val & DF_1_INITFIRST)
2040 2040 FLAGS(lmp) |= FLG_RT_INITFRST;
2041 2041 if (dyn->d_un.d_val & DF_1_NOOPEN)
2042 2042 FLAGS(lmp) |= FLG_RT_NOOPEN;
2043 2043 if (dyn->d_un.d_val & DF_1_LOADFLTR)
2044 2044 FLAGS(lmp) |= FLG_RT_LOADFLTR;
2045 2045 if (dyn->d_un.d_val & DF_1_NODUMP)
2046 2046 FLAGS(lmp) |= FLG_RT_NODUMP;
2047 2047 if (dyn->d_un.d_val & DF_1_CONFALT)
2048 2048 crle = 1;
2049 2049 if (dyn->d_un.d_val & DF_1_DIRECT)
2050 2050 FLAGS1(lmp) |= FL1_RT_DIRECT;
2051 2051 if (dyn->d_un.d_val & DF_1_NODEFLIB)
2052 2052 FLAGS1(lmp) |= FL1_RT_NODEFLIB;
2053 2053 if (dyn->d_un.d_val & DF_1_ENDFILTEE)
2054 2054 FLAGS1(lmp) |= FL1_RT_ENDFILTE;
2055 2055 if (dyn->d_un.d_val & DF_1_TRANS)
2056 2056 FLAGS(lmp) |= FLG_RT_TRANS;
2057 2057
2058 2058 /*
2059 2059 * Global auditing is only meaningful when
2060 2060 * specified by the initiating object of the
2061 2061 * process - typically the dynamic executable.
2062 2062 * If this is the initiating object, its link-
2063 2063 * map will not yet have been added to the
2064 2064 * link-map list, and consequently the link-map
2065 2065 * list is empty. (see setup()).
2066 2066 */
2067 2067 if (dyn->d_un.d_val & DF_1_GLOBAUDIT) {
2068 2068 if (lml_main.lm_head == NULL)
2069 2069 FLAGS1(lmp) |= FL1_RT_GLOBAUD;
2070 2070 else
2071 2071 DBG_CALL(Dbg_audit_ignore(lmp));
2072 2072 }
2073 2073
2074 2074 /*
2075 2075 * If this object identifies itself as an
2076 2076 * interposer, but relocation processing has
2077 2077 * already started, then demote it. It's too
2078 2078 * late to guarantee complete interposition.
2079 2079 */
2080 2080 /* BEGIN CSTYLED */
2081 2081 if (dyn->d_un.d_val &
2082 2082 (DF_1_INTERPOSE | DF_1_SYMINTPOSE)) {
2083 2083 if (lml->lm_flags & LML_FLG_STARTREL) {
2084 2084 DBG_CALL(Dbg_util_intoolate(lmp));
2085 2085 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
2086 2086 (void) printf(
2087 2087 MSG_INTL(MSG_LDD_REL_ERR2),
2088 2088 NAME(lmp));
2089 2089 } else if (dyn->d_un.d_val & DF_1_INTERPOSE)
2090 2090 FLAGS(lmp) |= FLG_RT_OBJINTPO;
2091 2091 else
2092 2092 FLAGS(lmp) |= FLG_RT_SYMINTPO;
2093 2093 }
2094 2094 /* END CSTYLED */
2095 2095 break;
2096 2096 case DT_SYMINFO:
2097 2097 SYMINFO(lmp) = (Syminfo *)(dyn->d_un.d_ptr +
2098 2098 base);
2099 2099 break;
2100 2100 case DT_SYMINENT:
2101 2101 SYMINENT(lmp) = dyn->d_un.d_val;
2102 2102 break;
2103 2103 case DT_PLTPAD:
2104 2104 PLTPAD(lmp) = (void *)(dyn->d_un.d_ptr + base);
2105 2105 break;
2106 2106 case DT_PLTPADSZ:
2107 2107 pltpadsz = dyn->d_un.d_val;
2108 2108 break;
2109 2109 case DT_SUNW_RTLDINF:
2110 2110 /*
2111 2111 * Maintain a list of RTLDINFO structures.
2112 2112 * Typically, libc is the only supplier, and
2113 2113 * only one structure is provided. However,
2114 2114 * multiple suppliers and multiple structures
2115 2115 * are supported. For example, one structure
2116 2116 * may provide thread_init, and another
2117 2117 * structure may provide atexit reservations.
2118 2118 */
2119 2119 if ((rti = alist_append(&lml->lm_rti, NULL,
2120 2120 sizeof (Rti_desc),
2121 2121 AL_CNT_RTLDINFO)) == NULL) {
2122 2122 remove_so(0, lmp, clmp);
2123 2123 return (NULL);
2124 2124 }
2125 2125 rti->rti_lmp = lmp;
2126 2126 rti->rti_info = (void *)(dyn->d_un.d_ptr +
2127 2127 base);
2128 2128 break;
2129 2129 case DT_SUNW_SORTENT:
2130 2130 SUNWSORTENT(lmp) = dyn->d_un.d_val;
2131 2131 break;
2132 2132 case DT_SUNW_SYMSORT:
2133 2133 SUNWSYMSORT(lmp) =
2134 2134 (void *)(dyn->d_un.d_ptr + base);
2135 2135 break;
2136 2136 case DT_SUNW_SYMSORTSZ:
2137 2137 SUNWSYMSORTSZ(lmp) = dyn->d_un.d_val;
2138 2138 break;
2139 2139 case DT_DEPRECATED_SPARC_REGISTER:
2140 2140 case M_DT_REGISTER:
2141 2141 dip->di_flags |= FLG_DI_REGISTER;
2142 2142 FLAGS(lmp) |= FLG_RT_REGSYMS;
2143 2143 break;
2144 2144 case DT_SUNW_CAP:
2145 2145 CAP(lmp) = (void *)(dyn->d_un.d_ptr + base);
2146 2146 break;
2147 2147 case DT_SUNW_CAPINFO:
2148 2148 CAPINFO(lmp) = (void *)(dyn->d_un.d_ptr + base);
2149 2149 break;
2150 2150 case DT_SUNW_CAPCHAIN:
2151 2151 CAPCHAIN(lmp) = (void *)(dyn->d_un.d_ptr +
2152 2152 base);
2153 2153 break;
2154 2154 case DT_SUNW_CAPCHAINENT:
2155 2155 CAPCHAINENT(lmp) = dyn->d_un.d_val;
2156 2156 break;
2157 2157 case DT_SUNW_CAPCHAINSZ:
2158 2158 CAPCHAINSZ(lmp) = dyn->d_un.d_val;
2159 2159 break;
2160 2160 }
2161 2161 }
2162 2162
2163 2163 /*
2164 2164 * Update any Dyninfo string pointers now that STRTAB() is
2165 2165 * known.
2166 2166 */
2167 2167 for (dynndx = 0, dyn = DYN(lmp), dip = DYNINFO(lmp);
2168 2168 !(dip->di_flags & FLG_DI_IGNORE); dyn++, dip++) {
2169 2169
2170 2170 switch ((Xword)dyn->d_tag) {
2171 2171 case DT_NEEDED:
2172 2172 case DT_USED:
2173 2173 case DT_FILTER:
2174 2174 case DT_AUXILIARY:
2175 2175 case DT_SUNW_FILTER:
2176 2176 case DT_SUNW_AUXILIARY:
2177 2177 dip->di_name = STRTAB(lmp) + dyn->d_un.d_val;
2178 2178 break;
2179 2179 }
2180 2180 }
2181 2181
2182 2182 /*
2183 2183 * Assign any padding.
2184 2184 */
2185 2185 if (PLTPAD(lmp)) {
2186 2186 if (pltpadsz == (Xword)0)
2187 2187 PLTPAD(lmp) = NULL;
2188 2188 else
2189 2189 PLTPADEND(lmp) = (void *)((Addr)PLTPAD(lmp) +
2190 2190 pltpadsz);
2191 2191 }
2192 2192 }
2193 2193
2194 2194 /*
2195 2195 * A dynsym contains only global functions. We want to have
2196 2196 * a version of it that also includes local functions, so that
2197 2197 * dladdr() will be able to report names for local functions
2198 2198 * when used to generate a stack trace for a stripped file.
2199 2199 * This version of the dynsym is provided via DT_SUNW_SYMTAB.
2200 2200 *
2201 2201 * In producing DT_SUNW_SYMTAB, ld uses a non-obvious trick
2202 2202 * in order to avoid having to have two copies of the global
2203 2203 * symbols held in DT_SYMTAB: The local symbols are placed in
2204 2204 * a separate section than the globals in the dynsym, but the
2205 2205 * linker conspires to put the data for these two sections adjacent
2206 2206 * to each other. DT_SUNW_SYMTAB points at the top of the local
2207 2207 * symbols, and DT_SUNW_SYMSZ is the combined length of both tables.
2208 2208 *
2209 2209 * If the two sections are not adjacent, then something went wrong
2210 2210 * at link time. We use ASSERT to kill the process if this is
2211 2211 * a debug build. In a production build, we will silently ignore
2212 2212 * the presence of the .ldynsym and proceed. We can detect this
2213 2213 * situation by checking to see that DT_SYMTAB lies in
2214 2214 * the range given by DT_SUNW_SYMTAB/DT_SUNW_SYMSZ.
2215 2215 */
2216 2216 if ((SUNWSYMTAB(lmp) != NULL) &&
2217 2217 (((char *)SYMTAB(lmp) <= (char *)SUNWSYMTAB(lmp)) ||
2218 2218 (((char *)SYMTAB(lmp) >=
2219 2219 (SUNWSYMSZ(lmp) + (char *)SUNWSYMTAB(lmp)))))) {
2220 2220 ASSERT(0);
2221 2221 SUNWSYMTAB(lmp) = NULL;
2222 2222 SUNWSYMSZ(lmp) = 0;
2223 2223 }
2224 2224
2225 2225 /*
2226 2226 * If configuration file use hasn't been disabled, and a configuration
2227 2227 * file hasn't already been set via an environment variable, see if any
2228 2228 * application specific configuration file is specified. An LD_CONFIG
2229 2229 * setting is used first, but if this image was generated via crle(1)
2230 2230 * then a default configuration file is a fall-back.
2231 2231 */
2232 2232 if ((!(rtld_flags & RT_FL_NOCFG)) && (config->c_name == NULL)) {
2233 2233 if (cfile)
2234 2234 config->c_name = (const char *)(cfile +
2235 2235 (char *)STRTAB(lmp));
2236 2236 else if (crle)
2237 2237 rtld_flags |= RT_FL_CONFAPP;
2238 2238 }
2239 2239
2240 2240 if (rpath)
2241 2241 RPATH(lmp) = (char *)(rpath + (char *)STRTAB(lmp));
2242 2242 if (fltr)
2243 2243 REFNAME(lmp) = (char *)(fltr + (char *)STRTAB(lmp));
2244 2244
2245 2245 /*
2246 2246 * For Intel ABI compatibility. It's possible that a JMPREL can be
2247 2247 * specified without any other relocations (e.g. a dynamic executable
2248 2248 * normally only contains .plt relocations). If this is the case then
2249 2249 * no REL, RELSZ or RELENT will have been created. For us to be able
2250 2250 * to traverse the .plt relocations under LD_BIND_NOW we need to know
2251 2251 * the RELENT for these relocations. Refer to elf_reloc() for more
2252 2252 * details.
2253 2253 */
2254 2254 if (!RELENT(lmp) && JMPREL(lmp))
2255 2255 RELENT(lmp) = sizeof (M_RELOC);
2256 2256
2257 2257 /*
2258 2258 * Establish any per-object auditing. If we're establishing main's
2259 2259 * link-map its too early to go searching for audit objects so just
2260 2260 * hold the object name for later (see setup()).
2261 2261 */
2262 2262 if (audit) {
2263 2263 char *cp = audit + (char *)STRTAB(lmp);
2264 2264
2265 2265 if (*cp) {
2266 2266 if (((AUDITORS(lmp) =
2267 2267 calloc(1, sizeof (Audit_desc))) == NULL) ||
2268 2268 ((AUDITORS(lmp)->ad_name = strdup(cp)) == NULL)) {
2269 2269 remove_so(0, lmp, clmp);
2270 2270 return (NULL);
2271 2271 }
2272 2272 if (lml_main.lm_head) {
2273 2273 if (audit_setup(lmp, AUDITORS(lmp), 0,
2274 2274 in_nfavl) == 0) {
2275 2275 remove_so(0, lmp, clmp);
2276 2276 return (NULL);
2277 2277 }
2278 2278 AFLAGS(lmp) |= AUDITORS(lmp)->ad_flags;
2279 2279 lml->lm_flags |= LML_FLG_LOCAUDIT;
2280 2280 }
2281 2281 }
2282 2282 }
2283 2283
2284 2284 if (tphdr && (tls_assign(lml, lmp, tphdr) == 0)) {
2285 2285 remove_so(0, lmp, clmp);
2286 2286 return (NULL);
2287 2287 }
2288 2288
2289 2289 /*
2290 2290 * A capabilities section should be identified by a DT_SUNW_CAP entry,
2291 2291 * and if non-empty object capabilities are included, a PT_SUNWCAP
2292 2292 * header should reference the section. Make sure CAP() is set
2293 2293 * regardless.
2294 2294 */
2295 2295 if ((CAP(lmp) == NULL) && cap)
2296 2296 CAP(lmp) = cap;
2297 2297
2298 2298 /*
2299 2299 * Make sure any capabilities information or chain can be handled.
2300 2300 */
2301 2301 if (CAPINFO(lmp) && (CAPINFO(lmp)[0] > CAPINFO_CURRENT))
2302 2302 CAPINFO(lmp) = NULL;
2303 2303 if (CAPCHAIN(lmp) && (CAPCHAIN(lmp)[0] > CAPCHAIN_CURRENT))
2304 2304 CAPCHAIN(lmp) = NULL;
2305 2305
2306 2306 /*
2307 2307 * As part of processing dependencies, a file descriptor is populated
2308 2308 * with capabilities information following validation.
2309 2309 */
2310 2310 if (fdp->fd_flags & FLG_FD_ALTCHECK) {
2311 2311 FLAGS1(lmp) |= FL1_RT_ALTCHECK;
2312 2312 CAPSET(lmp) = fdp->fd_scapset;
2313 2313
2314 2314 if (fdp->fd_flags & FLG_FD_ALTCAP)
2315 2315 FLAGS1(lmp) |= FL1_RT_ALTCAP;
2316 2316
2317 2317 } else if ((cap = CAP(lmp)) != NULL) {
2318 2318 /*
2319 2319 * Processing of the a.out and ld.so.1 does not involve a file
2320 2320 * descriptor as exec() did all the work, so capture the
2321 2321 * capabilities for these cases.
2322 2322 */
2323 2323 while (cap->c_tag != CA_SUNW_NULL) {
2324 2324 switch (cap->c_tag) {
2325 2325 case CA_SUNW_HW_1:
2326 2326 CAPSET(lmp).sc_hw_1 = cap->c_un.c_val;
2327 2327 break;
2328 2328 case CA_SUNW_SF_1:
2329 2329 CAPSET(lmp).sc_sf_1 = cap->c_un.c_val;
2330 2330 break;
2331 2331 case CA_SUNW_HW_2:
2332 2332 CAPSET(lmp).sc_hw_2 = cap->c_un.c_val;
2333 2333 break;
2334 2334 case CA_SUNW_PLAT:
2335 2335 CAPSET(lmp).sc_plat = STRTAB(lmp) +
2336 2336 cap->c_un.c_ptr;
2337 2337 break;
2338 2338 case CA_SUNW_MACH:
2339 2339 CAPSET(lmp).sc_mach = STRTAB(lmp) +
2340 2340 cap->c_un.c_ptr;
2341 2341 break;
2342 2342 }
2343 2343 cap++;
2344 2344 }
2345 2345 }
2346 2346
2347 2347 /*
↓ open down ↓ |
614 lines elided |
↑ open up ↑ |
2348 2348 * If a capabilities chain table exists, duplicate it. The chain table
2349 2349 * is inspected for each initial call to a capabilities family lead
2350 2350 * symbol. From this chain, each family member is inspected to
2351 2351 * determine the 'best' family member. The chain table is then updated
2352 2352 * so that the best member is immediately selected for any further
2353 2353 * family searches.
2354 2354 */
2355 2355 if (CAPCHAIN(lmp)) {
2356 2356 Capchain *capchain;
2357 2357
2358 - if ((capchain = calloc(CAPCHAINSZ(lmp), 1)) == NULL)
2358 + if ((capchain = calloc(1, CAPCHAINSZ(lmp))) == NULL)
2359 2359 return (NULL);
2360 2360 (void) memcpy(capchain, CAPCHAIN(lmp), CAPCHAINSZ(lmp));
2361 2361 CAPCHAIN(lmp) = capchain;
2362 2362 }
2363 2363
2364 2364 /*
2365 2365 * Add the mapped object to the end of the link map list.
2366 2366 */
2367 2367 lm_append(lml, lmco, lmp);
2368 2368
2369 2369 /*
2370 2370 * Start the system loading in the ELF information we'll be processing.
2371 2371 */
2372 2372 if (REL(lmp)) {
2373 2373 (void) madvise((void *)ADDR(lmp), (uintptr_t)REL(lmp) +
2374 2374 (uintptr_t)RELSZ(lmp) - (uintptr_t)ADDR(lmp),
2375 2375 MADV_WILLNEED);
2376 2376 }
2377 2377 return (lmp);
2378 2378 }
2379 2379
2380 2380 /*
2381 2381 * Build full pathname of shared object from given directory name and filename.
2382 2382 */
2383 2383 static char *
2384 2384 elf_get_so(const char *dir, const char *file, size_t dlen, size_t flen)
2385 2385 {
2386 2386 static char pname[PATH_MAX];
2387 2387
2388 2388 (void) strncpy(pname, dir, dlen);
2389 2389 pname[dlen++] = '/';
2390 2390 (void) strncpy(&pname[dlen], file, flen + 1);
2391 2391 return (pname);
2392 2392 }
2393 2393
2394 2394 /*
2395 2395 * The copy relocation is recorded in a copy structure which will be applied
2396 2396 * after all other relocations are carried out. This provides for copying data
2397 2397 * that must be relocated itself (ie. pointers in shared objects). This
2398 2398 * structure also provides a means of binding RTLD_GROUP dependencies to any
2399 2399 * copy relocations that have been taken from any group members.
2400 2400 *
2401 2401 * If the size of the .bss area available for the copy information is not the
2402 2402 * same as the source of the data inform the user if we're under ldd(1) control
2403 2403 * (this checking was only established in 5.3, so by only issuing an error via
2404 2404 * ldd(1) we maintain the standard set by previous releases).
2405 2405 */
2406 2406 int
2407 2407 elf_copy_reloc(char *name, Sym *rsym, Rt_map *rlmp, void *radd, Sym *dsym,
2408 2408 Rt_map *dlmp, const void *dadd)
2409 2409 {
2410 2410 Rel_copy rc;
2411 2411 Lm_list *lml = LIST(rlmp);
2412 2412
2413 2413 rc.r_name = name;
2414 2414 rc.r_rsym = rsym; /* the new reference symbol and its */
2415 2415 rc.r_rlmp = rlmp; /* associated link-map */
2416 2416 rc.r_dlmp = dlmp; /* the defining link-map */
2417 2417 rc.r_dsym = dsym; /* the original definition */
2418 2418 rc.r_radd = radd;
2419 2419 rc.r_dadd = dadd;
2420 2420
2421 2421 if (rsym->st_size > dsym->st_size)
2422 2422 rc.r_size = (size_t)dsym->st_size;
2423 2423 else
2424 2424 rc.r_size = (size_t)rsym->st_size;
2425 2425
2426 2426 if (alist_append(©_R(dlmp), &rc, sizeof (Rel_copy),
2427 2427 AL_CNT_COPYREL) == NULL) {
2428 2428 if (!(lml->lm_flags & LML_FLG_TRC_WARN))
2429 2429 return (0);
2430 2430 else
2431 2431 return (1);
2432 2432 }
2433 2433 if (!(FLAGS1(dlmp) & FL1_RT_COPYTOOK)) {
2434 2434 if (aplist_append(©_S(rlmp), dlmp,
2435 2435 AL_CNT_COPYREL) == NULL) {
2436 2436 if (!(lml->lm_flags & LML_FLG_TRC_WARN))
2437 2437 return (0);
2438 2438 else
2439 2439 return (1);
2440 2440 }
2441 2441 FLAGS1(dlmp) |= FL1_RT_COPYTOOK;
2442 2442 }
2443 2443
2444 2444 /*
2445 2445 * If we are tracing (ldd), warn the user if
2446 2446 * 1) the size from the reference symbol differs from the
2447 2447 * copy definition. We can only copy as much data as the
2448 2448 * reference (dynamic executables) entry allows.
2449 2449 * 2) the copy definition has STV_PROTECTED visibility.
2450 2450 */
2451 2451 if (lml->lm_flags & LML_FLG_TRC_WARN) {
2452 2452 if (rsym->st_size != dsym->st_size) {
2453 2453 (void) printf(MSG_INTL(MSG_LDD_CPY_SIZDIF),
2454 2454 _conv_reloc_type(M_R_COPY), demangle(name),
2455 2455 NAME(rlmp), EC_XWORD(rsym->st_size),
2456 2456 NAME(dlmp), EC_XWORD(dsym->st_size));
2457 2457 if (rsym->st_size > dsym->st_size)
2458 2458 (void) printf(MSG_INTL(MSG_LDD_CPY_INSDATA),
2459 2459 NAME(dlmp));
2460 2460 else
2461 2461 (void) printf(MSG_INTL(MSG_LDD_CPY_DATRUNC),
2462 2462 NAME(rlmp));
2463 2463 }
2464 2464
2465 2465 if (ELF_ST_VISIBILITY(dsym->st_other) == STV_PROTECTED) {
2466 2466 (void) printf(MSG_INTL(MSG_LDD_CPY_PROT),
2467 2467 _conv_reloc_type(M_R_COPY), demangle(name),
2468 2468 NAME(dlmp));
2469 2469 }
2470 2470 }
2471 2471
2472 2472 DBG_CALL(Dbg_reloc_apply_val(lml, ELF_DBG_RTLD, (Xword)radd,
2473 2473 (Xword)rc.r_size));
2474 2474 return (1);
2475 2475 }
2476 2476
2477 2477 /*
2478 2478 * Determine the symbol location of an address within a link-map. Look for
2479 2479 * the nearest symbol (whose value is less than or equal to the required
2480 2480 * address). This is the object specific part of dladdr().
2481 2481 */
2482 2482 static void
2483 2483 elf_dladdr(ulong_t addr, Rt_map *lmp, Dl_info *dlip, void **info, int flags)
2484 2484 {
2485 2485 ulong_t ndx, cnt, base, _value;
2486 2486 Sym *sym, *_sym = NULL;
2487 2487 const char *str;
2488 2488 int _flags;
2489 2489 uint_t *dynaddr_ndx;
2490 2490 uint_t dynaddr_n = 0;
2491 2491 ulong_t value;
2492 2492
2493 2493 /*
2494 2494 * If SUNWSYMTAB() is non-NULL, then it sees a special version of
2495 2495 * the dynsym that starts with any local function symbols that exist in
2496 2496 * the library and then moves to the data held in SYMTAB(). In this
2497 2497 * case, SUNWSYMSZ tells us how long the symbol table is. The
2498 2498 * availability of local function symbols will enhance the results
2499 2499 * we can provide.
2500 2500 *
2501 2501 * If SUNWSYMTAB() is non-NULL, then there might also be a
2502 2502 * SUNWSYMSORT() vector associated with it. SUNWSYMSORT() contains
2503 2503 * an array of indices into SUNWSYMTAB, sorted by increasing
2504 2504 * address. We can use this to do an O(log N) search instead of a
2505 2505 * brute force search.
2506 2506 *
2507 2507 * If SUNWSYMTAB() is NULL, then SYMTAB() references a dynsym that
2508 2508 * contains only global symbols. In that case, the length of
2509 2509 * the symbol table comes from the nchain field of the related
2510 2510 * symbol lookup hash table.
2511 2511 */
2512 2512 str = STRTAB(lmp);
2513 2513 if (SUNWSYMSZ(lmp) == NULL) {
2514 2514 sym = SYMTAB(lmp);
2515 2515 /*
2516 2516 * If we don't have a .hash table there are no symbols
2517 2517 * to look at.
2518 2518 */
2519 2519 if (HASH(lmp) == NULL)
2520 2520 return;
2521 2521 cnt = HASH(lmp)[1];
2522 2522 } else {
2523 2523 sym = SUNWSYMTAB(lmp);
2524 2524 cnt = SUNWSYMSZ(lmp) / SYMENT(lmp);
2525 2525 dynaddr_ndx = SUNWSYMSORT(lmp);
2526 2526 if (dynaddr_ndx != NULL)
2527 2527 dynaddr_n = SUNWSYMSORTSZ(lmp) / SUNWSORTENT(lmp);
2528 2528 }
2529 2529
2530 2530 if (FLAGS(lmp) & FLG_RT_FIXED)
2531 2531 base = 0;
2532 2532 else
2533 2533 base = ADDR(lmp);
2534 2534
2535 2535 if (dynaddr_n > 0) { /* Binary search */
2536 2536 long low = 0, low_bnd;
2537 2537 long high = dynaddr_n - 1, high_bnd;
2538 2538 long mid;
2539 2539 Sym *mid_sym;
2540 2540
2541 2541 /*
2542 2542 * Note that SUNWSYMSORT only contains symbols types that
2543 2543 * supply memory addresses, so there's no need to check and
2544 2544 * filter out any other types.
2545 2545 */
2546 2546 low_bnd = low;
2547 2547 high_bnd = high;
2548 2548 while (low <= high) {
2549 2549 mid = (low + high) / 2;
2550 2550 mid_sym = &sym[dynaddr_ndx[mid]];
2551 2551 value = mid_sym->st_value + base;
2552 2552 if (addr < value) {
2553 2553 if ((sym[dynaddr_ndx[high]].st_value + base) >=
2554 2554 addr)
2555 2555 high_bnd = high;
2556 2556 high = mid - 1;
2557 2557 } else if (addr > value) {
2558 2558 if ((sym[dynaddr_ndx[low]].st_value + base) <=
2559 2559 addr)
2560 2560 low_bnd = low;
2561 2561 low = mid + 1;
2562 2562 } else {
2563 2563 _sym = mid_sym;
2564 2564 _value = value;
2565 2565 break;
2566 2566 }
2567 2567 }
2568 2568 /*
2569 2569 * If the above didn't find it exactly, then we must
2570 2570 * return the closest symbol with a value that doesn't
2571 2571 * exceed the one we are looking for. If that symbol exists,
2572 2572 * it will lie in the range bounded by low_bnd and
2573 2573 * high_bnd. This is a linear search, but a short one.
2574 2574 */
2575 2575 if (_sym == NULL) {
2576 2576 for (mid = low_bnd; mid <= high_bnd; mid++) {
2577 2577 mid_sym = &sym[dynaddr_ndx[mid]];
2578 2578 value = mid_sym->st_value + base;
2579 2579 if (addr >= value) {
2580 2580 _sym = mid_sym;
2581 2581 _value = value;
2582 2582 } else {
2583 2583 break;
2584 2584 }
2585 2585 }
2586 2586 }
2587 2587 } else { /* Linear search */
2588 2588 for (_value = 0, sym++, ndx = 1; ndx < cnt; ndx++, sym++) {
2589 2589 /*
2590 2590 * Skip expected symbol types that are not functions
2591 2591 * or data:
2592 2592 * - A symbol table starts with an undefined symbol
2593 2593 * in slot 0. If we are using SUNWSYMTAB(),
2594 2594 * there will be a second undefined symbol
2595 2595 * right before the globals.
2596 2596 * - The local part of SUNWSYMTAB() contains a
2597 2597 * series of function symbols. Each section
2598 2598 * starts with an initial STT_FILE symbol.
2599 2599 */
2600 2600 if ((sym->st_shndx == SHN_UNDEF) ||
2601 2601 (ELF_ST_TYPE(sym->st_info) == STT_FILE))
2602 2602 continue;
2603 2603
2604 2604 value = sym->st_value + base;
2605 2605 if (value > addr)
2606 2606 continue;
2607 2607 if (value < _value)
2608 2608 continue;
2609 2609
2610 2610 _sym = sym;
2611 2611 _value = value;
2612 2612
2613 2613 /*
2614 2614 * Note, because we accept local and global symbols
2615 2615 * we could find a section symbol that matches the
2616 2616 * associated address, which means that the symbol
2617 2617 * name will be null. In this case continue the
2618 2618 * search in case we can find a global symbol of
2619 2619 * the same value.
2620 2620 */
2621 2621 if ((value == addr) &&
2622 2622 (ELF_ST_TYPE(sym->st_info) != STT_SECTION))
2623 2623 break;
2624 2624 }
2625 2625 }
2626 2626
2627 2627 _flags = flags & RTLD_DL_MASK;
2628 2628 if (_sym) {
2629 2629 if (_flags == RTLD_DL_SYMENT)
2630 2630 *info = (void *)_sym;
2631 2631 else if (_flags == RTLD_DL_LINKMAP)
2632 2632 *info = (void *)lmp;
2633 2633
2634 2634 dlip->dli_sname = str + _sym->st_name;
2635 2635 dlip->dli_saddr = (void *)_value;
2636 2636 } else {
2637 2637 /*
2638 2638 * addr lies between the beginning of the mapped segment and
2639 2639 * the first global symbol. We have no symbol to return
2640 2640 * and the caller requires one. We use _START_, the base
2641 2641 * address of the mapping.
2642 2642 */
2643 2643
2644 2644 if (_flags == RTLD_DL_SYMENT) {
2645 2645 /*
2646 2646 * An actual symbol struct is needed, so we
2647 2647 * construct one for _START_. To do this in a
2648 2648 * fully accurate way requires a different symbol
2649 2649 * for each mapped segment. This requires the
2650 2650 * use of dynamic memory and a mutex. That's too much
2651 2651 * plumbing for a fringe case of limited importance.
2652 2652 *
2653 2653 * Fortunately, we can simplify:
2654 2654 * - Only the st_size and st_info fields are useful
2655 2655 * outside of the linker internals. The others
2656 2656 * reference things that outside code cannot see,
2657 2657 * and can be set to 0.
2658 2658 * - It's just a label and there is no size
2659 2659 * to report. So, the size should be 0.
2660 2660 * This means that only st_info needs a non-zero
2661 2661 * (constant) value. A static struct will suffice.
2662 2662 * It must be const (readonly) so the caller can't
2663 2663 * change its meaning for subsequent callers.
2664 2664 */
2665 2665 static const Sym fsym = { 0, 0, 0,
2666 2666 ELF_ST_INFO(STB_LOCAL, STT_OBJECT) };
2667 2667 *info = (void *) &fsym;
2668 2668 }
2669 2669
2670 2670 dlip->dli_sname = MSG_ORIG(MSG_SYM_START);
2671 2671 dlip->dli_saddr = (void *) ADDR(lmp);
2672 2672 }
2673 2673 }
2674 2674
2675 2675 /*
2676 2676 * This routine is called as a last fall-back to search for a symbol from a
2677 2677 * standard relocation or dlsym(). To maintain lazy loadings goal of reducing
2678 2678 * the number of objects mapped, any symbol search is first carried out using
2679 2679 * the objects that already exist in the process (either on a link-map list or
2680 2680 * handle). If a symbol can't be found, and lazy dependencies are still
2681 2681 * pending, this routine loads the dependencies in an attempt to locate the
2682 2682 * symbol.
2683 2683 */
2684 2684 int
2685 2685 elf_lazy_find_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
2686 2686 {
2687 2687 static APlist *alist = NULL;
2688 2688 Aliste idx1;
2689 2689 Rt_map *lmp1, *lmp = slp->sl_imap, *clmp = slp->sl_cmap;
2690 2690 const char *name = slp->sl_name;
2691 2691 Slookup sl1 = *slp;
2692 2692 Lm_list *lml;
2693 2693 Lm_cntl *lmc;
2694 2694
2695 2695 /*
2696 2696 * It's quite possible we've been here before to process objects,
2697 2697 * therefore reinitialize our dynamic list.
2698 2698 */
2699 2699 if (alist)
2700 2700 aplist_reset(alist);
2701 2701
2702 2702 /*
2703 2703 * Discard any relocation index from further symbol searches. This
2704 2704 * index has already been used to trigger any necessary lazy-loads,
2705 2705 * and it might be because one of these lazy loads has failed that
2706 2706 * we're performing this fallback. By removing the relocation index
2707 2707 * we don't try and perform the same failed lazy loading activity again.
2708 2708 */
2709 2709 sl1.sl_rsymndx = 0;
2710 2710
2711 2711 /*
2712 2712 * Determine the callers link-map list so that we can monitor whether
2713 2713 * new objects have been added.
2714 2714 */
2715 2715 lml = LIST(clmp);
2716 2716 lmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, CNTL(clmp));
2717 2717
2718 2718 /*
2719 2719 * Generate a local list of new objects to process. This list can grow
2720 2720 * as each object supplies its own lazy dependencies.
2721 2721 */
2722 2722 if (aplist_append(&alist, lmp, AL_CNT_LAZYFIND) == NULL)
2723 2723 return (NULL);
2724 2724
2725 2725 for (APLIST_TRAVERSE(alist, idx1, lmp1)) {
2726 2726 uint_t dynndx;
2727 2727 Dyninfo *dip, *pdip;
2728 2728
2729 2729 /*
2730 2730 * Loop through the lazy DT_NEEDED entries examining each object
2731 2731 * for the required symbol. If the symbol is not found, the
2732 2732 * object is in turn added to the local alist, so that the
2733 2733 * objects lazy DT_NEEDED entries can be examined.
2734 2734 */
2735 2735 lmp = lmp1;
2736 2736 for (dynndx = 0, dip = DYNINFO(lmp), pdip = NULL;
2737 2737 !(dip->di_flags & FLG_DI_IGNORE); dynndx++, pdip = dip++) {
2738 2738 Grp_hdl *ghp;
2739 2739 Grp_desc *gdp;
2740 2740 Rt_map *nlmp, *llmp;
2741 2741 Slookup sl2;
2742 2742 Sresult sr;
2743 2743 Aliste idx2;
2744 2744
2745 2745 if (((dip->di_flags & FLG_DI_LAZY) == 0) ||
2746 2746 dip->di_info)
2747 2747 continue;
2748 2748
2749 2749 /*
2750 2750 * If this object has already failed to lazy load, and
2751 2751 * we're still processing the same runtime linker
2752 2752 * operation that produced the failure, don't bother
2753 2753 * to try and load the object again.
2754 2754 */
2755 2755 if ((dip->di_flags & FLG_DI_LAZYFAIL) && pdip &&
2756 2756 (pdip->di_flags & FLG_DI_POSFLAG1)) {
2757 2757 if (pdip->di_info == (void *)ld_entry_cnt)
2758 2758 continue;
2759 2759
2760 2760 dip->di_flags &= ~FLG_DI_LAZYFAIL;
2761 2761 pdip->di_info = NULL;
2762 2762 }
2763 2763
2764 2764 /*
2765 2765 * Determine the last link-map presently on the callers
2766 2766 * link-map control list.
2767 2767 */
2768 2768 llmp = lmc->lc_tail;
2769 2769
2770 2770 /*
2771 2771 * Try loading this lazy dependency. If the object
2772 2772 * can't be loaded, consider this non-fatal and continue
2773 2773 * the search. Lazy loaded dependencies need not exist
2774 2774 * and their loading should only turn out to be fatal
2775 2775 * if they are required to satisfy a relocation.
2776 2776 *
2777 2777 * A successful lazy load can mean one of two things:
2778 2778 *
2779 2779 * - new objects have been loaded, in which case the
2780 2780 * objects will have been analyzed, relocated, and
2781 2781 * finally moved to the callers control list.
2782 2782 * - the objects are already loaded, and this lazy
2783 2783 * load has simply associated the referenced object
2784 2784 * with it's lazy dependencies.
2785 2785 *
2786 2786 * If new objects are loaded, look in these objects
2787 2787 * first. Note, a new object can be the object being
2788 2788 * referenced by this lazy load, however we can also
2789 2789 * descend into multiple lazy loads as we relocate this
2790 2790 * reference.
2791 2791 *
2792 2792 * If the symbol hasn't been found, use the referenced
2793 2793 * objects handle, as it might have dependencies on
2794 2794 * objects that are already loaded. Note that existing
2795 2795 * objects might have already been searched and skipped
2796 2796 * as non-available to this caller. However, a lazy
2797 2797 * load might have caused the promotion of modes, or
2798 2798 * added this object to the family of the caller. In
2799 2799 * either case, the handle associated with the object
2800 2800 * is then used to carry out the symbol search.
2801 2801 */
2802 2802 if ((nlmp = elf_lazy_load(lmp, &sl1, dynndx, name,
2803 2803 FLG_RT_PRIHDL, &ghp, in_nfavl)) == NULL)
2804 2804 continue;
2805 2805
2806 2806 if (NEXT_RT_MAP(llmp)) {
2807 2807 /*
2808 2808 * Look in any new objects.
2809 2809 */
2810 2810 sl1.sl_imap = NEXT_RT_MAP(llmp);
2811 2811 sl1.sl_flags &= ~LKUP_STDRELOC;
2812 2812
2813 2813 /*
2814 2814 * Initialize a local symbol result descriptor,
2815 2815 * using the original symbol name.
2816 2816 */
2817 2817 SRESULT_INIT(sr, slp->sl_name);
2818 2818
2819 2819 if (lookup_sym(&sl1, &sr, binfo, in_nfavl)) {
2820 2820 *srp = sr;
2821 2821 return (1);
2822 2822 }
2823 2823 }
2824 2824
2825 2825 /*
2826 2826 * Use the objects handle to inspect the family of
2827 2827 * objects associated with the handle. Note, there's
2828 2828 * a possibility of overlap with the above search,
2829 2829 * should a lazy load bring in new objects and
2830 2830 * reference existing objects.
2831 2831 */
2832 2832 sl2 = sl1;
2833 2833 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
2834 2834 if ((gdp->gd_depend != NEXT_RT_MAP(llmp)) &&
2835 2835 (gdp->gd_flags & GPD_DLSYM)) {
2836 2836
2837 2837 sl2.sl_imap = gdp->gd_depend;
2838 2838 sl2.sl_flags |= LKUP_FIRST;
2839 2839
2840 2840 /*
2841 2841 * Initialize a local symbol result
2842 2842 * descriptor, using the original
2843 2843 * symbol name.
2844 2844 */
2845 2845 SRESULT_INIT(sr, slp->sl_name);
2846 2846
2847 2847 if (lookup_sym(&sl2, &sr, binfo,
2848 2848 in_nfavl)) {
2849 2849 *srp = sr;
2850 2850 return (1);
2851 2851 }
2852 2852 }
2853 2853 }
2854 2854
2855 2855 /*
2856 2856 * Some dlsym() operations are already traversing a
2857 2857 * link-map (dlopen(0)), and thus there's no need to
2858 2858 * save them on the dynamic dependency list.
2859 2859 */
2860 2860 if (slp->sl_flags & LKUP_NODESCENT)
2861 2861 continue;
2862 2862
2863 2863 if (aplist_test(&alist, nlmp, AL_CNT_LAZYFIND) == NULL)
2864 2864 return (0);
2865 2865 }
2866 2866 }
2867 2867
2868 2868 return (0);
2869 2869 }
2870 2870
2871 2871 /*
2872 2872 * Warning message for bad r_offset.
2873 2873 */
2874 2874 void
2875 2875 elf_reloc_bad(Rt_map *lmp, void *rel, uchar_t rtype, ulong_t roffset,
2876 2876 ulong_t rsymndx)
2877 2877 {
2878 2878 const char *name = NULL;
2879 2879 Lm_list *lml = LIST(lmp);
2880 2880 int trace;
2881 2881
2882 2882 if ((lml->lm_flags & LML_FLG_TRC_ENABLE) &&
2883 2883 (((rtld_flags & RT_FL_SILENCERR) == 0) ||
2884 2884 (lml->lm_flags & LML_FLG_TRC_VERBOSE)))
2885 2885 trace = 1;
2886 2886 else
2887 2887 trace = 0;
2888 2888
2889 2889 if ((trace == 0) && (DBG_ENABLED == 0))
2890 2890 return;
2891 2891
2892 2892 if (rsymndx) {
2893 2893 Sym *symref = (Sym *)((ulong_t)SYMTAB(lmp) +
2894 2894 (rsymndx * SYMENT(lmp)));
2895 2895
2896 2896 if (ELF_ST_BIND(symref->st_info) != STB_LOCAL)
2897 2897 name = (char *)(STRTAB(lmp) + symref->st_name);
2898 2898 }
2899 2899
2900 2900 if (name == NULL)
2901 2901 name = MSG_INTL(MSG_STR_UNKNOWN);
2902 2902
2903 2903 if (trace) {
2904 2904 const char *rstr;
2905 2905
2906 2906 rstr = _conv_reloc_type((uint_t)rtype);
2907 2907 (void) printf(MSG_INTL(MSG_LDD_REL_ERR1), rstr, name,
2908 2908 EC_ADDR(roffset));
2909 2909 return;
2910 2910 }
2911 2911
2912 2912 Dbg_reloc_error(lml, ELF_DBG_RTLD, M_MACH, M_REL_SHT_TYPE, rel, name);
2913 2913 }
2914 2914
2915 2915 /*
2916 2916 * Resolve a static TLS relocation.
2917 2917 */
2918 2918 long
2919 2919 elf_static_tls(Rt_map *lmp, Sym *sym, void *rel, uchar_t rtype, char *name,
2920 2920 ulong_t roffset, long value)
2921 2921 {
2922 2922 Lm_list *lml = LIST(lmp);
2923 2923
2924 2924 /*
2925 2925 * Relocations against a static TLS block have limited support once
2926 2926 * process initialization has completed. Any error condition should be
2927 2927 * discovered by testing for DF_STATIC_TLS as part of loading an object,
2928 2928 * however individual relocations are tested in case the dynamic flag
2929 2929 * had not been set when this object was built.
2930 2930 */
2931 2931 if (PTTLS(lmp) == NULL) {
2932 2932 DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
2933 2933 M_REL_SHT_TYPE, rel, NULL, 0, name));
2934 2934 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
2935 2935 _conv_reloc_type((uint_t)rtype), NAME(lmp),
2936 2936 name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
2937 2937 return (0);
2938 2938 }
2939 2939
2940 2940 /*
2941 2941 * If no static TLS has been set aside for this object, determine if
2942 2942 * any can be obtained. Enforce that any object using static TLS is
2943 2943 * non-deletable.
2944 2944 */
2945 2945 if (TLSSTATOFF(lmp) == 0) {
2946 2946 FLAGS1(lmp) |= FL1_RT_TLSSTAT;
2947 2947 MODE(lmp) |= RTLD_NODELETE;
2948 2948
2949 2949 if (tls_assign(lml, lmp, PTTLS(lmp)) == 0) {
2950 2950 DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH,
2951 2951 M_REL_SHT_TYPE, rel, NULL, 0, name));
2952 2952 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
2953 2953 _conv_reloc_type((uint_t)rtype), NAME(lmp),
2954 2954 name ? demangle(name) : MSG_INTL(MSG_STR_UNKNOWN));
2955 2955 return (0);
2956 2956 }
2957 2957 }
2958 2958
2959 2959 /*
2960 2960 * Typically, a static TLS offset is maintained as a symbols value.
2961 2961 * For local symbols that are not apart of the dynamic symbol table,
2962 2962 * the TLS relocation points to a section symbol, and the static TLS
2963 2963 * offset was deposited in the associated GOT table. Make sure the GOT
2964 2964 * is cleared, so that the value isn't reused in do_reloc().
2965 2965 */
2966 2966 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
2967 2967 if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION)) {
2968 2968 value = *(long *)roffset;
2969 2969 *(long *)roffset = 0;
2970 2970 } else {
2971 2971 value = sym->st_value;
2972 2972 }
2973 2973 }
2974 2974 return (-(TLSSTATOFF(lmp) - value));
2975 2975 }
2976 2976
2977 2977 /*
2978 2978 * If the symbol is not found and the reference was not to a weak symbol, report
2979 2979 * an error. Weak references may be unresolved.
2980 2980 */
2981 2981 int
2982 2982 elf_reloc_error(Rt_map *lmp, const char *name, void *rel, uint_t binfo)
2983 2983 {
2984 2984 Lm_list *lml = LIST(lmp);
2985 2985
2986 2986 /*
2987 2987 * Under crle(1), relocation failures are ignored.
2988 2988 */
2989 2989 if (lml->lm_flags & LML_FLG_IGNRELERR)
2990 2990 return (1);
2991 2991
2992 2992 /*
2993 2993 * Under ldd(1), unresolved references are reported. However, if the
2994 2994 * original reference is EXTERN or PARENT these references are ignored
2995 2995 * unless ldd's -p option is in effect.
2996 2996 */
2997 2997 if (lml->lm_flags & LML_FLG_TRC_WARN) {
2998 2998 if (((binfo & DBG_BINFO_REF_MSK) == 0) ||
2999 2999 ((lml->lm_flags & LML_FLG_TRC_NOPAREXT) != 0)) {
3000 3000 (void) printf(MSG_INTL(MSG_LDD_SYM_NFOUND),
3001 3001 demangle(name), NAME(lmp));
3002 3002 }
3003 3003 return (1);
3004 3004 }
3005 3005
3006 3006 /*
3007 3007 * Otherwise, the unresolved references is fatal.
3008 3008 */
3009 3009 DBG_CALL(Dbg_reloc_in(lml, ELF_DBG_RTLD, M_MACH, M_REL_SHT_TYPE, rel,
3010 3010 NULL, 0, name));
3011 3011 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
3012 3012 demangle(name));
3013 3013
3014 3014 return (0);
3015 3015 }
↓ open down ↓ |
647 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX