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
Dbg_reloc_apply_reg(Lm_list * lml,int caller,Half mach,Xword off,Xword value)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
Dbg_reloc_apply_val(Lm_list * lml,int caller,Xword off,Xword value)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
Dbg_reloc_error(Lm_list * lml,int caller,Half mach,Word type,void * reloc,const char * sname)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
Dbg_reloc_run(Rt_map * lmp,uint_t rtype,int info,int dtype)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
Dbg_reloc_copy(Rt_map * dlmp,Rt_map * nlmp,const char * name,int zero)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
Dbg_reloc_generate(Lm_list * lml,Os_desc * osp,Word type)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
Dbg_reloc_proc(Lm_list * lml,Os_desc * osp,Is_desc * isp,Is_desc * risp)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
Dbg_reloc_doact_title(Lm_list * lml)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
Dbg_reloc_doact(Lm_list * lml,int caller,Half mach,Word type,Rel_desc * rdesc,Xword off,Xword value,rel_desc_sname_func_t rel_desc_sname_func)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
Dbg_reloc_dooutrel(Lm_list * lml,Word type)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
Dbg_reloc_discard(Lm_list * lml,Half mach,Rel_desc * rsp)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
Dbg_reloc_transition(Lm_list * lml,Half mach,Word rtype,Rel_desc * rsp,rel_desc_sname_func_t rel_desc_sname_func)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
Dbg_reloc_out(Ofl_desc * ofl,int caller,Word type,void * reloc,const char * secname,const char * symname)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
Dbg_reloc_in(Lm_list * lml,int caller,Half mach,Word type,void * reloc,const char * secname,Word secndx,const char * symname)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
Dbg_reloc_sloppycomdat(Lm_list * lml,Sym_desc * sdp)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
Dbg_reloc_ors_entry(Lm_list * lml,int caller,Word type,Half mach,Rel_desc * orsp)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
Dbg_reloc_ars_entry(Lm_list * lml,int caller,Word type,Half mach,Rel_desc * arsp)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
Dbg_reloc_entry(Lm_list * lml,const char * prestr,Half mach,Word type,void * reloc,const char * secname,const char * symname,const char * poststr)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
Dbg64_pltpad_to(Lm_list * lml,const char * file,Addr pltpad,const char * dfile,const char * symname)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
Dbg64_pltpad_from(Lm_list * lml,const char * file,const char * sname,Addr pltpad)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
Elf_reloc_title(Lm_list * lml,int caller,Word type)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
Elf_reloc_entry_2(Lm_list * lml,int caller,const char * prestr,Word type,const char * typestr,Addr off,Sxword add,const char * secname,const char * symname,const char * poststr)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
Elf_reloc_entry_1(Lm_list * lml,int caller,const char * prestr,Half mach,Word type,void * reloc,const char * secname,const char * symname,const char * poststr)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
Elf_reloc_apply_val(Lm_list * lml,int caller,Xword offset,Xword value)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
Elf_reloc_apply_reg(Lm_list * lml,int caller,Half mach,Xword offset,Xword value)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