xref: /titanic_50/usr/src/cmd/sgs/liblddbg/common/relocate.c (revision fa9e4066f08beec538e775443c5be79dd423fcab)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include	"msg.h"
29 #include	"_debug.h"
30 #include	"libld.h"
31 #include	<sys/elf_SPARC.h>
32 
33 
34 void _gelf_reloc_entry(const char *prestr, GElf_Half mach,
35     GElf_Word type, void *reloc,
36     const char *sec, const char *name, const char *com);
37 
38 void
39 Dbg_reloc_generate(Os_desc * osp, Word relshtype)
40 {
41 	if (DBG_NOTCLASS(DBG_RELOC))
42 		return;
43 	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
44 	dbg_print(MSG_INTL(MSG_REL_GENERATE), osp->os_name);
45 	if (DBG_NOTDETAIL())
46 		return;
47 	if (relshtype == SHT_RELA)
48 		dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2));
49 	else
50 		dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2));
51 }
52 
53 void
54 Dbg_reloc_proc(Os_desc *osp, Is_desc *isp, Is_desc *risp)
55 {
56 	const char	*str1, *str2;
57 
58 	if (DBG_NOTCLASS(DBG_RELOC))
59 		return;
60 
61 	if (osp && osp->os_name)
62 		str1 = osp->os_name;
63 	else
64 		str1 =	MSG_INTL(MSG_STR_NULL);
65 
66 	if (isp && isp->is_file)
67 		str2 = isp->is_file->ifl_name;
68 	else if (risp && risp->is_file)
69 		str2 = risp->is_file->ifl_name;
70 	else
71 		str2 = MSG_INTL(MSG_STR_NULL);
72 
73 	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
74 	dbg_print(MSG_INTL(MSG_REL_COLLECT), str1, str2);
75 	if (DBG_NOTDETAIL())
76 		return;
77 
78 	/*
79 	 * Determine the relocation titles from the sections type.
80 	 */
81 	if (risp->is_shdr->sh_type == SHT_RELA)
82 		dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2));
83 	else
84 		dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2));
85 }
86 
87 #if	!defined(_ELF64)
88 void
89 Dbg_reloc_doactiverel()
90 {
91 	if (DBG_NOTCLASS(DBG_RELOC))
92 		return;
93 	if (DBG_NOTDETAIL())
94 		return;
95 
96 	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
97 	dbg_print(MSG_INTL(MSG_REL_ACTIVE));
98 	dbg_print(MSG_ORIG(MSG_REL_TITLE_1));
99 }
100 #endif /* !defined(_ELF64) */
101 
102 void
103 Dbg_reloc_doact(Half mach, Word rtype, Xword off, Xword value, const char *sym,
104     Os_desc *osp)
105 {
106 	const char	*sec;
107 	const char	*msg;
108 
109 	if (DBG_NOTCLASS(DBG_RELOC))
110 		return;
111 	if (DBG_NOTDETAIL())
112 		return;
113 	if (DBG_NOTLONG())
114 		msg = MSG_ORIG(MSG_REL_ARGS_6);
115 	else
116 		msg = MSG_ORIG(MSG_REL_L_ARGS_6);
117 
118 	if (osp) {
119 		sec = osp->os_name;
120 		off += osp->os_shdr->sh_offset;
121 	} else
122 		sec = MSG_ORIG(MSG_STR_EMPTY);
123 
124 	dbg_print(msg, MSG_ORIG(MSG_STR_EMPTY),
125 	    conv_reloc_type_str(mach, rtype), EC_OFF(off), EC_XWORD(value),
126 	    sec, _Dbg_sym_dem(sym), MSG_ORIG(MSG_STR_EMPTY));
127 }
128 
129 void
130 Dbg_reloc_dooutrel(GElf_Word type)
131 {
132 	if (DBG_NOTCLASS(DBG_RELOC))
133 		return;
134 	if (DBG_NOTDETAIL())
135 		return;
136 
137 	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
138 	dbg_print(MSG_INTL(MSG_REL_CREATING));
139 
140 	if (type == SHT_RELA)
141 		dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2));
142 	else
143 		dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2));
144 }
145 
146 void
147 Dbg_reloc_discard(Half mach, Rel_desc *rsp)
148 {
149 	if (DBG_NOTCLASS(DBG_RELOC))
150 		return;
151 	if (DBG_NOTDETAIL())
152 		return;
153 
154 	dbg_print(MSG_INTL(MSG_REL_DISCARDED), rsp->rel_isdesc->is_basename,
155 		rsp->rel_isdesc->is_file->ifl_name,
156 		conv_reloc_type_str(mach, rsp->rel_rtype),
157 		EC_OFF(rsp->rel_roffset));
158 }
159 
160 void
161 Dbg_reloc_transition(Half mach, Word oldrtype, Word newrtype, Xword off,
162 	const char *sym)
163 {
164 	if (DBG_NOTCLASS(DBG_RELOC))
165 		return;
166 	dbg_print(MSG_INTL(MSG_REL_TRANS), EC_OFF(off),
167 		conv_reloc_type_str(mach, oldrtype) + M_R_STR_LEN,
168 		conv_reloc_type_str(mach, newrtype) + M_R_STR_LEN,
169 		sym);
170 }
171 
172 void
173 Dbg_reloc_reg_apply(unsigned long long off, unsigned long long value)
174 {
175 	if (DBG_NOTCLASS(DBG_RELOC))
176 		return;
177 	if (DBG_NOTDETAIL())
178 		return;
179 	dbg_print(MSG_ORIG(MSG_REL_REGSYM),
180 #if	defined(_ELF64)
181 		conv_sym_value_str(EM_SPARCV9, STT_SPARC_REGISTER, off),
182 #else
183 		conv_sym_value_str(EM_SPARC, STT_SPARC_REGISTER, off),
184 #endif
185 		value);
186 }
187 
188 #if	!defined(_ELF64)
189 void
190 Dbg_reloc_apply(unsigned long long off, unsigned long long value)
191 {
192 	if (DBG_NOTCLASS(DBG_RELOC))
193 		return;
194 	if (DBG_NOTDETAIL())
195 		return;
196 
197 	/*
198 	 * Print the actual relocation being applied to the specified output
199 	 * section, the offset represents the actual relocation address, and the
200 	 * value is the new data being written to that address).
201 	 */
202 	dbg_print(MSG_ORIG(MSG_REL_ARGS_2), off, value);
203 }
204 #endif	/* !defined(_ELF64) */
205 
206 void
207 Dbg_reloc_out(Half mach, Word type, void *rel, const char *name,
208 	const char *relsectname)
209 {
210 	if (DBG_NOTCLASS(DBG_RELOC))
211 		return;
212 	if (DBG_NOTDETAIL())
213 		return;
214 
215 	_gelf_reloc_entry(MSG_ORIG(MSG_STR_EMPTY), mach, type, rel,
216 	    relsectname, _Dbg_sym_dem(name), MSG_ORIG(MSG_STR_EMPTY));
217 }
218 
219 void
220 Dbg_reloc_in(Half mach, Word type, void *rel, const char *name,
221     const char *iname)
222 {
223 	if (DBG_NOTCLASS(DBG_RELOC))
224 		return;
225 	if (DBG_NOTDETAIL())
226 		return;
227 
228 	_gelf_reloc_entry(MSG_INTL(MSG_STR_IN), mach, type, rel,
229 	    (iname ? iname : MSG_ORIG(MSG_STR_EMPTY)),
230 	    (name ? _Dbg_sym_dem(name) : MSG_ORIG(MSG_STR_EMPTY)),
231 	    MSG_ORIG(MSG_STR_EMPTY));
232 }
233 
234 void
235 Dbg_reloc_error(Half mach, Word type, void *rel, const char *name,
236     const char *com)
237 {
238 	if (DBG_NOTCLASS(DBG_RELOC))
239 		return;
240 	if (DBG_NOTDETAIL())
241 		return;
242 
243 	_gelf_reloc_entry(MSG_INTL(MSG_STR_ERROR), mach, type, rel,
244 	    MSG_ORIG(MSG_STR_EMPTY),
245 	    (name ? _Dbg_sym_dem(name) : MSG_ORIG(MSG_STR_EMPTY)),
246 	    (com ? com : MSG_ORIG(MSG_STR_EMPTY)));
247 }
248 
249 /*
250  * Print a output relocation structure(Rel_desc).
251  */
252 void
253 Dbg_reloc_ors_entry(Half mach, Rel_desc *orsp)
254 {
255 	const char	*os_name;
256 	const char	*sym_name;
257 	const char 	*msg;
258 
259 	if (DBG_NOTCLASS(DBG_RELOC))
260 		return;
261 	if (DBG_NOTDETAIL())
262 		return;
263 	if (DBG_NOTLONG())
264 		msg = MSG_ORIG(MSG_REL_ARGS_5);
265 	else
266 		msg = MSG_ORIG(MSG_REL_L_ARGS_5);
267 
268 	if (orsp->rel_flags & (FLG_REL_GOT | FLG_REL_RFPTR1 | FLG_REL_RFPTR2))
269 		os_name = MSG_ORIG(MSG_SCN_GOT);
270 	else if (orsp->rel_flags & FLG_REL_PLT)
271 		os_name = MSG_ORIG(MSG_SCN_PLT);
272 	else if (orsp->rel_flags & FLG_REL_BSS)
273 		os_name = MSG_ORIG(MSG_SCN_BSS);
274 	else if (orsp->rel_osdesc)
275 		os_name = orsp->rel_osdesc->os_name;
276 	else
277 		os_name = MSG_INTL(MSG_STR_NULL);
278 
279 	/*
280 	 * Register symbols can be relocated/initialized
281 	 * to a constant, which is a special case where
282 	 * the symbol index is 0.
283 	 */
284 	if (orsp->rel_sym != NULL)
285 		sym_name = orsp->rel_sym->sd_name;
286 	else
287 		sym_name = MSG_ORIG(MSG_STR_EMPTY);
288 
289 	dbg_print(msg, MSG_INTL(MSG_STR_OUT),
290 	    conv_reloc_type_str(mach, orsp->rel_rtype),
291 	    EC_OFF(orsp->rel_roffset), os_name,
292 	    _Dbg_sym_dem(sym_name), MSG_ORIG(MSG_STR_EMPTY));
293 }
294 
295 /*
296  * Print a Active relocation structure (Rel_desc).
297  */
298 void
299 Dbg_reloc_ars_entry(Half mach, Rel_desc *arsp)
300 {
301 	const char	*os_name;
302 	const char	*msg;
303 
304 	if (DBG_NOTCLASS(DBG_RELOC))
305 		return;
306 	if (DBG_NOTDETAIL())
307 		return;
308 	if (DBG_NOTLONG())
309 		msg = MSG_ORIG(MSG_REL_ARGS_5);
310 	else
311 		msg = MSG_ORIG(MSG_REL_L_ARGS_5);
312 
313 	if (arsp->rel_flags & (FLG_REL_GOT | FLG_REL_FPTR))
314 		os_name = MSG_ORIG(MSG_SCN_GOT);
315 	else
316 		os_name = arsp->rel_osdesc->os_name;
317 
318 	dbg_print(msg, MSG_INTL(MSG_STR_ACT),
319 	    conv_reloc_type_str(mach, arsp->rel_rtype),
320 	    EC_OFF(arsp->rel_roffset), os_name,
321 	    _Dbg_sym_dem(arsp->rel_sym->sd_name), MSG_ORIG(MSG_STR_EMPTY));
322 }
323 
324 #if	!defined(_ELF64)
325 void
326 Dbg_reloc_run(const char *file, uint_t rel, int info, int type)
327 {
328 	const char	*str;
329 
330 	if (DBG_NOTCLASS(DBG_RELOC))
331 		return;
332 
333 	if (type == DBG_REL_FINISH) {
334 		if (info)
335 			str = MSG_ORIG(MSG_STR_EMPTY);
336 		else
337 			str = MSG_INTL(MSG_REL_RELOC_FAIL);
338 	} else {
339 		if (info)
340 			str = MSG_INTL(MSG_REL_RELOC_PLT);
341 		else
342 			str = MSG_ORIG(MSG_STR_EMPTY);
343 	}
344 
345 	if (type == DBG_REL_START) {
346 		dbg_print(MSG_ORIG(MSG_STR_EMPTY));
347 		dbg_print(MSG_INTL(MSG_REL_RELOC_START), file, str);
348 
349 		if (DBG_NOTDETAIL())
350 			return;
351 
352 		if (rel == SHT_RELA) {
353 			dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_3));
354 			dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_4));
355 		} else
356 			dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_3));
357 	} else {
358 		if (type == DBG_REL_NONE) {
359 			dbg_print(MSG_ORIG(MSG_STR_EMPTY));
360 			dbg_print(MSG_INTL(MSG_REL_RELOC_NONE), file, str);
361 		} else
362 			dbg_print(MSG_INTL(MSG_REL_RELOC_FINISH), file, str);
363 
364 		dbg_print(MSG_ORIG(MSG_STR_EMPTY));
365 	}
366 }
367 
368 void
369 Dbg_reloc_copy(const char *dname, const char *rname, const char *sname,
370     int zero)
371 {
372 	const char	*str;
373 
374 	if (DBG_NOTCLASS(DBG_RELOC))
375 		return;
376 	if (DBG_NOTDETAIL())
377 		return;
378 
379 	if (zero)
380 		str = MSG_INTL(MSG_STR_COPYZERO);
381 	else
382 		str = MSG_ORIG(MSG_STR_EMPTY);
383 
384 	dbg_print(MSG_INTL(MSG_REL_COPY), dname, rname, sname, str);
385 }
386 
387 /*
388  * Print a relocation entry. This can either be an input or output
389  * relocation record, and specifies the relocation section for which is
390  * associated.
391  */
392 void
393 Gelf_reloc_entry(const char *prestr, GElf_Half mach, GElf_Word type,
394     GElf_Rela *rel, const char *sec, const char *name)
395 {
396 	const char *msg;
397 
398 	if (type == SHT_RELA) {
399 		if (DBG_NOTLONG())
400 			msg = MSG_ORIG(MSG_REL_ARGS_6);
401 		else
402 			msg = MSG_ORIG(MSG_REL_L_ARGS_6);
403 	} else {
404 		if (DBG_NOTLONG())
405 			msg = MSG_ORIG(MSG_REL_ARGS_5);
406 		else
407 			msg = MSG_ORIG(MSG_REL_L_ARGS_5);
408 	}
409 
410 	if (type == SHT_RELA)
411 		dbg_print(msg, prestr,
412 		    conv_reloc_type_str(mach, (uint_t)GELF_R_TYPE(rel->r_info)),
413 			EC_ADDR(rel->r_offset), EC_XWORD(rel->r_addend),
414 			sec, _Dbg_sym_dem(name), MSG_ORIG(MSG_STR_EMPTY));
415 	else
416 		dbg_print(msg, prestr,
417 		    conv_reloc_type_str(mach, (uint_t)GELF_R_TYPE(rel->r_info)),
418 			EC_ADDR(rel->r_offset), sec, _Dbg_sym_dem(name),
419 			MSG_ORIG(MSG_STR_EMPTY));
420 }
421 
422 void
423 _gelf_reloc_entry(const char *prestr, GElf_Half mach, GElf_Word type,
424     void *reloc, const char *sec, const char *name, const char *com)
425 {
426 	const char *msg;
427 
428 	/*
429 	 * Register relocations can use a constant initialzer,
430 	 * in which case the associated symbol is 0.
431 	 */
432 	if (name == NULL)
433 		name = MSG_ORIG(MSG_STR_EMPTY);
434 
435 	if (type == SHT_RELA) {
436 		if (DBG_NOTLONG())
437 			msg = MSG_ORIG(MSG_REL_ARGS_6);
438 		else
439 			msg = MSG_ORIG(MSG_REL_L_ARGS_6);
440 	} else {
441 		if (DBG_NOTLONG())
442 			msg = MSG_ORIG(MSG_REL_ARGS_5);
443 		else
444 			msg = MSG_ORIG(MSG_REL_L_ARGS_5);
445 	}
446 
447 	if ((mach == EM_SPARCV9) || (mach == EM_AMD64)) {
448 		Elf64_Rela * rel = (Elf64_Rela *)reloc;
449 
450 		if (type == SHT_RELA) {
451 			dbg_print(msg, prestr,
452 			    conv_reloc_type_str(mach,
453 				(uint_t)ELF64_R_TYPE(rel->r_info)),
454 			    EC_ADDR(rel->r_offset),
455 			    EC_XWORD(rel->r_addend),
456 			    sec, name, com);
457 		} else {
458 			dbg_print(msg, prestr,
459 			    conv_reloc_type_str(mach,
460 				(uint_t)ELF64_R_TYPE(rel->r_info)),
461 			    EC_ADDR(rel->r_offset), sec, name, com);
462 		}
463 	} else {
464 		Elf32_Rela * rel = (Elf32_Rela *)reloc;
465 
466 		if (type == SHT_RELA) {
467 			dbg_print(msg, prestr,
468 			    conv_reloc_type_str(mach,
469 				ELF32_R_TYPE(rel->r_info)),
470 			    EC_ADDR(rel->r_offset), EC_XWORD(rel->r_addend),
471 			    sec, name, com);
472 		} else {
473 			dbg_print(msg, prestr,
474 			    conv_reloc_type_str(mach,
475 				ELF32_R_TYPE(rel->r_info)),
476 			    EC_ADDR(rel->r_offset), sec, name, com);
477 		}
478 	}
479 }
480 #endif	/* !defined(_ELF64) */
481 
482 #if	defined(_ELF64)
483 void
484 Dbg_pltpad_boundto64(const char *file, Addr pltpad, const char *dfile,
485 	const char *symname)
486 {
487 	if (DBG_NOTCLASS(DBG_RELOC))
488 		return;
489 	if (DBG_NOTDETAIL())
490 		return;
491 	dbg_print(MSG_INTL(MSG_REL_PADBOUNDTO), file, EC_ADDR(pltpad),
492 	    dfile, symname);
493 }
494 
495 void
496 Dbg_pltpad_bindto64(const char *file, const char *sname, Addr pltpad)
497 {
498 	if (DBG_NOTCLASS(DBG_RELOC))
499 		return;
500 	if (DBG_NOTDETAIL())
501 		return;
502 	dbg_print(MSG_INTL(MSG_REL_PADBINDTO), file, _Dbg_sym_dem(sname),
503 	    EC_ADDR(pltpad));
504 }
505 #endif
506