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.
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.
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]
23 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
28 * SPARC V9 machine dependent and ELF file class dependent functions.
29 * Contains routines for performing function binding and symbol relocations.
34 #include <sys/elf_SPARC.h>
45 #include "_inline_gen.h"
46 #include "_inline_reloc.h"
49 extern void iflush_range(caddr_t
, size_t);
50 extern void plt_upper_32(uintptr_t, uintptr_t);
51 extern void plt_upper_44(uintptr_t, uintptr_t);
52 extern void plt_full_range(uintptr_t, uintptr_t);
53 extern void elf_rtbndr(Rt_map
*, ulong_t
, caddr_t
);
54 extern void elf_rtbndr_far(Rt_map
*, ulong_t
, caddr_t
);
57 elf_mach_flags_check(Rej_desc
*rej
, Ehdr
*ehdr
)
60 * Check machine type and flags.
62 if (ehdr
->e_flags
& EF_SPARC_EXT_MASK
) {
64 * Check vendor-specific extensions.
66 if (ehdr
->e_flags
& EF_SPARC_HAL_R1
) {
67 rej
->rej_type
= SGS_REJ_HAL
;
68 rej
->rej_info
= (uint_t
)ehdr
->e_flags
;
71 if ((ehdr
->e_flags
& EF_SPARC_SUN_US3
) & ~at_flags
) {
72 rej
->rej_type
= SGS_REJ_US3
;
73 rej
->rej_info
= (uint_t
)ehdr
->e_flags
;
79 * All of our 64-bit SPARC's support the US1 (UltraSPARC 1)
80 * instructions so that bit isn't worth checking for explicitly.
82 if ((ehdr
->e_flags
& EF_SPARC_EXT_MASK
) & ~at_flags
) {
83 rej
->rej_type
= SGS_REJ_BADFLAG
;
84 rej
->rej_info
= (uint_t
)ehdr
->e_flags
;
87 } else if ((ehdr
->e_flags
& ~EF_SPARCV9_MM
) != 0) {
88 rej
->rej_type
= SGS_REJ_BADFLAG
;
89 rej
->rej_info
= (uint_t
)ehdr
->e_flags
;
97 ldso_plt_init(Rt_map
*lmp
)
100 * There is no need to analyze ld.so because we don't map in any of
101 * its dependencies. However we may map these dependencies in later
102 * (as if ld.so had dlopened them), so initialize the plt and the
103 * permission information.
109 * Install the lm pointer in .PLT2 as per the ABI.
111 pltoff
= (2 * M_PLT_ENTSIZE
) / M_PLT_INSSIZE
;
112 elf_plt2_init(PLTGOT(lmp
) + pltoff
, lmp
);
115 * The V9 ABI states that the first 32k PLT entries
116 * use .PLT1, with .PLT0 used by the "latter" entries.
117 * We don't currently implement the extendend format,
118 * so install an error handler in .PLT0 to catch anyone
121 elf_plt_init(PLTGOT(lmp
), (caddr_t
)elf_rtbndr_far
);
126 pltoff
= M_PLT_ENTSIZE
/ M_PLT_INSSIZE
;
127 elf_plt_init(PLTGOT(lmp
) + pltoff
, (caddr_t
)elf_rtbndr
);
132 * elf_plt_write() will test to see how far away our destination
133 * address lies. If it is close enough that a branch can
134 * be used instead of a jmpl - we will fill the plt in with
135 * single branch. The branches are much quicker then
136 * a jmpl instruction - see bug#4356879 for further
139 * NOTE: we pass in both a 'pltaddr' and a 'vpltaddr' since
140 * librtld/dldump update PLT's who's physical
141 * address is not the same as the 'virtual' runtime
145 elf_plt_write(uintptr_t addr
, uintptr_t vaddr
, void *rptr
, uintptr_t symval
,
148 Rela
*rel
= (Rela
*)rptr
;
149 uintptr_t nsym
= ~symval
;
150 uintptr_t vpltaddr
, pltaddr
;
154 pltaddr
= addr
+ rel
->r_offset
;
155 vpltaddr
= vaddr
+ rel
->r_offset
;
156 disp
= symval
- vpltaddr
- 4;
158 if (pltndx
>= (M64_PLT_NEARPLTS
- M_PLT_XNumber
)) {
159 *((Sxword
*)pltaddr
) = (uintptr_t)symval
+
160 (uintptr_t)rel
->r_addend
- vaddr
;
161 DBG_CALL(pltcntfar
++);
166 * Test if the destination address is close enough to use
167 * a ba,a... instruction to reach it.
169 if (S_INRANGE(disp
, 23) && !(rtld_flags
& RT_FL_NOBAPLT
)) {
170 uint_t
*pltent
, bainstr
;
173 pltent
= (uint_t
*)pltaddr
;
178 * ba,a,pt %icc, <dest>
180 * is the most efficient of the PLT's. If we
181 * are within +-20 bits - use that branch.
183 if (S_INRANGE(disp
, 20)) {
184 bainstr
= M_BA_A_PT
; /* ba,a,pt %icc,<dest> */
186 bainstr
|= (uint_t
)(S_MASK(19) & (disp
>> 2));
188 DBG_CALL(pltcnt21d
++);
191 * Otherwise - we fall back to the good old
195 * Which still beats a jmpl instruction.
197 bainstr
= M_BA_A
; /* ba,a <dest> */
199 bainstr
|= (uint_t
)(S_MASK(22) & (disp
>> 2));
201 DBG_CALL(pltcnt24d
++);
204 pltent
[2] = M_NOP
; /* nop instr */
207 iflush_range((char *)(&pltent
[1]), 4);
208 pltent
[0] = M_NOP
; /* nop instr */
209 iflush_range((char *)(&pltent
[0]), 4);
213 if ((nsym
>> 32) == 0) {
214 plt_upper_32(pltaddr
, symval
);
215 DBG_CALL(pltcntu32
++);
219 if ((nsym
>> 44) == 0) {
220 plt_upper_44(pltaddr
, symval
);
221 DBG_CALL(pltcntu44
++);
226 * The PLT destination is not in reach of
227 * a branch instruction - so we fall back
228 * to a 'jmpl' sequence.
230 plt_full_range(pltaddr
, symval
);
231 DBG_CALL(pltcntfull
++);
236 * Once relocated, the following 6 instruction sequence moves
237 * a 64-bit immediate value into register %g1
239 #define VAL64_TO_G1 \
240 /* 0x00 */ 0x0b, 0x00, 0x00, 0x00, /* sethi %hh(value), %g5 */ \
241 /* 0x04 */ 0x8a, 0x11, 0x60, 0x00, /* or %g5, %hm(value), %g5 */ \
242 /* 0x08 */ 0x8b, 0x29, 0x70, 0x20, /* sllx %g5, 32, %g5 */ \
243 /* 0x0c */ 0x03, 0x00, 0x00, 0x00, /* sethi %lm(value), %g1 */ \
244 /* 0x10 */ 0x82, 0x10, 0x60, 0x00, /* or %g1, %lo(value), %g1 */ \
245 /* 0x14 */ 0x82, 0x10, 0x40, 0x05 /* or %g1, %g5, %g1 */
248 * Local storage space created on the stack created for this glue
249 * code includes space for:
250 * 0x8 pointer to dyn_data
251 * 0x8 size prev stack frame
253 static const Byte dyn_plt_template
[] = {
254 /* 0x0 */ 0x2a, 0xcf, 0x80, 0x03, /* brnz,a,pt %fp, 0xc */
255 /* 0x4 */ 0x82, 0x27, 0x80, 0x0e, /* sub %fp, %sp, %g1 */
256 /* 0x8 */ 0x82, 0x10, 0x20, 0xb0, /* mov 176, %g1 */
257 /* 0xc */ 0x9d, 0xe3, 0xbf, 0x40, /* save %sp, -192, %sp */
258 /* 0x10 */ 0xc2, 0x77, 0xa7, 0xef, /* stx %g1, [%fp + 2031] */
260 /* store prev stack size */
261 /* 0x14 */ VAL64_TO_G1
, /* dyn_data to g1 */
262 /* 0x2c */ 0xc2, 0x77, 0xa7, 0xf7, /* stx %g1, [%fp + 2039] */
264 /* 0x30 */ VAL64_TO_G1
, /* elf_plt_trace() addr to g1 */
266 /* Call to elf_plt_trace() via g1 */
267 /* 0x48 */ 0x9f, 0xc0, 0x60, 0x00, /* jmpl ! link r[15] to addr in g1 */
268 /* 0x4c */ 0x01, 0x00, 0x00, 0x00 /* nop ! for jmpl delay slot *AND* */
269 /* to get 8-byte alignment */
272 int dyn_plt_ent_size
= sizeof (dyn_plt_template
) +
273 sizeof (Addr
) + /* reflmp */
274 sizeof (Addr
) + /* deflmp */
275 sizeof (Word
) + /* symndx */
276 sizeof (Word
) + /* sb_flags */
277 sizeof (Sym
); /* symdef */
280 * the dynamic plt entry is:
284 * mov SA(MINFRAME), %g1
286 * save %sp, -(SA(MINFRAME) + (2 * CLONGSIZE)), %sp
288 * ! store prev stack size
289 * stx %g1, [%fp + STACK_BIAS - (2 * CLONGSIZE)]
292 * ! move dyn_data to %g1
293 * sethi %hh(dyn_data), %g5
294 * or %g5, %hm(dyn_data), %g5
296 * sethi %lm(dyn_data), %g1
297 * or %g1, %lo(dyn_data), %g1
300 * ! store dyn_data ptr on frame (from %g1)
301 * stx %g1, [%fp + STACK_BIAS - CLONGSIZE]
303 * ! Move address of elf_plt_trace() into %g1
304 * [Uses same 6 instructions as shown at label 2: above. Not shown.]
306 * ! Use JMPL to make call. CALL instruction is limited to 30-bits.
310 * ! JMPL has a delay slot that must be filled. And, the sequence
311 * ! of instructions needs to have 8-byte alignment. This NOP does both.
312 * ! The alignment is needed for the data we put following the
321 * Sym symdef (Elf64_Sym = 24-bytes)
325 * Relocate the instructions given by the VAL64_TO_G1 macro above.
326 * The arguments parallel those of do_reloc_rtld().
329 * off - Address of 1st instruction in sequence.
330 * value - Value being relocated (addend)
331 * sym - Name of value being relocated.
332 * lml - link map list
335 * Returns TRUE for success, FALSE for failure.
338 reloc_val64_to_g1(uchar_t
*off
, Addr
*value
, const char *sym
, Lm_list
*lml
)
344 * sethi %hh(value), %g5
346 tmp_value
= (Xword
)value
;
347 if (do_reloc_rtld(R_SPARC_HH22
, off
, &tmp_value
, sym
,
348 MSG_ORIG(MSG_SPECFIL_DYNPLT
), lml
) == 0) {
354 * or %g5, %hm(value), %g5
356 tmp_value
= (Xword
)value
;
357 if (do_reloc_rtld(R_SPARC_HM10
, off
+ 4, &tmp_value
, sym
,
358 MSG_ORIG(MSG_SPECFIL_DYNPLT
), lml
) == 0) {
364 * sethi %lm(value), %g1
366 tmp_value
= (Xword
)value
;
367 if (do_reloc_rtld(R_SPARC_LM22
, off
+ 12, &tmp_value
, sym
,
368 MSG_ORIG(MSG_SPECFIL_DYNPLT
), lml
) == 0) {
374 * or %g1, %lo(value), %g1
376 tmp_value
= (Xword
)value
;
377 if (do_reloc_rtld(R_SPARC_LO10
, off
+ 16, &tmp_value
, sym
,
378 MSG_ORIG(MSG_SPECFIL_DYNPLT
), lml
) == 0) {
386 elf_plt_trace_write(caddr_t addr
, Rela
*rptr
, Rt_map
*rlmp
, Rt_map
*dlmp
,
387 Sym
*sym
, uint_t symndx
, ulong_t pltndx
, caddr_t to
, uint_t sb_flags
,
390 extern ulong_t
elf_plt_trace();
395 * If both pltenter & pltexit have been disabled there
396 * there is no reason to even create the glue code.
398 if ((sb_flags
& (LA_SYMB_NOPLTENTER
| LA_SYMB_NOPLTEXIT
)) ==
399 (LA_SYMB_NOPLTENTER
| LA_SYMB_NOPLTEXIT
)) {
400 (void) elf_plt_write((uintptr_t)addr
, (uintptr_t)addr
,
401 rptr
, (uintptr_t)to
, pltndx
);
406 * We only need to add the glue code if there is an auditing
407 * library that is interested in this binding.
409 dyn_plt
= (uchar_t
*)((uintptr_t)AUDINFO(rlmp
)->ai_dynplts
+
410 (pltndx
* dyn_plt_ent_size
));
413 * Have we initialized this dynamic plt entry yet? If we haven't do it
414 * now. Otherwise this function has been called before, but from a
415 * different plt (ie. from another shared object). In that case
416 * we just set the plt to point to the new dyn_plt.
420 Lm_list
*lml
= LIST(rlmp
);
422 (void) memcpy((void *)dyn_plt
, dyn_plt_template
,
423 sizeof (dyn_plt_template
));
424 dyndata
= (uintptr_t *)((uintptr_t)dyn_plt
+
425 sizeof (dyn_plt_template
));
429 * VAL64_TO_G1(dyndata)
430 * VAL64_TO_G1(&elf_plt_trace)
432 if (!(reloc_val64_to_g1((dyn_plt
+ 0x14), dyndata
,
433 MSG_ORIG(MSG_SYM_LADYNDATA
), lml
) &&
434 reloc_val64_to_g1((dyn_plt
+ 0x30), (Addr
*)&elf_plt_trace
,
435 MSG_ORIG(MSG_SYM_ELFPLTTRACE
), lml
))) {
440 *dyndata
++ = (Addr
)rlmp
;
441 *dyndata
++ = (Addr
)dlmp
;
444 * symndx in the high word, sb_flags in the low.
446 *dyndata
= (Addr
)sb_flags
;
447 *(Word
*)dyndata
= symndx
;
450 symp
= (Sym
*)dyndata
;
452 symp
->st_value
= (Addr
)to
;
453 iflush_range((void *)dyn_plt
, sizeof (dyn_plt_template
));
456 (void) elf_plt_write((uintptr_t)addr
, (uintptr_t)addr
, rptr
,
457 (uintptr_t)dyn_plt
, pltndx
);
458 return ((caddr_t
)dyn_plt
);
462 * Function binding routine - invoked on the first call to a function through
463 * the procedure linkage table;
464 * passes first through an assembly language interface.
466 * Takes the address of the PLT entry where the call originated,
467 * the offset into the relocation table of the associated
468 * relocation entry and the address of the link map (rt_private_map struct)
471 * Returns the address of the function referenced after re-writing the PLT
472 * entry to invoke the function directly.
474 * On error, causes process to terminate with a signal.
477 elf_bndr(Rt_map
*lmp
, ulong_t pltoff
, caddr_t from
)
480 Addr addr
, vaddr
, reloff
, symval
;
485 uint_t binfo
, sb_flags
= 0, dbg_class
;
490 int entry
, lmflags
, farplt
= 0;
494 * For compatibility with libthread (TI_VERSION 1) we track the entry
495 * value. A zero value indicates we have recursed into ld.so.1 to
496 * further process a locking request. Under this recursion we disable
497 * tsort and cleanup activities.
502 if ((lmflags
= lml
->lm_flags
) & LML_FLG_RTLDLM
) {
503 dbg_class
= dbg_desc
->d_class
;
504 dbg_desc
->d_class
= 0;
508 * Must calculate true plt relocation address from reloc.
509 * Take offset, subtract number of reserved PLT entries, and divide
510 * by PLT entry size, which should give the index of the plt
511 * entry (and relocation entry since they have been defined to be
512 * in the same order). Then we must multiply by the size of
513 * a relocation entry, which will give us the offset of the
514 * plt relocation entry from the start of them given by JMPREL(lm).
516 addr
= pltoff
- M_PLT_RESERVSZ
;
518 if (pltoff
< (M64_PLT_NEARPLTS
* M_PLT_ENTSIZE
)) {
519 pltndx
= addr
/ M_PLT_ENTSIZE
;
523 pltblockoff
= pltoff
- (M64_PLT_NEARPLTS
* M_PLT_ENTSIZE
);
524 pltndx
= M64_PLT_NEARPLTS
+
525 ((pltblockoff
/ M64_PLT_FBLOCKSZ
) * M64_PLT_FBLKCNTS
) +
526 ((pltblockoff
% M64_PLT_FBLOCKSZ
) / M64_PLT_FENTSIZE
) -
532 * Perform some basic sanity checks. If we didn't get a load map
533 * or the plt offset is invalid then its possible someone has walked
534 * over the plt entries or jumped to plt[01] out of the blue.
536 if (!lmp
|| (!farplt
&& (addr
% M_PLT_ENTSIZE
) != 0) ||
537 (farplt
&& (addr
% M_PLT_INSSIZE
))) {
538 Conv_inv_buf_t inv_buf
;
540 eprintf(lml
, ERR_FATAL
, MSG_INTL(MSG_REL_PLTREF
),
541 conv_reloc_SPARC_type(R_SPARC_JMP_SLOT
, 0, &inv_buf
),
542 EC_NATPTR(lmp
), EC_XWORD(pltoff
), EC_NATPTR(from
));
545 reloff
= pltndx
* sizeof (Rela
);
548 * Use relocation entry to get symbol table entry and symbol name.
550 addr
= (ulong_t
)JMPREL(lmp
);
551 rptr
= (Rela
*)(addr
+ reloff
);
552 rsymndx
= ELF_R_SYM(rptr
->r_info
);
553 rsym
= (Sym
*)((ulong_t
)SYMTAB(lmp
) + (rsymndx
* SYMENT(lmp
)));
554 name
= (char *)(STRTAB(lmp
) + rsym
->st_name
);
557 * Determine the last link-map of this list, this'll be the starting
558 * point for any tsort() processing.
563 * Find definition for symbol. Initialize the symbol lookup, and symbol
564 * result, data structures.
566 SLOOKUP_INIT(sl
, name
, lmp
, lml
->lm_head
, ld_entry_cnt
, 0,
567 rsymndx
, rsym
, 0, LKUP_DEFT
);
568 SRESULT_INIT(sr
, name
);
570 if (lookup_sym(&sl
, &sr
, &binfo
, NULL
) == 0) {
571 eprintf(lml
, ERR_FATAL
, MSG_INTL(MSG_REL_NOSYM
), NAME(lmp
),
576 name
= (char *)sr
.sr_name
;
580 symval
= nsym
->st_value
;
582 if (!(FLAGS(nlmp
) & FLG_RT_FIXED
) &&
583 (nsym
->st_shndx
!= SHN_ABS
))
584 symval
+= ADDR(nlmp
);
585 if ((lmp
!= nlmp
) && ((FLAGS1(nlmp
) & FL1_RT_NOINIFIN
) == 0)) {
587 * Record that this new link map is now bound to the caller.
589 if (bind_one(lmp
, nlmp
, BND_REFER
) == 0)
593 if ((lml
->lm_tflags
| AFLAGS(lmp
) | AFLAGS(nlmp
)) &
594 LML_TFLG_AUD_SYMBIND
) {
596 uint_t symndx
= (uint_t
)(((uintptr_t)nsym
-
597 (uintptr_t)SYMTAB(nlmp
)) / SYMENT(nlmp
));
599 symval
= audit_symbind(lmp
, nlmp
, nsym
, symndx
, symval
,
603 if (FLAGS(lmp
) & FLG_RT_FIXED
)
609 if (!(rtld_flags
& RT_FL_NOBIND
)) {
610 if (((lml
->lm_tflags
| AFLAGS(lmp
)) &
611 (LML_TFLG_AUD_PLTENTER
| LML_TFLG_AUD_PLTEXIT
)) &&
612 AUDINFO(lmp
)->ai_dynplts
) {
615 uint_t symndx
= (uint_t
)(((uintptr_t)nsym
-
616 (uintptr_t)SYMTAB(nlmp
)) / SYMENT(nlmp
));
618 symval
= (ulong_t
)elf_plt_trace_write((caddr_t
)vaddr
,
619 rptr
, lmp
, nlmp
, nsym
, symndx
, pltndx
,
620 (caddr_t
)symval
, sb_flags
, &fail
);
625 * Write standard PLT entry to jump directly
626 * to newly bound function.
628 pbtype
= elf_plt_write((uintptr_t)vaddr
,
629 (uintptr_t)vaddr
, rptr
, symval
, pltndx
);
634 * Print binding information and rebuild PLT entry.
636 DBG_CALL(Dbg_bind_global(lmp
, (Addr
)from
, (Off
)(from
- ADDR(lmp
)),
637 (Xword
)pltndx
, pbtype
, nlmp
, (Addr
)symval
, nsym
->st_value
,
641 * Complete any processing for newly loaded objects. Note we don't
642 * know exactly where any new objects are loaded (we know the object
643 * that supplied the symbol, but others may have been loaded lazily as
644 * we searched for the symbol), so sorting starts from the last
645 * link-map know on entry to this routine.
648 load_completion(llmp
);
651 * Some operations like dldump() or dlopen()'ing a relocatable object
652 * result in objects being loaded on rtld's link-map, make sure these
653 * objects are initialized also.
655 if ((LIST(nlmp
)->lm_flags
& LML_FLG_RTLDLM
) && LIST(nlmp
)->lm_init
)
656 load_completion(nlmp
);
659 * Make sure the object to which we've bound has had it's .init fired.
660 * Cleanup before return to user code.
663 is_dep_init(nlmp
, lmp
);
667 if (lmflags
& LML_FLG_RTLDLM
)
668 dbg_desc
->d_class
= dbg_class
;
674 bindpltpad(Rt_map
*lmp
, Alist
**padlist
, Addr value
, void **pltaddr
,
675 const char *fname
, const char *sname
)
678 Pltpadinfo ppi
, *ppip
;
684 for (ALIST_TRAVERSE(*padlist
, idx
, ppip
)) {
685 if (ppip
->pp_addr
== value
) {
686 *pltaddr
= ppip
->pp_plt
;
687 DBG_CALL(Dbg_bind_pltpad_from(lmp
, (Addr
)*pltaddr
,
691 if (ppip
->pp_addr
> value
)
696 pltoff
= (uintptr_t)plt
- (uintptr_t)ADDR(lmp
);
698 PLTPAD(lmp
) = (void *)((uintptr_t)PLTPAD(lmp
) + M_PLT_ENTSIZE
);
700 if (PLTPAD(lmp
) > PLTPADEND(lmp
)) {
702 * Just fail in usual relocation way
704 *pltaddr
= (void *)value
;
707 rel
.r_offset
= pltoff
;
712 * elf_plt_write assumes the plt was previously filled
713 * with NOP's, so fill it in now.
715 for (i
= 0; i
< (M_PLT_ENTSIZE
/ sizeof (uint_t
)); i
++) {
716 ((uint_t
*)plt
)[i
] = M_NOP
;
718 iflush_range((caddr_t
)plt
, M_PLT_ENTSIZE
);
720 (void) elf_plt_write(ADDR(lmp
), ADDR(lmp
), &rel
, value
, 0);
725 if (alist_insert(padlist
, &ppi
, sizeof (Pltpadinfo
),
726 AL_CNT_PLTPAD
, idx
) == NULL
)
730 DBG_CALL(Dbg_bind_pltpad_to(lmp
, (Addr
)*pltaddr
, fname
, sname
));
735 * Read and process the relocations for one link object, we assume all
736 * relocation sections for loadable segments are stored contiguously in
740 elf_reloc(Rt_map
*lmp
, uint_t plt
, int *in_nfavl
, APlist
**textrel
)
742 ulong_t relbgn
, relend
, relsiz
, basebgn
, pltbgn
, pltend
;
743 ulong_t pltndx
, roffset
, rsymndx
, psymndx
= 0;
744 uint_t dsymndx
, binfo
, pbinfo
;
748 Sym
*symref
, *psymref
, *symdef
, *psymdef
;
752 int ret
= 1, noplt
= 0;
753 long relacount
= RELACOUNT(lmp
);
756 Alist
*pltpadlist
= NULL
;
757 APlist
*bound
= NULL
;
760 * If an object has any DT_REGISTER entries associated with
761 * it, they are processed now.
763 if ((plt
== 0) && (FLAGS(lmp
) & FLG_RT_REGSYMS
)) {
764 if (elf_regsyms(lmp
) == 0)
769 * Although only necessary for lazy binding, initialize the first
770 * procedure linkage table entry to go to elf_rtbndr(). dbx(1) seems
771 * to find this useful.
773 if ((plt
== 0) && PLTGOT(lmp
)) {
774 mmapobj_result_t
*mpp
;
778 * Make sure the segment is writable.
781 find_segment((caddr_t
)PLTGOT(lmp
), lmp
)) != NULL
) &&
782 ((mpp
->mr_prot
& PROT_WRITE
) == 0)) &&
783 ((set_prot(lmp
, mpp
, 1) == 0) ||
784 (aplist_append(textrel
, mpp
, AL_CNT_TEXTREL
) == NULL
)))
788 * Install the lm pointer in .PLT2 as per the ABI.
790 pltoff
= (2 * M_PLT_ENTSIZE
) / M_PLT_INSSIZE
;
791 elf_plt2_init(PLTGOT(lmp
) + pltoff
, lmp
);
794 * The V9 ABI states that the first 32k PLT entries
795 * use .PLT1, with .PLT0 used by the "latter" entries.
796 * We don't currently implement the extendend format,
797 * so install an error handler in .PLT0 to catch anyone
800 elf_plt_init(PLTGOT(lmp
), (caddr_t
)elf_rtbndr_far
);
805 pltoff
= M_PLT_ENTSIZE
/ M_PLT_INSSIZE
;
806 elf_plt_init(PLTGOT(lmp
) + pltoff
, (caddr_t
)elf_rtbndr
);
810 * Initialize the plt start and end addresses.
812 if ((pltbgn
= (ulong_t
)JMPREL(lmp
)) != 0)
813 pltend
= pltbgn
+ (ulong_t
)(PLTRELSZ(lmp
));
816 * If we've been called upon to promote an RTLD_LAZY object to an
817 * RTLD_NOW then we're only interested in scaning the .plt table.
824 * The relocation sections appear to the run-time linker as a
825 * single table. Determine the address of the beginning and end
826 * of this table. There are two different interpretations of
827 * the ABI at this point:
829 * o The REL table and its associated RELSZ indicate the
830 * concatenation of *all* relocation sections (this is the
831 * model our link-editor constructs).
833 * o The REL table and its associated RELSZ indicate the
834 * concatenation of all *but* the .plt relocations. These
835 * relocations are specified individually by the JMPREL and
838 * Determine from our knowledege of the relocation range and
839 * .plt range, the range of the total relocation table. Note
840 * that one other ABI assumption seems to be that the .plt
841 * relocations always follow any other relocations, the
842 * following range checking drops that assumption.
844 relbgn
= (ulong_t
)(REL(lmp
));
845 relend
= relbgn
+ (ulong_t
)(RELSZ(lmp
));
847 if (!relbgn
|| (relbgn
> pltbgn
))
849 if (!relbgn
|| (relend
< pltend
))
853 if (!relbgn
|| (relbgn
== relend
)) {
854 DBG_CALL(Dbg_reloc_run(lmp
, 0, plt
, DBG_REL_NONE
));
858 relsiz
= (ulong_t
)(RELENT(lmp
));
861 DBG_CALL(Dbg_reloc_run(lmp
, M_REL_SHT_TYPE
, plt
, DBG_REL_START
));
864 * If we're processing in lazy mode there is no need to scan the
867 if (pltbgn
&& ((MODE(lmp
) & RTLD_NOW
) == 0))
872 * Loop through relocations.
874 while (relbgn
< relend
) {
875 mmapobj_result_t
*mpp
;
879 rtype
= ELF_R_TYPE(((Rela
*)relbgn
)->r_info
, M_MACH
);
882 * If this is a RELATIVE relocation in a shared object
883 * (the common case), and if we are not debugging, then
884 * jump into a tighter relocaiton loop (elf_reloc_relacount)
885 * Only make the jump if we've been given a hint on the
886 * number of relocations.
888 if ((rtype
== R_SPARC_RELATIVE
) &&
889 ((FLAGS(lmp
) & FLG_RT_FIXED
) == 0) && (DBG_ENABLED
== 0)) {
891 relbgn
= elf_reloc_relative_count(relbgn
,
892 relacount
, relsiz
, basebgn
, lmp
,
896 relbgn
= elf_reloc_relative(relbgn
, relend
,
897 relsiz
, basebgn
, lmp
, textrel
, 0);
899 if (relbgn
>= relend
)
901 rtype
= ELF_R_TYPE(((Rela
*)relbgn
)->r_info
, M_MACH
);
904 roffset
= ((Rela
*)relbgn
)->r_offset
;
906 reladd
= (long)(((Rela
*)relbgn
)->r_addend
);
907 rsymndx
= ELF_R_SYM(((Rela
*)relbgn
)->r_info
);
908 rel
= (Rela
*)relbgn
;
914 if (rtype
== R_SPARC_NONE
)
916 if (noplt
&& ((ulong_t
)rel
>= pltbgn
) &&
917 ((ulong_t
)rel
< pltend
)) {
922 if (rtype
!= R_SPARC_REGISTER
) {
924 * If this is a shared object, add the base address
927 if (!(FLAGS(lmp
) & FLG_RT_FIXED
))
931 * If this relocation is not against part of the image
932 * mapped into memory we skip it.
934 if ((mpp
= find_segment((caddr_t
)roffset
,
936 elf_reloc_bad(lmp
, (void *)rel
, rtype
, roffset
,
943 * If we're promoting plts, determine if this one has already
944 * been written. An uninitialized plts' second instruction is a
948 uchar_t
*_roffset
= (uchar_t
*)roffset
;
950 _roffset
+= M_PLT_INSSIZE
;
952 if ((*(uint_t
*)_roffset
&
953 (~(S_MASK(19)))) != M_BA_A_XCC
)
958 pltndx
= (ulong_t
)-1;
962 * If a symbol index is specified then get the symbol table
963 * entry, locate the symbol definition, and determine its
968 * If a Syminfo section is provided, determine if this
969 * symbol is deferred, and if so, skip this relocation.
971 if (sip
&& is_sym_deferred((ulong_t
)rel
, basebgn
, lmp
,
972 textrel
, sip
, rsymndx
))
976 * Get the local symbol table entry.
978 symref
= (Sym
*)((ulong_t
)SYMTAB(lmp
) +
979 (rsymndx
* SYMENT(lmp
)));
982 * If this is a local symbol, just use the base address.
983 * (we should have no local relocations in the
986 if (ELF_ST_BIND(symref
->st_info
) == STB_LOCAL
) {
991 * Special case TLS relocations.
993 if ((rtype
== R_SPARC_TLS_DTPMOD32
) ||
994 (rtype
== R_SPARC_TLS_DTPMOD64
)) {
998 value
= TLSMODID(lmp
);
1000 } else if ((rtype
== R_SPARC_TLS_TPOFF32
) ||
1001 (rtype
== R_SPARC_TLS_TPOFF64
)) {
1002 if ((value
= elf_static_tls(lmp
, symref
,
1003 rel
, rtype
, 0, roffset
, 0)) == 0) {
1010 * If the symbol index is equal to the previous
1011 * symbol index relocation we processed then
1012 * reuse the previous values. (Note that there
1013 * have been cases where a relocation exists
1014 * against a copy relocation symbol, our ld(1)
1015 * should optimize this away, but make sure we
1016 * don't use the same symbol information should
1019 if ((rsymndx
== psymndx
) &&
1020 (rtype
!= R_SPARC_COPY
)) {
1023 DBG_CALL(Dbg_bind_weak(lmp
,
1024 (Addr
)roffset
, (Addr
)
1025 (roffset
- basebgn
), name
));
1040 if ((LIST(_lmp
)->lm_tflags
|
1042 LML_TFLG_AUD_SYMBIND
) {
1043 value
= audit_symbind(lmp
, _lmp
,
1045 symdef
, dsymndx
, value
,
1053 * Lookup the symbol definition.
1054 * Initialize the symbol lookup, and
1055 * symbol result, data structures.
1057 name
= (char *)(STRTAB(lmp
) +
1060 SLOOKUP_INIT(sl
, name
, lmp
, 0,
1061 ld_entry_cnt
, 0, rsymndx
, symref
,
1062 rtype
, LKUP_STDRELOC
);
1063 SRESULT_INIT(sr
, name
);
1066 if (lookup_sym(&sl
, &sr
, &binfo
,
1068 name
= (char *)sr
.sr_name
;
1074 * If the symbol is not found and the
1075 * reference was not to a weak symbol,
1076 * report an error. Weak references
1077 * may be unresolved.
1081 if (sl
.sl_bind
!= STB_WEAK
) {
1082 if (elf_reloc_error(lmp
, name
,
1093 DBG_CALL(Dbg_bind_weak(lmp
,
1094 (Addr
)roffset
, (Addr
)
1095 (roffset
- basebgn
), name
));
1102 * If symbol was found in an object
1103 * other than the referencing object
1104 * then record the binding.
1106 if ((lmp
!= _lmp
) && ((FLAGS1(_lmp
) &
1107 FL1_RT_NOINIFIN
) == 0)) {
1108 if (aplist_test(&bound
, _lmp
,
1109 AL_CNT_RELBIND
) == 0) {
1116 * Calculate the location of definition;
1117 * symbol value plus base address of
1118 * containing shared object.
1121 value
= symdef
->st_size
;
1123 value
= symdef
->st_value
;
1125 if (!(FLAGS(_lmp
) & FLG_RT_FIXED
) &&
1126 !(IS_SIZE(rtype
)) &&
1127 (symdef
->st_shndx
!= SHN_ABS
) &&
1128 (ELF_ST_TYPE(symdef
->st_info
) !=
1130 value
+= ADDR(_lmp
);
1133 * Retain this symbol index and the
1134 * value in case it can be used for the
1135 * subsequent relocations.
1137 if (rtype
!= R_SPARC_COPY
) {
1146 if ((LIST(_lmp
)->lm_tflags
|
1148 LML_TFLG_AUD_SYMBIND
) {
1150 dsymndx
= (((uintptr_t)symdef
-
1151 (uintptr_t)SYMTAB(_lmp
)) /
1153 value
= audit_symbind(lmp
, _lmp
,
1154 symdef
, dsymndx
, value
,
1160 * If relocation is PC-relative, subtract
1163 if (IS_PC_RELATIVE(rtype
))
1167 * Special case TLS relocations.
1169 if ((rtype
== R_SPARC_TLS_DTPMOD32
) ||
1170 (rtype
== R_SPARC_TLS_DTPMOD64
)) {
1172 * Relocation value is the TLS modid.
1174 value
= TLSMODID(_lmp
);
1176 } else if ((rtype
== R_SPARC_TLS_TPOFF64
) ||
1177 (rtype
== R_SPARC_TLS_TPOFF32
)) {
1178 if ((value
= elf_static_tls(_lmp
,
1179 symdef
, rel
, rtype
, name
, roffset
,
1190 if (rtype
== R_SPARC_REGISTER
) {
1192 * A register symbol associated with symbol
1193 * index 0 is initialized (i.e. relocated) to
1194 * a constant in the r_addend field rather than
1195 * to a symbol value.
1199 } else if ((rtype
== R_SPARC_TLS_DTPMOD32
) ||
1200 (rtype
== R_SPARC_TLS_DTPMOD64
)) {
1202 * TLS relocation value is the TLS modid.
1204 value
= TLSMODID(lmp
);
1211 DBG_CALL(Dbg_reloc_in(LIST(lmp
), ELF_DBG_RTLD
, M_MACH
,
1212 M_REL_SHT_TYPE
, rel
, NULL
, 0, name
));
1215 * Make sure the segment is writable.
1217 if ((rtype
!= R_SPARC_REGISTER
) &&
1218 ((mpp
->mr_prot
& PROT_WRITE
) == 0) &&
1219 ((set_prot(lmp
, mpp
, 1) == 0) ||
1220 (aplist_append(textrel
, mpp
, AL_CNT_TEXTREL
) == NULL
))) {
1226 * Call relocation routine to perform required relocation.
1229 case R_SPARC_REGISTER
:
1231 * The v9 ABI 4.2.4 says that system objects may,
1232 * but are not required to, use register symbols
1233 * to inidcate how they use global registers. Thus
1234 * at least %g6, %g7 must be allowed in addition
1238 if (roffset
== STO_SPARC_REGISTER_G1
) {
1239 set_sparc_g1(value
);
1240 } else if (roffset
== STO_SPARC_REGISTER_G2
) {
1241 set_sparc_g2(value
);
1242 } else if (roffset
== STO_SPARC_REGISTER_G3
) {
1243 set_sparc_g3(value
);
1244 } else if (roffset
== STO_SPARC_REGISTER_G4
) {
1245 set_sparc_g4(value
);
1246 } else if (roffset
== STO_SPARC_REGISTER_G5
) {
1247 set_sparc_g5(value
);
1248 } else if (roffset
== STO_SPARC_REGISTER_G6
) {
1249 set_sparc_g6(value
);
1250 } else if (roffset
== STO_SPARC_REGISTER_G7
) {
1251 set_sparc_g7(value
);
1253 eprintf(LIST(lmp
), ERR_FATAL
,
1254 MSG_INTL(MSG_REL_BADREG
), NAME(lmp
),
1260 DBG_CALL(Dbg_reloc_apply_reg(LIST(lmp
), ELF_DBG_RTLD
,
1261 M_MACH
, (Xword
)roffset
, (Xword
)value
));
1264 if (elf_copy_reloc(name
, symref
, lmp
, (void *)roffset
,
1265 symdef
, _lmp
, (const void *)value
) == 0)
1268 case R_SPARC_JMP_SLOT
:
1269 pltndx
= ((uintptr_t)rel
-
1270 (uintptr_t)JMPREL(lmp
)) / relsiz
;
1272 if (FLAGS(lmp
) & FLG_RT_FIXED
)
1277 if (((LIST(lmp
)->lm_tflags
| AFLAGS(lmp
)) &
1278 (LML_TFLG_AUD_PLTENTER
| LML_TFLG_AUD_PLTEXIT
)) &&
1279 AUDINFO(lmp
)->ai_dynplts
) {
1282 uint_t symndx
= (uint_t
)(((uintptr_t)symdef
-
1283 (uintptr_t)SYMTAB(_lmp
)) / SYMENT(_lmp
));
1285 (void) elf_plt_trace_write((caddr_t
)vaddr
,
1286 (Rela
*)rel
, lmp
, _lmp
, symdef
, symndx
,
1287 pltndx
, (caddr_t
)value
, sb_flags
, &fail
);
1292 * Write standard PLT entry to jump directly
1293 * to newly bound function.
1295 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp
),
1296 ELF_DBG_RTLD
, (Xword
)roffset
,
1298 pbtype
= elf_plt_write((uintptr_t)vaddr
,
1299 (uintptr_t)vaddr
, (void *)rel
, value
,
1303 case R_SPARC_WDISP30
:
1305 (S_INRANGE((Sxword
)value
, 29) == 0)) {
1308 if (bindpltpad(lmp
, &pltpadlist
,
1309 value
+ roffset
, &plt
,
1310 NAME(_lmp
), name
) == 0) {
1314 value
= (Addr
)((Addr
)plt
- roffset
);
1319 if (IS_EXTOFFSET(rtype
))
1320 value
+= (Word
)ELF_R_TYPE_DATA(rel
->r_info
);
1323 * Write the relocation out. If this relocation is a
1324 * common basic write, skip the doreloc() engine.
1326 if ((rtype
== R_SPARC_GLOB_DAT
) ||
1327 (rtype
== R_SPARC_64
)) {
1328 if (roffset
& 0x7) {
1329 Conv_inv_buf_t inv_buf
;
1331 eprintf(LIST(lmp
), ERR_FATAL
,
1332 MSG_INTL(MSG_REL_NONALIGN
),
1333 conv_reloc_SPARC_type(rtype
,
1335 NAME(lmp
), demangle(name
),
1339 *(ulong_t
*)roffset
+= value
;
1341 if (do_reloc_rtld(rtype
, (uchar_t
*)roffset
,
1342 (Xword
*)&value
, name
,
1343 NAME(lmp
), LIST(lmp
)) == 0)
1348 * The value now contains the 'bit-shifted' value that
1349 * was or'ed into memory (this was set by
1352 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp
), ELF_DBG_RTLD
,
1353 (Xword
)roffset
, (Xword
)value
));
1356 * If this relocation is against a text segment, make
1357 * sure that the instruction cache is flushed.
1360 iflush_range((caddr_t
)roffset
, 0x4);
1364 ((LIST(lmp
)->lm_flags
& LML_FLG_TRC_WARN
) == 0))
1368 DBG_CALL(Dbg_bind_global(lmp
, (Addr
)roffset
,
1369 (Off
)(roffset
- basebgn
), pltndx
, pbtype
,
1370 _lmp
, (Addr
)value
, symdef
->st_value
, name
, binfo
));
1375 * Free up any items on the pltpadlist if it was allocated
1379 return (relocate_finish(lmp
, bound
, ret
));
1383 * Provide a machine specific interface to the conversion routine. By calling
1384 * the machine specific version, rather than the generic version, we insure that
1385 * the data tables/strings for all known machine versions aren't dragged into
1389 _conv_reloc_type(uint_t rel
)
1391 static Conv_inv_buf_t inv_buf
;
1393 return (conv_reloc_SPARC_type(rel
, 0, &inv_buf
));