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