1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
25 *
26 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
27 */
28
29 /*
30 * SPARC machine dependent and ELF file class dependent functions.
31 * Contains routines for performing function binding and symbol relocations.
32 */
33
34 #include <stdio.h>
35 #include <sys/elf.h>
36 #include <sys/elf_SPARC.h>
37 #include <sys/mman.h>
38 #include <dlfcn.h>
39 #include <synch.h>
40 #include <string.h>
41 #include <debug.h>
42 #include <reloc.h>
43 #include <conv.h>
44 #include "_rtld.h"
45 #include "_audit.h"
46 #include "_elf.h"
47 #include "_inline_gen.h"
48 #include "_inline_reloc.h"
49 #include "msg.h"
50
51 extern void iflush_range(caddr_t, size_t);
52 extern void plt_full_range(uintptr_t, uintptr_t);
53
54 int
elf_mach_flags_check(Rej_desc * rej,Ehdr * ehdr)55 elf_mach_flags_check(Rej_desc *rej, Ehdr *ehdr)
56 {
57 /*
58 * Check machine type and flags.
59 */
60 if (ehdr->e_machine != EM_SPARC) {
61 if (ehdr->e_machine != EM_SPARC32PLUS) {
62 rej->rej_type = SGS_REJ_MACH;
63 rej->rej_info = (uint_t)ehdr->e_machine;
64 return (0);
65 }
66 if ((ehdr->e_flags & EF_SPARC_32PLUS) == 0) {
67 rej->rej_type = SGS_REJ_MISFLAG;
68 rej->rej_info = (uint_t)ehdr->e_flags;
69 return (0);
70 }
71 if ((ehdr->e_flags & ~at_flags) & EF_SPARC_32PLUS_MASK) {
72 rej->rej_type = SGS_REJ_BADFLAG;
73 rej->rej_info = (uint_t)ehdr->e_flags;
74 return (0);
75 }
76 } else if ((ehdr->e_flags & ~EF_SPARCV9_MM) != 0) {
77 rej->rej_type = SGS_REJ_BADFLAG;
78 rej->rej_info = (uint_t)ehdr->e_flags;
79 return (0);
80 }
81 return (1);
82 }
83
84 void
ldso_plt_init(Rt_map * lmp)85 ldso_plt_init(Rt_map *lmp)
86 {
87 /*
88 * There is no need to analyze ld.so because we don't map in any of
89 * its dependencies. However we may map these dependencies in later
90 * (as if ld.so had dlopened them), so initialize the plt and the
91 * permission information.
92 */
93 if (PLTGOT(lmp))
94 elf_plt_init((PLTGOT(lmp)), (caddr_t)lmp);
95 }
96
97 /*
98 * elf_plt_write() will test to see how far away our destination
99 * address lies. If it is close enough that a branch can
100 * be used instead of a jmpl - we will fill the plt in with
101 * single branch. The branches are much quicker then
102 * a jmpl instruction - see bug#4356879 for further
103 * details.
104 *
105 * NOTE: we pass in both a 'pltaddr' and a 'vpltaddr' since
106 * librtld/dldump update PLT's who's physical
107 * address is not the same as the 'virtual' runtime
108 * address.
109 */
110 Pltbindtype
111 /* ARGSUSED4 */
elf_plt_write(uintptr_t addr,uintptr_t vaddr,void * rptr,uintptr_t symval,Xword pltndx)112 elf_plt_write(uintptr_t addr, uintptr_t vaddr, void *rptr, uintptr_t symval,
113 Xword pltndx)
114 {
115 Rela *rel = (Rela *)rptr;
116 uintptr_t vpltaddr, pltaddr;
117 long disp;
118
119 pltaddr = addr + rel->r_offset;
120 vpltaddr = vaddr + rel->r_offset;
121 disp = symval - vpltaddr - 4;
122
123 /*
124 * Test if the destination address is close enough to use
125 * a ba,a... instruction to reach it.
126 */
127 if (S_INRANGE(disp, 23) && !(rtld_flags & RT_FL_NOBAPLT)) {
128 uint_t *pltent, bainstr;
129 Pltbindtype rc;
130
131 pltent = (uint_t *)pltaddr;
132
133 /*
134 * The
135 *
136 * ba,a,pt %icc, <dest>
137 *
138 * is the most efficient of the PLT's. If we
139 * are within +-20 bits *and* running on a
140 * v8plus architecture - use that branch.
141 */
142 if ((at_flags & EF_SPARC_32PLUS) &&
143 S_INRANGE(disp, 20)) {
144 bainstr = M_BA_A_PT; /* ba,a,pt %icc,<dest> */
145 bainstr |= (S_MASK(19) & (disp >> 2));
146 rc = PLT_T_21D;
147 DBG_CALL(pltcnt21d++);
148 } else {
149 /*
150 * Otherwise - we fall back to the good old
151 *
152 * ba,a <dest>
153 *
154 * Which still beats a jmpl instruction.
155 */
156 bainstr = M_BA_A; /* ba,a <dest> */
157 bainstr |= (S_MASK(22) & (disp >> 2));
158 rc = PLT_T_24D;
159 DBG_CALL(pltcnt24d++);
160 }
161
162 pltent[2] = M_NOP; /* nop instr */
163 pltent[1] = bainstr;
164
165 iflush_range((char *)(&pltent[1]), 4);
166 pltent[0] = M_NOP; /* nop instr */
167 iflush_range((char *)(&pltent[0]), 4);
168 return (rc);
169 }
170
171 /*
172 * The PLT destination is not in reach of
173 * a branch instruction - so we fall back
174 * to a 'jmpl' sequence.
175 */
176 plt_full_range(pltaddr, symval);
177 DBG_CALL(pltcntfull++);
178 return (PLT_T_FULL);
179 }
180
181 /*
182 * Local storage space created on the stack created for this glue
183 * code includes space for:
184 * 0x4 pointer to dyn_data
185 * 0x4 size prev stack frame
186 */
187 static const uchar_t dyn_plt_template[] = {
188 /* 0x00 */ 0x80, 0x90, 0x00, 0x1e, /* tst %fp */
189 /* 0x04 */ 0x02, 0x80, 0x00, 0x04, /* be 0x14 */
190 /* 0x08 */ 0x82, 0x27, 0x80, 0x0e, /* sub %sp, %fp, %g1 */
191 /* 0x0c */ 0x10, 0x80, 0x00, 0x03, /* ba 0x20 */
192 /* 0x10 */ 0x01, 0x00, 0x00, 0x00, /* nop */
193 /* 0x14 */ 0x82, 0x10, 0x20, 0x60, /* mov 0x60, %g1 */
194 /* 0x18 */ 0x9d, 0xe3, 0xbf, 0x98, /* save %sp, -0x68, %sp */
195 /* 0x1c */ 0xc2, 0x27, 0xbf, 0xf8, /* st %g1, [%fp + -0x8] */
196 /* 0x20 */ 0x03, 0x00, 0x00, 0x00, /* sethi %hi(val), %g1 */
197 /* 0x24 */ 0x82, 0x10, 0x60, 0x00, /* or %g1, %lo(val), %g1 */
198 /* 0x28 */ 0x40, 0x00, 0x00, 0x00, /* call <rel_addr> */
199 /* 0x2c */ 0xc2, 0x27, 0xbf, 0xfc /* st %g1, [%fp + -0x4] */
200 };
201
202 int dyn_plt_ent_size = sizeof (dyn_plt_template) +
203 sizeof (uintptr_t) + /* reflmp */
204 sizeof (uintptr_t) + /* deflmp */
205 sizeof (ulong_t) + /* symndx */
206 sizeof (ulong_t) + /* sb_flags */
207 sizeof (Sym); /* symdef */
208
209 /*
210 * the dynamic plt entry is:
211 *
212 * tst %fp
213 * be 1f
214 * nop
215 * sub %sp, %fp, %g1
216 * ba 2f
217 * nop
218 * 1:
219 * mov SA(MINFRAME), %g1 ! if %fp is null this is the
220 * ! 'minimum stack'. %fp is null
221 * ! on the initial stack frame
222 * 2:
223 * save %sp, -(SA(MINFRAME) + 2 * CLONGSIZE), %sp
224 * st %g1, [%fp + -0x8] ! store prev_stack size in [%fp - 8]
225 * sethi %hi(dyn_data), %g1
226 * or %g1, %lo(dyn_data), %g1
227 * call elf_plt_trace
228 * st %g1, [%fp + -0x4] ! store dyn_data ptr in [%fp - 4]
229 * dyn data:
230 * uintptr_t reflmp
231 * uintptr_t deflmp
232 * ulong_t symndx
233 * ulong_t sb_flags
234 * Sym symdef
235 */
236 static caddr_t
elf_plt_trace_write(caddr_t addr,Rela * rptr,Rt_map * rlmp,Rt_map * dlmp,Sym * sym,ulong_t symndx,ulong_t pltndx,caddr_t to,ulong_t sb_flags,int * fail)237 elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp,
238 Sym *sym, ulong_t symndx, ulong_t pltndx, caddr_t to, ulong_t sb_flags,
239 int *fail)
240 {
241 extern ulong_t elf_plt_trace();
242 uchar_t *dyn_plt;
243 uintptr_t *dyndata;
244
245 /*
246 * If both pltenter & pltexit have been disabled there
247 * there is no reason to even create the glue code.
248 */
249 if ((sb_flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) ==
250 (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) {
251 (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr,
252 rptr, (uintptr_t)to, pltndx);
253 return (to);
254 }
255
256 /*
257 * We only need to add the glue code if there is an auditing
258 * library that is interested in this binding.
259 */
260 dyn_plt = (uchar_t *)((uintptr_t)AUDINFO(rlmp)->ai_dynplts +
261 (pltndx * dyn_plt_ent_size));
262
263 /*
264 * Have we initialized this dynamic plt entry yet? If we haven't do it
265 * now. Otherwise this function has been called before, but from a
266 * different plt (ie. from another shared object). In that case
267 * we just set the plt to point to the new dyn_plt.
268 */
269 if (*dyn_plt == 0) {
270 Sym *symp;
271 Xword symvalue;
272 Lm_list *lml = LIST(rlmp);
273
274 (void) memcpy((void *)dyn_plt, dyn_plt_template,
275 sizeof (dyn_plt_template));
276 dyndata = (uintptr_t *)((uintptr_t)dyn_plt +
277 sizeof (dyn_plt_template));
278
279 /*
280 * relocating:
281 * sethi %hi(dyndata), %g1
282 */
283 symvalue = (Xword)dyndata;
284 if (do_reloc_rtld(R_SPARC_HI22, (dyn_plt + 0x20),
285 &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA),
286 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
287 *fail = 1;
288 return (0);
289 }
290
291 /*
292 * relocating:
293 * or %g1, %lo(dyndata), %g1
294 */
295 symvalue = (Xword)dyndata;
296 if (do_reloc_rtld(R_SPARC_LO10, (dyn_plt + 0x24),
297 &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA),
298 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
299 *fail = 1;
300 return (0);
301 }
302
303 /*
304 * relocating:
305 * call elf_plt_trace
306 */
307 symvalue = (Xword)((uintptr_t)&elf_plt_trace -
308 (uintptr_t)(dyn_plt + 0x28));
309 if (do_reloc_rtld(R_SPARC_WDISP30, (dyn_plt + 0x28),
310 &symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE),
311 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) {
312 *fail = 1;
313 return (0);
314 }
315
316 *dyndata++ = (uintptr_t)rlmp;
317 *dyndata++ = (uintptr_t)dlmp;
318 *(ulong_t *)dyndata++ = symndx;
319 *(ulong_t *)dyndata++ = sb_flags;
320 symp = (Sym *)dyndata;
321 *symp = *sym;
322 symp->st_name += (Word)STRTAB(dlmp);
323 symp->st_value = (Addr)to;
324
325 iflush_range((void *)dyn_plt, sizeof (dyn_plt_template));
326 }
327
328 (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr, rptr,
329 (uintptr_t)dyn_plt, 0);
330 return ((caddr_t)dyn_plt);
331 }
332
333 /*
334 * Function binding routine - invoked on the first call to a function through
335 * the procedure linkage table;
336 * passes first through an assembly language interface.
337 *
338 * Takes the address of the PLT entry where the call originated,
339 * the offset into the relocation table of the associated
340 * relocation entry and the address of the link map (rt_private_map struct)
341 * for the entry.
342 *
343 * Returns the address of the function referenced after re-writing the PLT
344 * entry to invoke the function directly.
345 *
346 * On error, causes process to terminate with a signal.
347 */
348 ulong_t
elf_bndr(Rt_map * lmp,ulong_t pltoff,caddr_t from)349 elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from)
350 {
351 Rt_map *nlmp, *llmp;
352 ulong_t addr, vaddr, reloff, symval, rsymndx;
353 char *name;
354 Rela *rptr;
355 Sym *rsym, *nsym;
356 Xword pltndx;
357 uint_t binfo, sb_flags = 0, dbg_class;
358 Slookup sl;
359 Sresult sr;
360 Pltbindtype pbtype;
361 int entry, lmflags;
362 Lm_list *lml;
363
364 /*
365 * For compatibility with libthread (TI_VERSION 1) we track the entry
366 * value. A zero value indicates we have recursed into ld.so.1 to
367 * further process a locking request. Under this recursion we disable
368 * tsort and cleanup activities.
369 */
370 entry = enter(0);
371
372 lml = LIST(lmp);
373 if ((lmflags = lml->lm_flags) & LML_FLG_RTLDLM) {
374 dbg_class = dbg_desc->d_class;
375 dbg_desc->d_class = 0;
376 }
377
378 /*
379 * Must calculate true plt relocation address from reloc.
380 * Take offset, subtract number of reserved PLT entries, and divide
381 * by PLT entry size, which should give the index of the plt
382 * entry (and relocation entry since they have been defined to be
383 * in the same order). Then we must multiply by the size of
384 * a relocation entry, which will give us the offset of the
385 * plt relocation entry from the start of them given by JMPREL(lm).
386 */
387 addr = pltoff - M_PLT_RESERVSZ;
388 pltndx = addr / M_PLT_ENTSIZE;
389
390 /*
391 * Perform some basic sanity checks. If we didn't get a load map
392 * or the plt offset is invalid then its possible someone has walked
393 * over the plt entries or jumped to plt[0] out of the blue.
394 */
395 if (!lmp || ((addr % M_PLT_ENTSIZE) != 0)) {
396 Conv_inv_buf_t inv_buf;
397
398 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_PLTREF),
399 conv_reloc_SPARC_type(R_SPARC_JMP_SLOT, 0, &inv_buf),
400 EC_NATPTR(lmp), EC_XWORD(pltoff), EC_NATPTR(from));
401 rtldexit(lml, 1);
402 }
403 reloff = pltndx * sizeof (Rela);
404
405 /*
406 * Use relocation entry to get symbol table entry and symbol name.
407 */
408 addr = (ulong_t)JMPREL(lmp);
409 rptr = (Rela *)(addr + reloff);
410 rsymndx = ELF_R_SYM(rptr->r_info);
411 rsym = (Sym *)((ulong_t)SYMTAB(lmp) + (rsymndx * SYMENT(lmp)));
412 name = (char *)(STRTAB(lmp) + rsym->st_name);
413
414 /*
415 * Determine the last link-map of this list, this'll be the starting
416 * point for any tsort() processing.
417 */
418 llmp = lml->lm_tail;
419
420 /*
421 * Find definition for symbol. Initialize the symbol lookup, and
422 * symbol result, data structures.
423 */
424 SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0,
425 rsymndx, rsym, 0, LKUP_DEFT);
426 SRESULT_INIT(sr, name);
427
428 if (lookup_sym(&sl, &sr, &binfo, NULL) == 0) {
429 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp),
430 demangle(name));
431 rtldexit(lml, 1);
432 }
433
434 name = (char *)sr.sr_name;
435 nlmp = sr.sr_dmap;
436 nsym = sr.sr_sym;
437
438 symval = nsym->st_value;
439
440 if (!(FLAGS(nlmp) & FLG_RT_FIXED) &&
441 (nsym->st_shndx != SHN_ABS))
442 symval += ADDR(nlmp);
443 if ((lmp != nlmp) && ((FLAGS1(nlmp) & FL1_RT_NOINIFIN) == 0)) {
444 /*
445 * Record that this new link map is now bound to the caller.
446 */
447 if (bind_one(lmp, nlmp, BND_REFER) == 0)
448 rtldexit(lml, 1);
449 }
450
451 if ((lml->lm_tflags | AFLAGS(lmp)) & LML_TFLG_AUD_SYMBIND) {
452 ulong_t symndx = (((uintptr_t)nsym -
453 (uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
454
455 symval = audit_symbind(lmp, nlmp, nsym, symndx, symval,
456 &sb_flags);
457 }
458
459 if (FLAGS(lmp) & FLG_RT_FIXED)
460 vaddr = 0;
461 else
462 vaddr = ADDR(lmp);
463
464 pbtype = PLT_T_NONE;
465 if (!(rtld_flags & RT_FL_NOBIND)) {
466 if (((lml->lm_tflags | AFLAGS(lmp)) &
467 (LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
468 AUDINFO(lmp)->ai_dynplts) {
469 int fail = 0;
470 ulong_t symndx = (((uintptr_t)nsym -
471 (uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp));
472
473 symval = (ulong_t)elf_plt_trace_write((caddr_t)vaddr,
474 rptr, lmp, nlmp, nsym, symndx, pltndx,
475 (caddr_t)symval, sb_flags, &fail);
476 if (fail)
477 rtldexit(lml, 1);
478 } else {
479 /*
480 * Write standard PLT entry to jump directly
481 * to newly bound function.
482 */
483 pbtype = elf_plt_write((uintptr_t)vaddr,
484 (uintptr_t)vaddr, rptr, symval, pltndx);
485 }
486 }
487
488 /*
489 * Print binding information and rebuild PLT entry.
490 */
491 DBG_CALL(Dbg_bind_global(lmp, (Addr)from, (Off)(from - ADDR(lmp)),
492 pltndx, pbtype, nlmp, (Addr)symval, nsym->st_value, name, binfo));
493
494 /*
495 * Complete any processing for newly loaded objects. Note we don't
496 * know exactly where any new objects are loaded (we know the object
497 * that supplied the symbol, but others may have been loaded lazily as
498 * we searched for the symbol), so sorting starts from the last
499 * link-map know on entry to this routine.
500 */
501 if (entry)
502 load_completion(llmp);
503
504 /*
505 * Some operations like dldump() or dlopen()'ing a relocatable object
506 * result in objects being loaded on rtld's link-map, make sure these
507 * objects are initialized also.
508 */
509 if ((LIST(nlmp)->lm_flags & LML_FLG_RTLDLM) && LIST(nlmp)->lm_init)
510 load_completion(nlmp);
511
512 /*
513 * Make sure the object to which we've bound has had it's .init fired.
514 * Cleanup before return to user code.
515 */
516 if (entry) {
517 is_dep_init(nlmp, lmp);
518 leave(lml, 0);
519 }
520
521 if (lmflags & LML_FLG_RTLDLM)
522 dbg_desc->d_class = dbg_class;
523
524 return (symval);
525 }
526
527 /*
528 * Read and process the relocations for one link object, we assume all
529 * relocation sections for loadable segments are stored contiguously in
530 * the file.
531 */
532 int
elf_reloc(Rt_map * lmp,uint_t plt,int * in_nfavl,APlist ** textrel)533 elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl, APlist **textrel)
534 {
535 ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend;
536 ulong_t dsymndx, pltndx, roffset, rsymndx, psymndx = 0;
537 uchar_t rtype;
538 long reladd, value, pvalue, relacount = RELACOUNT(lmp);
539 Sym *symref, *psymref, *symdef, *psymdef;
540 Syminfo *sip;
541 char *name, *pname;
542 Rt_map *_lmp, *plmp;
543 int ret = 1, noplt = 0;
544 Rela *rel;
545 Pltbindtype pbtype;
546 uint_t binfo, pbinfo;
547 APlist *bound = NULL;
548
549 /*
550 * If an object has any DT_REGISTER entries associated with
551 * it, they are processed now.
552 */
553 if ((plt == 0) && (FLAGS(lmp) & FLG_RT_REGSYMS)) {
554 if (elf_regsyms(lmp) == 0)
555 return (0);
556 }
557
558 /*
559 * Although only necessary for lazy binding, initialize the first
560 * procedure linkage table entry to go to elf_rtbndr(). dbx(1) seems
561 * to find this useful.
562 */
563 if ((plt == 0) && PLTGOT(lmp)) {
564 mmapobj_result_t *mpp;
565
566 /*
567 * Make sure the segment is writable.
568 */
569 if ((((mpp =
570 find_segment((caddr_t)PLTGOT(lmp), lmp)) != NULL) &&
571 ((mpp->mr_prot & PROT_WRITE) == 0)) &&
572 ((set_prot(lmp, mpp, 1) == 0) ||
573 (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL)))
574 return (0);
575
576 elf_plt_init(PLTGOT(lmp), (caddr_t)lmp);
577 }
578
579 /*
580 * Initialize the plt start and end addresses.
581 */
582 if ((pltbgn = (ulong_t)JMPREL(lmp)) != 0)
583 pltend = pltbgn + (ulong_t)(PLTRELSZ(lmp));
584
585 /*
586 * If we've been called upon to promote an RTLD_LAZY object to an
587 * RTLD_NOW then we're only interested in scaning the .plt table.
588 */
589 if (plt) {
590 relbgn = pltbgn;
591 relend = pltend;
592 } else {
593 /*
594 * The relocation sections appear to the run-time linker as a
595 * single table. Determine the address of the beginning and end
596 * of this table. There are two different interpretations of
597 * the ABI at this point:
598 *
599 * - The REL table and its associated RELSZ indicate the
600 * concatenation of *all* relocation sections (this is the
601 * model our link-editor constructs).
602 *
603 * - The REL table and its associated RELSZ indicate the
604 * concatenation of all *but* the .plt relocations. These
605 * relocations are specified individually by the JMPREL and
606 * PLTRELSZ entries.
607 *
608 * Determine from our knowledege of the relocation range and
609 * .plt range, the range of the total relocation table. Note
610 * that one other ABI assumption seems to be that the .plt
611 * relocations always follow any other relocations, the
612 * following range checking drops that assumption.
613 */
614 relbgn = (ulong_t)(REL(lmp));
615 relend = relbgn + (ulong_t)(RELSZ(lmp));
616 if (pltbgn) {
617 if (!relbgn || (relbgn > pltbgn))
618 relbgn = pltbgn;
619 if (!relbgn || (relend < pltend))
620 relend = pltend;
621 }
622 }
623 if (!relbgn || (relbgn == relend)) {
624 DBG_CALL(Dbg_reloc_run(lmp, 0, plt, DBG_REL_NONE));
625 return (1);
626 }
627
628 relsiz = (ulong_t)(RELENT(lmp));
629 basebgn = ADDR(lmp);
630
631 DBG_CALL(Dbg_reloc_run(lmp, M_REL_SHT_TYPE, plt, DBG_REL_START));
632
633 /*
634 * If we're processing in lazy mode there is no need to scan the
635 * .rela.plt table.
636 */
637 if (pltbgn && ((MODE(lmp) & RTLD_NOW) == 0))
638 noplt = 1;
639
640 sip = SYMINFO(lmp);
641 /*
642 * Loop through relocations.
643 */
644 while (relbgn < relend) {
645 mmapobj_result_t *mpp;
646 uint_t sb_flags = 0;
647 Addr vaddr;
648
649 rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
650
651 /*
652 * If this is a RELATIVE relocation in a shared object (the
653 * common case), and if we are not debugging, then jump into one
654 * of the tighter relocation loops.
655 */
656 if ((rtype == R_SPARC_RELATIVE) &&
657 ((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) {
658 if (relacount) {
659 relbgn = elf_reloc_relative_count(relbgn,
660 relacount, relsiz, basebgn, lmp,
661 textrel, 0);
662 relacount = 0;
663 } else {
664 relbgn = elf_reloc_relative(relbgn, relend,
665 relsiz, basebgn, lmp, textrel, 0);
666 }
667 if (relbgn >= relend)
668 break;
669 rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH);
670 }
671
672 roffset = ((Rela *)relbgn)->r_offset;
673
674 reladd = (long)(((Rela *)relbgn)->r_addend);
675 rsymndx = ELF_R_SYM(((Rela *)relbgn)->r_info);
676 rel = (Rela *)relbgn;
677 relbgn += relsiz;
678
679 /*
680 * Optimizations.
681 */
682 if (rtype == R_SPARC_NONE)
683 continue;
684 if (noplt && ((ulong_t)rel >= pltbgn) &&
685 ((ulong_t)rel < pltend)) {
686 relbgn = pltend;
687 continue;
688 }
689
690 if (rtype != R_SPARC_REGISTER) {
691 /*
692 * If this is a shared object, add the base address
693 * to offset.
694 */
695 if (!(FLAGS(lmp) & FLG_RT_FIXED))
696 roffset += basebgn;
697
698 /*
699 * If this relocation is not against part of the image
700 * mapped into memory we skip it.
701 */
702 if ((mpp = find_segment((caddr_t)roffset,
703 lmp)) == NULL) {
704 elf_reloc_bad(lmp, (void *)rel, rtype, roffset,
705 rsymndx);
706 continue;
707 }
708 }
709
710 /*
711 * If we're promoting .plts, try and determine if this one has
712 * already been written. An uninitialized .plts' second
713 * instruction is a branch. Note, elf_plt_write() optimizes
714 * .plt relocations, and it's possible that a relocated entry
715 * is a branch. If this is the case, we can't tell the
716 * difference between an uninitialized .plt and a relocated,
717 * .plt that uses a branch. In this case, we'll simply redo
718 * the relocation calculation, which is a bit sad.
719 */
720 if (plt) {
721 ulong_t *_roffset = (ulong_t *)roffset;
722
723 _roffset++;
724 if ((*_roffset & (~(S_MASK(22)))) != M_BA_A)
725 continue;
726 }
727
728 binfo = 0;
729 pltndx = (ulong_t)-1;
730 pbtype = PLT_T_NONE;
731
732 /*
733 * If a symbol index is specified then get the symbol table
734 * entry, locate the symbol definition, and determine its
735 * address.
736 */
737 if (rsymndx) {
738 /*
739 * If a Syminfo section is provided, determine if this
740 * symbol is deferred, and if so, skip this relocation.
741 */
742 if (sip && is_sym_deferred((ulong_t)rel, basebgn, lmp,
743 textrel, sip, rsymndx))
744 continue;
745
746 /*
747 * Get the local symbol table entry.
748 */
749 symref = (Sym *)((ulong_t)SYMTAB(lmp) +
750 (rsymndx * SYMENT(lmp)));
751
752 /*
753 * If this is a local symbol, just use the base address.
754 * (we should have no local relocations in the
755 * executable).
756 */
757 if (ELF_ST_BIND(symref->st_info) == STB_LOCAL) {
758 value = basebgn;
759 name = NULL;
760
761 /*
762 * Special case TLS relocations.
763 */
764 if (rtype == R_SPARC_TLS_DTPMOD32) {
765 /*
766 * Use the TLS modid.
767 */
768 value = TLSMODID(lmp);
769
770 } else if (rtype == R_SPARC_TLS_TPOFF32) {
771 if ((value = elf_static_tls(lmp, symref,
772 rel, rtype, 0, roffset, 0)) == 0) {
773 ret = 0;
774 break;
775 }
776 }
777 } else {
778 /*
779 * If the symbol index is equal to the previous
780 * symbol index relocation we processed then
781 * reuse the previous values. (Note that there
782 * have been cases where a relocation exists
783 * against a copy relocation symbol, our ld(1)
784 * should optimize this away, but make sure we
785 * don't use the same symbol information should
786 * this case exist).
787 */
788 if ((rsymndx == psymndx) &&
789 (rtype != R_SPARC_COPY)) {
790 /* LINTED */
791 if (psymdef == 0) {
792 DBG_CALL(Dbg_bind_weak(lmp,
793 (Addr)roffset, (Addr)
794 (roffset - basebgn), name));
795 continue;
796 }
797 /* LINTED */
798 value = pvalue;
799 /* LINTED */
800 name = pname;
801 symdef = psymdef;
802 /* LINTED */
803 symref = psymref;
804 /* LINTED */
805 _lmp = plmp;
806 /* LINTED */
807 binfo = pbinfo;
808
809 if ((LIST(_lmp)->lm_tflags |
810 AFLAGS(_lmp)) &
811 LML_TFLG_AUD_SYMBIND) {
812 value = audit_symbind(lmp, _lmp,
813 /* LINTED */
814 symdef, dsymndx, value,
815 &sb_flags);
816 }
817 } else {
818 Slookup sl;
819 Sresult sr;
820
821 /*
822 * Lookup the symbol definition.
823 * Initialize the symbol lookup, and
824 * symbol result, data structures.
825 */
826 name = (char *)(STRTAB(lmp) +
827 symref->st_name);
828
829 SLOOKUP_INIT(sl, name, lmp, 0,
830 ld_entry_cnt, 0, rsymndx, symref,
831 rtype, LKUP_STDRELOC);
832 SRESULT_INIT(sr, name);
833 symdef = NULL;
834
835 if (lookup_sym(&sl, &sr, &binfo,
836 in_nfavl)) {
837 name = (char *)sr.sr_name;
838 _lmp = sr.sr_dmap;
839 symdef = sr.sr_sym;
840 }
841
842 /*
843 * If the symbol is not found and the
844 * reference was not to a weak symbol,
845 * report an error. Weak references
846 * may be unresolved.
847 */
848 /* BEGIN CSTYLED */
849 if (symdef == 0) {
850 if (sl.sl_bind != STB_WEAK) {
851 if (elf_reloc_error(lmp, name,
852 rel, binfo))
853 continue;
854
855 ret = 0;
856 break;
857
858 } else {
859 psymndx = rsymndx;
860 psymdef = 0;
861
862 DBG_CALL(Dbg_bind_weak(lmp,
863 (Addr)roffset, (Addr)
864 (roffset - basebgn), name));
865 continue;
866 }
867 }
868 /* END CSTYLED */
869
870 /*
871 * If symbol was found in an object
872 * other than the referencing object
873 * then record the binding.
874 */
875 if ((lmp != _lmp) && ((FLAGS1(_lmp) &
876 FL1_RT_NOINIFIN) == 0)) {
877 if (aplist_test(&bound, _lmp,
878 AL_CNT_RELBIND) == 0) {
879 ret = 0;
880 break;
881 }
882 }
883
884 /*
885 * Calculate the location of definition;
886 * symbol value plus base address of
887 * containing shared object.
888 */
889 if (IS_SIZE(rtype))
890 value = symdef->st_size;
891 else
892 value = symdef->st_value;
893
894 if (!(FLAGS(_lmp) & FLG_RT_FIXED) &&
895 !(IS_SIZE(rtype)) &&
896 (symdef->st_shndx != SHN_ABS) &&
897 (ELF_ST_TYPE(symdef->st_info) !=
898 STT_TLS))
899 value += ADDR(_lmp);
900
901 /*
902 * Retain this symbol index and the
903 * value in case it can be used for the
904 * subsequent relocations.
905 */
906 if (rtype != R_SPARC_COPY) {
907 psymndx = rsymndx;
908 pvalue = value;
909 pname = name;
910 psymdef = symdef;
911 psymref = symref;
912 plmp = _lmp;
913 pbinfo = binfo;
914 }
915 if ((LIST(_lmp)->lm_tflags |
916 AFLAGS(_lmp)) &
917 LML_TFLG_AUD_SYMBIND) {
918 dsymndx = (((uintptr_t)symdef -
919 (uintptr_t)SYMTAB(_lmp)) /
920 SYMENT(_lmp));
921 value = audit_symbind(lmp, _lmp,
922 symdef, dsymndx, value,
923 &sb_flags);
924 }
925 }
926
927 /*
928 * If relocation is PC-relative, subtract
929 * offset address.
930 */
931 if (IS_PC_RELATIVE(rtype))
932 value -= roffset;
933
934 /*
935 * Special case TLS relocations.
936 */
937 if (rtype == R_SPARC_TLS_DTPMOD32) {
938 /*
939 * Relocation value is the TLS modid.
940 */
941 value = TLSMODID(_lmp);
942
943 } else if (rtype == R_SPARC_TLS_TPOFF32) {
944 if ((value = elf_static_tls(_lmp,
945 symdef, rel, rtype, name, roffset,
946 value)) == 0) {
947 ret = 0;
948 break;
949 }
950 }
951 }
952 } else {
953 /*
954 * Special cases.
955 */
956 if (rtype == R_SPARC_REGISTER) {
957 /*
958 * A register symbol associated with symbol
959 * index 0 is initialized (i.e. relocated) to
960 * a constant in the r_addend field rather than
961 * to a symbol value.
962 */
963 value = 0;
964
965 } else if (rtype == R_SPARC_TLS_DTPMOD32) {
966 /*
967 * TLS relocation value is the TLS modid.
968 */
969 value = TLSMODID(lmp);
970 } else
971 value = basebgn;
972
973 name = NULL;
974 }
975
976 DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH,
977 M_REL_SHT_TYPE, rel, NULL, 0, name));
978
979 /*
980 * Make sure the segment is writable.
981 */
982 if ((rtype != R_SPARC_REGISTER) &&
983 ((mpp->mr_prot & PROT_WRITE) == 0) &&
984 ((set_prot(lmp, mpp, 1) == 0) ||
985 (aplist_append(textrel, mpp, AL_CNT_TEXTREL) == NULL))) {
986 ret = 0;
987 break;
988 }
989
990 /*
991 * Call relocation routine to perform required relocation.
992 */
993 switch (rtype) {
994 case R_SPARC_REGISTER:
995 /*
996 * The v9 ABI 4.2.4 says that system objects may,
997 * but are not required to, use register symbols
998 * to inidcate how they use global registers. Thus
999 * at least %g6, %g7 must be allowed in addition
1000 * to %g2 and %g3.
1001 */
1002 value += reladd;
1003 if (roffset == STO_SPARC_REGISTER_G1) {
1004 set_sparc_g1(value);
1005 } else if (roffset == STO_SPARC_REGISTER_G2) {
1006 set_sparc_g2(value);
1007 } else if (roffset == STO_SPARC_REGISTER_G3) {
1008 set_sparc_g3(value);
1009 } else if (roffset == STO_SPARC_REGISTER_G4) {
1010 set_sparc_g4(value);
1011 } else if (roffset == STO_SPARC_REGISTER_G5) {
1012 set_sparc_g5(value);
1013 } else if (roffset == STO_SPARC_REGISTER_G6) {
1014 set_sparc_g6(value);
1015 } else if (roffset == STO_SPARC_REGISTER_G7) {
1016 set_sparc_g7(value);
1017 } else {
1018 eprintf(LIST(lmp), ERR_FATAL,
1019 MSG_INTL(MSG_REL_BADREG), NAME(lmp),
1020 EC_ADDR(roffset));
1021 ret = 0;
1022 break;
1023 }
1024
1025 DBG_CALL(Dbg_reloc_apply_reg(LIST(lmp), ELF_DBG_RTLD,
1026 M_MACH, (Xword)roffset, (Xword)value));
1027 break;
1028 case R_SPARC_COPY:
1029 if (elf_copy_reloc(name, symref, lmp, (void *)roffset,
1030 symdef, _lmp, (const void *)value) == 0)
1031 ret = 0;
1032 break;
1033 case R_SPARC_JMP_SLOT:
1034 pltndx = ((ulong_t)rel -
1035 (uintptr_t)JMPREL(lmp)) / relsiz;
1036
1037 if (FLAGS(lmp) & FLG_RT_FIXED)
1038 vaddr = 0;
1039 else
1040 vaddr = ADDR(lmp);
1041
1042 if (((LIST(lmp)->lm_tflags | AFLAGS(lmp)) &
1043 (LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) &&
1044 AUDINFO(lmp)->ai_dynplts) {
1045 int fail = 0;
1046 ulong_t symndx = (((uintptr_t)symdef -
1047 (uintptr_t)SYMTAB(_lmp)) / SYMENT(_lmp));
1048
1049 (void) elf_plt_trace_write((caddr_t)vaddr,
1050 (Rela *)rel, lmp, _lmp, symdef, symndx,
1051 pltndx, (caddr_t)value, sb_flags, &fail);
1052 if (fail)
1053 ret = 0;
1054 } else {
1055 /*
1056 * Write standard PLT entry to jump directly
1057 * to newly bound function.
1058 */
1059 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp),
1060 ELF_DBG_RTLD, (Xword)roffset,
1061 (Xword)value));
1062 pbtype = elf_plt_write((uintptr_t)vaddr,
1063 (uintptr_t)vaddr, (void *)rel, value,
1064 pltndx);
1065 }
1066 break;
1067 default:
1068 value += reladd;
1069
1070 /*
1071 * Write the relocation out. If this relocation is a
1072 * common basic write, skip the doreloc() engine.
1073 */
1074 if ((rtype == R_SPARC_GLOB_DAT) ||
1075 (rtype == R_SPARC_32)) {
1076 if (roffset & 0x3) {
1077 Conv_inv_buf_t inv_buf;
1078
1079 eprintf(LIST(lmp), ERR_FATAL,
1080 MSG_INTL(MSG_REL_NONALIGN),
1081 conv_reloc_SPARC_type(rtype,
1082 0, &inv_buf),
1083 NAME(lmp), demangle(name),
1084 EC_OFF(roffset));
1085 ret = 0;
1086 } else
1087 *(uint_t *)roffset += value;
1088 } else {
1089 if (do_reloc_rtld(rtype, (uchar_t *)roffset,
1090 (Xword *)&value, name,
1091 NAME(lmp), LIST(lmp)) == 0)
1092 ret = 0;
1093 }
1094
1095 /*
1096 * The value now contains the 'bit-shifted' value that
1097 * was or'ed into memory (this was set by
1098 * do_reloc_rtld()).
1099 */
1100 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), ELF_DBG_RTLD,
1101 (Xword)roffset, (Xword)value));
1102
1103 /*
1104 * If this relocation is against a text segment, make
1105 * sure that the instruction cache is flushed.
1106 */
1107 if (textrel)
1108 iflush_range((caddr_t)roffset, 0x4);
1109 }
1110
1111 if ((ret == 0) &&
1112 ((LIST(lmp)->lm_flags & LML_FLG_TRC_WARN) == 0))
1113 break;
1114
1115 if (binfo) {
1116 DBG_CALL(Dbg_bind_global(lmp, (Addr)roffset,
1117 (Off)(roffset - basebgn), pltndx, pbtype,
1118 _lmp, (Addr)value, symdef->st_value, name, binfo));
1119 }
1120 }
1121
1122 return (relocate_finish(lmp, bound, ret));
1123 }
1124
1125 /*
1126 * Provide a machine specific interface to the conversion routine. By calling
1127 * the machine specific version, rather than the generic version, we insure that
1128 * the data tables/strings for all known machine versions aren't dragged into
1129 * ld.so.1.
1130 */
1131 const char *
_conv_reloc_type(uint_t rel)1132 _conv_reloc_type(uint_t rel)
1133 {
1134 static Conv_inv_buf_t inv_buf;
1135
1136 return (conv_reloc_SPARC_type(rel, 0, &inv_buf));
1137 }
1138