xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/relocate.c (revision 904e51f67bfac9f3ec88d9254757474c448808eb)
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) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include	<sys/elf_SPARC.h>
27 #include	<debug.h>
28 #include	<libld.h>
29 #include	<conv.h>
30 #include	"_debug.h"
31 #include	"msg.h"
32 
33 void
34 Dbg_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword off, Xword value)
35 {
36 	if (DBG_NOTCLASS(DBG_C_RELOC))
37 		return;
38 	if (DBG_NOTDETAIL())
39 		return;
40 
41 	/*
42 	 * Print the actual relocation being applied to the specified output
43 	 * section, the offset represents the actual relocation address, and the
44 	 * value is the new data being written to that address.
45 	 */
46 	Elf_reloc_apply_reg(lml, caller, mach, off, value);
47 }
48 
49 void
50 Dbg_reloc_apply_val(Lm_list *lml, int caller, Xword off, Xword value)
51 {
52 	if (DBG_NOTCLASS(DBG_C_RELOC))
53 		return;
54 	if (DBG_NOTDETAIL())
55 		return;
56 
57 	/*
58 	 * Print the actual relocation being applied to the specified output
59 	 * section, the offset represents the actual relocation address, and the
60 	 * value is the new data being written to that address.
61 	 */
62 	Elf_reloc_apply_val(lml, caller, off, value);
63 }
64 
65 void
66 Dbg_reloc_error(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
67     const char *sname)
68 {
69 	if (DBG_NOTCLASS(DBG_C_RELOC))
70 		return;
71 	if (DBG_NOTDETAIL())
72 		return;
73 
74 	Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc,
75 	    NULL, sname, MSG_INTL(MSG_REL_BADROFFSET));
76 }
77 
78 void
79 Dbg_reloc_run(Rt_map *lmp, uint_t rtype, int info, int dtype)
80 {
81 	Lm_list		*lml = LIST(lmp);
82 	const char	*str, *name = NAME(lmp);
83 
84 	if (DBG_NOTCLASS(DBG_C_RELOC))
85 		return;
86 
87 	if (dtype == DBG_REL_FINISH) {
88 		if (info)
89 			str = MSG_ORIG(MSG_STR_EMPTY);
90 		else
91 			str = MSG_INTL(MSG_REL_FAIL);
92 	} else {
93 		if (info)
94 			str = MSG_INTL(MSG_REL_PLT);
95 		else
96 			str = MSG_ORIG(MSG_STR_EMPTY);
97 	}
98 
99 	if (dtype == DBG_REL_START) {
100 		Dbg_util_nl(lml, DBG_NL_STD);
101 		dbg_print(lml, MSG_INTL(MSG_REL_START), name, str);
102 
103 		if (DBG_NOTDETAIL())
104 			return;
105 
106 		Elf_reloc_title(lml, ELF_DBG_RTLD, rtype);
107 
108 	} else {
109 		if (dtype == DBG_REL_NONE) {
110 			dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
111 			dbg_print(lml, MSG_INTL(MSG_REL_NONE), name, str);
112 		} else
113 			dbg_print(lml, MSG_INTL(MSG_REL_FINISH), name,
114 			    str);
115 
116 		Dbg_util_nl(lml, DBG_NL_STD);
117 	}
118 }
119 
120 void
121 Dbg_reloc_copy(Rt_map *dlmp, Rt_map *nlmp, const char *name, int zero)
122 {
123 	const char	*str;
124 
125 	if (DBG_NOTCLASS(DBG_C_RELOC))
126 		return;
127 	if (DBG_NOTDETAIL())
128 		return;
129 
130 	if (zero)
131 		str = MSG_INTL(MSG_STR_COPYZERO);
132 	else
133 		str = MSG_ORIG(MSG_STR_EMPTY);
134 
135 	dbg_print(LIST(dlmp), MSG_INTL(MSG_REL_COPY), NAME(dlmp), NAME(nlmp),
136 	    name, str);
137 }
138 
139 void
140 Dbg_reloc_generate(Lm_list *lml, Os_desc *osp, Word type)
141 {
142 	if (DBG_NOTCLASS(DBG_C_RELOC))
143 		return;
144 
145 	Dbg_util_nl(lml, DBG_NL_STD);
146 	dbg_print(lml, MSG_INTL(MSG_REL_GENERATE), osp->os_name);
147 
148 	if (DBG_NOTDETAIL())
149 		return;
150 
151 	Elf_reloc_title(lml, ELF_DBG_LD, type);
152 }
153 
154 /*
155  * Issue relocation collecting header message prior to listing
156  * each relocation.
157  *
158  * entry:
159  *	lml - Link map control list
160  *	osp - If sh_info was non-NULL, output section to which
161  *		relocation applies. Otherwise NULL.
162  *	isp - If sh_info was non-NULL, input section to which
163  *		relocation applies. Otherwise NULL.
164  *	risp - Relocation section
165  *
166  * note: osp and isp must both be NULL, or both non-NULL. risp is never NULL.
167  */
168 void
169 Dbg_reloc_proc(Lm_list *lml, Os_desc *osp, Is_desc *isp, Is_desc *risp)
170 {
171 	const char	*str1, *str2;
172 
173 	if (DBG_NOTCLASS(DBG_C_RELOC))
174 		return;
175 
176 	if (osp && osp->os_name)
177 		str1 = osp->os_name;
178 	else
179 		str1 =	MSG_INTL(MSG_STR_NULL);
180 
181 	if (isp && isp->is_file)
182 		str2 = isp->is_file->ifl_name;
183 	else if (risp && risp->is_file)
184 		str2 = risp->is_file->ifl_name;
185 	else
186 		str2 = MSG_INTL(MSG_STR_NULL);
187 
188 	Dbg_util_nl(lml, DBG_NL_STD);
189 	dbg_print(lml, MSG_INTL(MSG_REL_COLLECT), str1, str2);
190 
191 	if (DBG_NOTDETAIL())
192 		return;
193 
194 	Elf_reloc_title(lml, ELF_DBG_LD, risp->is_shdr->sh_type);
195 }
196 
197 void
198 Dbg_reloc_doact_title(Lm_list *lml)
199 {
200 	if (DBG_NOTCLASS(DBG_C_RELOC))
201 		return;
202 	if (DBG_NOTDETAIL())
203 		return;
204 
205 	Dbg_util_nl(lml, DBG_NL_STD);
206 	dbg_print(lml, MSG_INTL(MSG_REL_ACTIVE));
207 	Elf_reloc_title(lml, ELF_DBG_LD_ACT, 0);
208 }
209 
210 void
211 Dbg_reloc_doact(Lm_list *lml, int caller, Half mach, Word type, Rel_desc *rdesc,
212     Xword off, Xword value, rel_desc_sname_func_t rel_desc_sname_func)
213 {
214 	Conv_inv_buf_t	inv_buf;
215 	const char	*secname;
216 	Os_desc		*osp;
217 
218 	if (DBG_NOTCLASS(DBG_C_RELOC))
219 		return;
220 	if (DBG_NOTDETAIL())
221 		return;
222 
223 	osp = RELAUX_GET_OSDESC(rdesc);
224 	if (osp) {
225 		secname = osp->os_name;
226 		off += osp->os_shdr->sh_offset;
227 	} else
228 		secname = MSG_ORIG(MSG_STR_EMPTY);
229 
230 	Elf_reloc_entry_2(lml, caller, MSG_ORIG(MSG_STR_EMPTY), type,
231 	    conv_reloc_type(mach, rdesc->rel_rtype, 0, &inv_buf),
232 	    off, value, secname, (*rel_desc_sname_func)(rdesc),
233 	    MSG_ORIG(MSG_STR_EMPTY));
234 }
235 
236 void
237 Dbg_reloc_dooutrel(Lm_list *lml, Word type)
238 {
239 	if (DBG_NOTCLASS(DBG_C_RELOC))
240 		return;
241 	if (DBG_NOTDETAIL())
242 		return;
243 
244 	Dbg_util_nl(lml, DBG_NL_STD);
245 	dbg_print(lml, MSG_INTL(MSG_REL_CREATING));
246 	Elf_reloc_title(lml, ELF_DBG_LD, type);
247 }
248 
249 void
250 Dbg_reloc_discard(Lm_list *lml, Half mach, Rel_desc *rsp)
251 {
252 	dbg_isec_name_buf_t	buf;
253 	char			*alloc_mem;
254 	Conv_inv_buf_t		inv_buf;
255 	Is_desc			*isp;
256 
257 	if (DBG_NOTCLASS(DBG_C_RELOC))
258 		return;
259 	if (DBG_NOTDETAIL())
260 		return;
261 
262 	isp = rsp->rel_isdesc;
263 	dbg_print(lml, MSG_INTL(MSG_REL_DISCARDED),
264 	    dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name,
265 	    conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf),
266 	    EC_OFF(rsp->rel_roffset));
267 	if (alloc_mem != NULL)
268 		free(alloc_mem);
269 }
270 
271 void
272 Dbg_reloc_transition(Lm_list *lml, Half mach, Word rtype, Rel_desc *rsp,
273     rel_desc_sname_func_t rel_desc_sname_func)
274 {
275 	dbg_isec_name_buf_t	buf;
276 	char			*alloc_mem;
277 	Conv_inv_buf_t		inv_buf1, inv_buf2;
278 	Is_desc			*isp;
279 
280 	if (DBG_NOTCLASS(DBG_C_RELOC))
281 		return;
282 
283 	isp = rsp->rel_isdesc;
284 	dbg_print(lml, MSG_INTL(MSG_REL_TRANSITION),
285 	    conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf1),
286 	    dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name,
287 	    EC_OFF(rsp->rel_roffset), (*rel_desc_sname_func)(rsp),
288 	    conv_reloc_type(mach, rtype, 0, &inv_buf2));
289 	if (alloc_mem != NULL)
290 		free(alloc_mem);
291 }
292 
293 void
294 Dbg_reloc_out(Ofl_desc *ofl, int caller, Word type, void *reloc,
295     const char *secname, const char *symname)
296 {
297 	if (DBG_NOTCLASS(DBG_C_RELOC))
298 		return;
299 	if (DBG_NOTDETAIL())
300 		return;
301 
302 	Elf_reloc_entry_1(ofl->ofl_lml, caller, MSG_ORIG(MSG_STR_EMPTY),
303 	    ofl->ofl_dehdr->e_machine, type, reloc, secname, symname,
304 	    MSG_ORIG(MSG_STR_EMPTY));
305 }
306 
307 void
308 Dbg_reloc_in(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
309     const char *secname, Word secndx, const char *symname)
310 {
311 	dbg_isec_name_buf_t	buf;
312 	char			*alloc_mem;
313 
314 	if (DBG_NOTCLASS(DBG_C_RELOC))
315 		return;
316 	if (DBG_NOTDETAIL())
317 		return;
318 
319 	Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc,
320 	    dbg_fmt_isec_name2(secname, secndx, buf, &alloc_mem), symname,
321 	    MSG_ORIG(MSG_STR_EMPTY));
322 
323 	if (alloc_mem != NULL)
324 		free(alloc_mem);
325 }
326 
327 /*
328  * Used by ld when '-z relaxreloc' is in use and a relocation
329  * is redirected to a kept section.
330  *
331  * entry:
332  *	lml - Link map control list
333  *	sdp - The replacement symbol to be used with the relocation,
334  *		which references the kept section.
335  */
336 void
337 Dbg_reloc_sloppycomdat(Lm_list *lml, Sym_desc *sdp)
338 {
339 	dbg_isec_name_buf_t	buf;
340 	char			*alloc_mem;
341 	const char		*nfname;
342 
343 	if (DBG_NOTCLASS(DBG_C_RELOC) || DBG_NOTDETAIL())
344 		return;
345 
346 	nfname = (sdp && sdp->sd_file && sdp->sd_file->ifl_name)
347 	    ? sdp->sd_file->ifl_name : MSG_INTL(MSG_STR_NULL);
348 
349 	dbg_print(lml, MSG_INTL(MSG_REL_SLOPPYCOMDAT),
350 	    dbg_fmt_isec_name(sdp->sd_isc, buf, &alloc_mem), nfname);
351 	if (alloc_mem != NULL)
352 		free(alloc_mem);
353 }
354 
355 /*
356  * Print a output relocation structure (Rel_desc).
357  */
358 void
359 Dbg_reloc_ors_entry(Lm_list *lml, int caller, Word type, Half mach,
360     Rel_desc *orsp)
361 {
362 	Conv_inv_buf_t	inv_buf;
363 	const char	*secname, *symname;
364 
365 	if (DBG_NOTCLASS(DBG_C_RELOC))
366 		return;
367 	if (DBG_NOTDETAIL())
368 		return;
369 
370 	if (orsp->rel_flags & (FLG_REL_GOT | FLG_REL_RFPTR1 | FLG_REL_RFPTR2)) {
371 		secname = MSG_ORIG(MSG_SCN_GOT);
372 	} else if (orsp->rel_flags & FLG_REL_PLT) {
373 		secname = MSG_ORIG(MSG_SCN_PLT);
374 	} else if (orsp->rel_flags & FLG_REL_BSS) {
375 		secname = MSG_ORIG(MSG_SCN_BSS);
376 	} else {
377 		Os_desc *osp = RELAUX_GET_OSDESC(orsp);
378 
379 		secname = osp ? osp->os_name : MSG_INTL(MSG_STR_NULL);
380 	}
381 
382 	/*
383 	 * Register symbols can be relocated/initialized to a constant, which
384 	 * is a special case where the symbol index is 0.
385 	 */
386 	if (orsp->rel_sym != NULL)
387 		symname = orsp->rel_sym->sd_name;
388 	else
389 		symname = MSG_ORIG(MSG_STR_EMPTY);
390 
391 	Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_OUT), type,
392 	    conv_reloc_type(mach, orsp->rel_rtype, 0, &inv_buf),
393 	    orsp->rel_roffset, orsp->rel_raddend, secname, symname,
394 	    MSG_ORIG(MSG_STR_EMPTY));
395 }
396 
397 /*
398  * Print a Active relocation structure (Rel_desc).
399  */
400 void
401 Dbg_reloc_ars_entry(Lm_list *lml, int caller, Word type, Half mach,
402     Rel_desc *arsp)
403 {
404 	Conv_inv_buf_t	inv_buf;
405 	const char	*secname;
406 
407 	if (DBG_NOTCLASS(DBG_C_RELOC))
408 		return;
409 	if (DBG_NOTDETAIL())
410 		return;
411 
412 	if (arsp->rel_flags & (FLG_REL_GOT | FLG_REL_FPTR))
413 		secname = MSG_ORIG(MSG_SCN_GOT);
414 	else
415 		secname = RELAUX_GET_OSDESC(arsp)->os_name;
416 
417 	Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_ACT), type,
418 	    conv_reloc_type(mach, arsp->rel_rtype, 0, &inv_buf),
419 	    arsp->rel_roffset, arsp->rel_raddend, secname,
420 	    arsp->rel_sym->sd_name, MSG_ORIG(MSG_STR_EMPTY));
421 }
422 
423 void
424 Dbg_reloc_entry(Lm_list *lml, const char *prestr, Half mach, Word type,
425     void *reloc, const char *secname, const char *symname, const char *poststr)
426 {
427 	/*
428 	 * Register relocations can use a constant initializer, in which case
429 	 * the associated symbol is 0.
430 	 */
431 	if (symname == NULL)
432 		symname = MSG_ORIG(MSG_STR_EMPTY);
433 
434 	Elf_reloc_entry_1(lml, ELF_DBG_LD, prestr, mach, type, reloc, secname,
435 	    symname, poststr);
436 }
437 
438 #if	defined(_ELF64)
439 
440 void
441 Dbg64_pltpad_to(Lm_list *lml, const char *file, Addr pltpad,
442     const char *dfile, const char *symname)
443 {
444 	if (DBG_NOTCLASS(DBG_C_RELOC))
445 		return;
446 	if (DBG_NOTDETAIL())
447 		return;
448 
449 	dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), file,
450 	    dfile, symname);
451 }
452 
453 void
454 Dbg64_pltpad_from(Lm_list *lml, const char *file, const char *sname,
455     Addr pltpad)
456 {
457 	if (DBG_NOTCLASS(DBG_C_RELOC))
458 		return;
459 	if (DBG_NOTDETAIL())
460 		return;
461 
462 	dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), file,
463 	    Dbg_demangle_name(sname));
464 }
465 
466 #endif
467 
468 /*
469  * Relocation output can differ depending on the caller and the type of
470  * relocation record.  However, the final diagnostic is maintained here so
471  * that the various message strings remain consistent.
472  *
473  * elfdump:
474  *               type       offset     addend    section   symbol
475  *               X          X          X         X         X              (Rela)
476  *
477  *               type       offset               section   symbol
478  *               X          X                    X         X              (Rel)
479  *
480  * Note, it could be argued that the section name output with elfdump(1) is
481  * unnecessary, as the table itself is identified with a title that reveals
482  * the section name.  However, the output does provide for grep(1)'ing for
483  * individual entries and obtaining the section name with this type of input.
484  *
485  * ld.so.1:
486  *   (prestr)    type       offset     addend    symbol
487  *                                     value
488  *       in      X          X          X         X                        (Rela)
489  *    apply                 X          X
490  *
491  *   (prestr)    type       offset     value     symbol
492  *       in      X          X                    X                        (Rel)
493  *    apply                 X          X
494  *
495  * ld:
496  *   (prestr)    type       offset     addend    section   symbol
497  *       in      X          X          X         X         X              (Rela)
498  *      act      X          X                    X         X
499  *      out      X          X                    X         X
500  *
501  *   (prestr)    type       offset               section   symbol
502  *       in      X          X                    X         X              (Rel)
503  *      act      X          X                    X         X
504  *      out      X          X                    X         X
505  *
506  * Both Rela and Rel active relocations are printed as:
507  *
508  *               type       offset     value     section   symbol
509  *               X          X          X         X         X
510  */
511 void
512 Elf_reloc_title(Lm_list *lml, int caller, Word type)
513 {
514 	if (caller == ELF_DBG_ELFDUMP) {
515 		if (type == SHT_RELA) {
516 			if (DBG_NOTLONG())
517 				dbg_print(lml, MSG_INTL(MSG_REL_EFSA_TITLE));
518 			else
519 				dbg_print(lml, MSG_INTL(MSG_REL_EFLA_TITLE));
520 		} else {
521 			if (DBG_NOTLONG())
522 				dbg_print(lml, MSG_INTL(MSG_REL_EFSN_TITLE));
523 			else
524 				dbg_print(lml, MSG_INTL(MSG_REL_EFLN_TITLE));
525 		}
526 		return;
527 	}
528 	if (caller == ELF_DBG_RTLD) {
529 		if (type == SHT_RELA) {
530 			dbg_print(lml, MSG_INTL(MSG_REL_RTA_TITLE));
531 			dbg_print(lml, MSG_INTL(MSG_REL_RTV_TITLE));
532 		} else
533 			dbg_print(lml, MSG_INTL(MSG_REL_RTN_TITLE));
534 		return;
535 	}
536 	if (caller == ELF_DBG_LD) {
537 		if (type == SHT_RELA) {
538 			if (DBG_NOTLONG())
539 				dbg_print(lml, MSG_INTL(MSG_REL_LDSA_TITLE));
540 			else
541 				dbg_print(lml, MSG_INTL(MSG_REL_LDLA_TITLE));
542 		} else {
543 			if (DBG_NOTLONG())
544 				dbg_print(lml, MSG_INTL(MSG_REL_LDSN_TITLE));
545 			else
546 				dbg_print(lml, MSG_INTL(MSG_REL_LDLN_TITLE));
547 		}
548 		return;
549 	}
550 	if (caller == ELF_DBG_LD_ACT) {
551 		if (DBG_NOTLONG())
552 			dbg_print(lml, MSG_INTL(MSG_REL_LDSV_TITLE));
553 		else
554 			dbg_print(lml, MSG_INTL(MSG_REL_LDLV_TITLE));
555 		return;
556 	}
557 }
558 
559 void
560 Elf_reloc_entry_2(Lm_list *lml, int caller, const char *prestr, Word type,
561     const char *typestr, Addr off, Sxword add, const char *secname,
562     const char *symname, const char *poststr)
563 {
564 	if (symname)
565 		symname = Elf_demangle_name(symname);
566 	else
567 		symname = MSG_ORIG(MSG_STR_EMPTY);
568 
569 	if (caller == ELF_DBG_ELFDUMP) {
570 		if (type == SHT_RELA) {
571 			if (DBG_NOTLONG())
572 				dbg_print(lml, MSG_INTL(MSG_REL_EFSA_ENTRY),
573 				    typestr, EC_OFF(off), EC_SXWORD(add),
574 				    secname, symname);
575 			else
576 				dbg_print(lml, MSG_INTL(MSG_REL_EFLA_ENTRY),
577 				    typestr, EC_OFF(off), EC_SXWORD(add),
578 				    secname, symname);
579 		} else {
580 			if (DBG_NOTLONG())
581 				dbg_print(lml, MSG_INTL(MSG_REL_EFSN_ENTRY),
582 				    typestr, EC_OFF(off), secname, symname);
583 			else
584 				dbg_print(lml, MSG_INTL(MSG_REL_EFLN_ENTRY),
585 				    typestr, EC_OFF(off), secname, symname);
586 		}
587 		return;
588 	}
589 	if (caller == ELF_DBG_RTLD) {
590 		if (type == SHT_RELA)
591 			dbg_print(lml, MSG_INTL(MSG_REL_RTA_ENTRY), prestr,
592 			    typestr, EC_OFF(off), EC_SXWORD(add), symname,
593 			    poststr);
594 		else
595 			dbg_print(lml, MSG_INTL(MSG_REL_RTN_ENTRY), prestr,
596 			    typestr, EC_OFF(off), symname, poststr);
597 		return;
598 	}
599 	if (caller == ELF_DBG_LD) {
600 		if (type == SHT_RELA) {
601 			if (DBG_NOTLONG())
602 				dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY),
603 				    prestr, typestr, EC_OFF(off),
604 				    EC_SXWORD(add), secname, symname, poststr);
605 			else
606 				dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY),
607 				    prestr, typestr, EC_OFF(off),
608 				    EC_SXWORD(add), secname, symname, poststr);
609 		} else {
610 			if (DBG_NOTLONG())
611 				dbg_print(lml, MSG_INTL(MSG_REL_LDSN_ENTRY),
612 				    prestr, typestr, EC_OFF(off), secname,
613 				    symname, poststr);
614 			else
615 				dbg_print(lml, MSG_INTL(MSG_REL_LDLN_ENTRY),
616 				    prestr, typestr, EC_OFF(off), secname,
617 				    symname, poststr);
618 		}
619 		return;
620 	}
621 	if (caller == ELF_DBG_LD_ACT) {
622 		longlong_t	value = EC_SXWORD(add);
623 
624 		/*
625 		 * The following diagnostics are used to create active
626 		 * relocation output.  A "value" field is specified in the
627 		 * same column as a RELA addend.
628 		 *
629 		 * We have to work around an issue caused by the use of a
630 		 * common format string to handle both the 32-bit and 64-bit
631 		 * cases.  'add' is a signed value.  In the ELFCLASS32 case
632 		 * where add is a 32-bit value, the EC_SXWORD() macro widens
633 		 * it to a 64-bit signed value, which will cause sign extension
634 		 * in the upper 32-bits.  As we are displaying the value in hex,
635 		 * this causes our 32-bit value to be displayed with 16 hex
636 		 * digits instead of 8, as would be appropriate for ELFCLASS32.
637 		 *
638 		 * The solution is to mask off the unwanted bits before
639 		 * formatting the value.  The use of 'longlong_t' instead of
640 		 * Elf64_Sxword (used by the EC_SXWORD macro) is for the
641 		 * benefit of lint.
642 		 */
643 #if	!defined(_ELF64)
644 		value &= 0xffffffff;
645 #endif
646 		if (DBG_NOTLONG())
647 			dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY),
648 			    prestr, typestr, EC_OFF(off),
649 			    value, secname, symname, poststr);
650 		else
651 			dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY),
652 			    prestr, typestr, EC_OFF(off),
653 			    value, secname, symname, poststr);
654 	}
655 }
656 
657 void
658 Elf_reloc_entry_1(Lm_list *lml, int caller, const char *prestr, Half mach,
659     Word type, void *reloc, const char *secname, const char *symname,
660     const char *poststr)
661 {
662 	Conv_inv_buf_t	inv_buf;
663 	Addr		off;
664 	Sxword		add;
665 	const char	*str;
666 
667 	if (type == SHT_RELA) {
668 		Rela	*rela = (Rela *)reloc;
669 
670 		str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach),
671 		    0, &inv_buf);
672 		off = rela->r_offset;
673 		add = rela->r_addend;
674 	} else {
675 		Rel	*rel = (Rel *)reloc;
676 
677 		str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach),
678 		    0, &inv_buf);
679 		off = rel->r_offset;
680 		add = 0;
681 	}
682 	Elf_reloc_entry_2(lml, caller, prestr, type, str, off, add, secname,
683 	    symname, poststr);
684 }
685 
686 /*
687  * Display any applied relocations.  Presently, these are only called from
688  * ld.so.1, but the interfaces are maintained here to insure consistency with
689  * other relocation diagnostics.
690  */
691 void
692 Elf_reloc_apply_val(Lm_list *lml, int caller, Xword offset, Xword value)
693 {
694 	if (caller == ELF_DBG_RTLD)
695 		dbg_print(lml, MSG_INTL(MSG_REL_RT_APLVAL), EC_XWORD(offset),
696 		    EC_XWORD(value));
697 }
698 void
699 Elf_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword offset,
700     Xword value)
701 {
702 	Conv_inv_buf_t inv_buf;
703 
704 	if (caller == ELF_DBG_RTLD)
705 		dbg_print(lml, MSG_INTL(MSG_REL_RT_APLREG),
706 		    conv_sym_value(mach, STT_SPARC_REGISTER,
707 		    offset, &inv_buf), EC_XWORD(value));
708 }
709