xref: /titanic_41/usr/src/cmd/sgs/liblddbg/common/relocate.c (revision bf994817a71d4ac680198e25fe79d13c247306e0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
23*bf994817SAli Bahrami  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include	<sys/elf_SPARC.h>
275aefb655Srie #include	<debug.h>
285aefb655Srie #include	<libld.h>
295aefb655Srie #include	<conv.h>
305aefb655Srie #include	"_debug.h"
315aefb655Srie #include	"msg.h"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate void
Dbg_reloc_apply_reg(Lm_list * lml,int caller,Half mach,Xword off,Xword value)345aefb655Srie Dbg_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword off, Xword value)
357c478bd9Sstevel@tonic-gate {
365aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
377c478bd9Sstevel@tonic-gate 		return;
387c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
397c478bd9Sstevel@tonic-gate 		return;
405aefb655Srie 
415aefb655Srie 	/*
425aefb655Srie 	 * Print the actual relocation being applied to the specified output
435aefb655Srie 	 * section, the offset represents the actual relocation address, and the
445aefb655Srie 	 * value is the new data being written to that address.
455aefb655Srie 	 */
465aefb655Srie 	Elf_reloc_apply_reg(lml, caller, mach, off, value);
477c478bd9Sstevel@tonic-gate }
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate void
Dbg_reloc_apply_val(Lm_list * lml,int caller,Xword off,Xword value)505aefb655Srie Dbg_reloc_apply_val(Lm_list *lml, int caller, Xword off, Xword value)
515aefb655Srie {
525aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
535aefb655Srie 		return;
545aefb655Srie 	if (DBG_NOTDETAIL())
555aefb655Srie 		return;
565aefb655Srie 
575aefb655Srie 	/*
585aefb655Srie 	 * Print the actual relocation being applied to the specified output
595aefb655Srie 	 * section, the offset represents the actual relocation address, and the
605aefb655Srie 	 * value is the new data being written to that address.
615aefb655Srie 	 */
625aefb655Srie 	Elf_reloc_apply_val(lml, caller, off, value);
635aefb655Srie }
645aefb655Srie 
655aefb655Srie void
Dbg_reloc_error(Lm_list * lml,int caller,Half mach,Word type,void * reloc,const char * sname)665aefb655Srie Dbg_reloc_error(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
675aefb655Srie     const char *sname)
685aefb655Srie {
695aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
705aefb655Srie 		return;
715aefb655Srie 	if (DBG_NOTDETAIL())
725aefb655Srie 		return;
735aefb655Srie 
745aefb655Srie 	Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc,
755aefb655Srie 	    NULL, sname, MSG_INTL(MSG_REL_BADROFFSET));
765aefb655Srie }
775aefb655Srie 
785aefb655Srie void
Dbg_reloc_run(Rt_map * lmp,uint_t rtype,int info,int dtype)795aefb655Srie Dbg_reloc_run(Rt_map *lmp, uint_t rtype, int info, int dtype)
805aefb655Srie {
815aefb655Srie 	Lm_list		*lml = LIST(lmp);
825aefb655Srie 	const char	*str, *name = NAME(lmp);
835aefb655Srie 
845aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
855aefb655Srie 		return;
865aefb655Srie 
875aefb655Srie 	if (dtype == DBG_REL_FINISH) {
885aefb655Srie 		if (info)
895aefb655Srie 			str = MSG_ORIG(MSG_STR_EMPTY);
905aefb655Srie 		else
915aefb655Srie 			str = MSG_INTL(MSG_REL_FAIL);
925aefb655Srie 	} else {
935aefb655Srie 		if (info)
945aefb655Srie 			str = MSG_INTL(MSG_REL_PLT);
955aefb655Srie 		else
965aefb655Srie 			str = MSG_ORIG(MSG_STR_EMPTY);
975aefb655Srie 	}
985aefb655Srie 
995aefb655Srie 	if (dtype == DBG_REL_START) {
1005aefb655Srie 		Dbg_util_nl(lml, DBG_NL_STD);
1015aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_REL_START), name, str);
1025aefb655Srie 
1035aefb655Srie 		if (DBG_NOTDETAIL())
1045aefb655Srie 			return;
1055aefb655Srie 
1065aefb655Srie 		Elf_reloc_title(lml, ELF_DBG_RTLD, rtype);
1075aefb655Srie 
1085aefb655Srie 	} else {
1095aefb655Srie 		if (dtype == DBG_REL_NONE) {
1105aefb655Srie 			dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
1115aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_NONE), name, str);
1125aefb655Srie 		} else
1135aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_FINISH), name,
1145aefb655Srie 			    str);
1155aefb655Srie 
1165aefb655Srie 		Dbg_util_nl(lml, DBG_NL_STD);
1175aefb655Srie 	}
1185aefb655Srie }
1195aefb655Srie 
1205aefb655Srie void
Dbg_reloc_copy(Rt_map * dlmp,Rt_map * nlmp,const char * name,int zero)1215aefb655Srie Dbg_reloc_copy(Rt_map *dlmp, Rt_map *nlmp, const char *name, int zero)
1225aefb655Srie {
1235aefb655Srie 	const char	*str;
1245aefb655Srie 
1255aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
1265aefb655Srie 		return;
1275aefb655Srie 	if (DBG_NOTDETAIL())
1285aefb655Srie 		return;
1295aefb655Srie 
1305aefb655Srie 	if (zero)
1315aefb655Srie 		str = MSG_INTL(MSG_STR_COPYZERO);
1325aefb655Srie 	else
1335aefb655Srie 		str = MSG_ORIG(MSG_STR_EMPTY);
1345aefb655Srie 
1355aefb655Srie 	dbg_print(LIST(dlmp), MSG_INTL(MSG_REL_COPY), NAME(dlmp), NAME(nlmp),
1365aefb655Srie 	    name, str);
1375aefb655Srie }
1385aefb655Srie 
1395aefb655Srie void
Dbg_reloc_generate(Lm_list * lml,Os_desc * osp,Word type)1405aefb655Srie Dbg_reloc_generate(Lm_list *lml, Os_desc *osp, Word type)
1415aefb655Srie {
1425aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
1435aefb655Srie 		return;
1445aefb655Srie 
1455aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1465aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_REL_GENERATE), osp->os_name);
1475aefb655Srie 
1485aefb655Srie 	if (DBG_NOTDETAIL())
1495aefb655Srie 		return;
1505aefb655Srie 
1515aefb655Srie 	Elf_reloc_title(lml, ELF_DBG_LD, type);
1525aefb655Srie }
1535aefb655Srie 
154e23c41c9SAli Bahrami /*
155e23c41c9SAli Bahrami  * Issue relocation collecting header message prior to listing
156e23c41c9SAli Bahrami  * each relocation.
157e23c41c9SAli Bahrami  *
158e23c41c9SAli Bahrami  * entry:
159e23c41c9SAli Bahrami  *	lml - Link map control list
160e23c41c9SAli Bahrami  *	osp - If sh_info was non-NULL, output section to which
161e23c41c9SAli Bahrami  *		relocation applies. Otherwise NULL.
162e23c41c9SAli Bahrami  *	isp - If sh_info was non-NULL, input section to which
163e23c41c9SAli Bahrami  *		relocation applies. Otherwise NULL.
164e23c41c9SAli Bahrami  *	risp - Relocation section
165e23c41c9SAli Bahrami  *
166e23c41c9SAli Bahrami  * note: osp and isp must both be NULL, or both non-NULL. risp is never NULL.
167e23c41c9SAli Bahrami  */
1685aefb655Srie void
Dbg_reloc_proc(Lm_list * lml,Os_desc * osp,Is_desc * isp,Is_desc * risp)1695aefb655Srie Dbg_reloc_proc(Lm_list *lml, Os_desc *osp, Is_desc *isp, Is_desc *risp)
1707c478bd9Sstevel@tonic-gate {
1717c478bd9Sstevel@tonic-gate 	const char	*str1, *str2;
1727c478bd9Sstevel@tonic-gate 
1735aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
1747c478bd9Sstevel@tonic-gate 		return;
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	if (osp && osp->os_name)
1777c478bd9Sstevel@tonic-gate 		str1 = osp->os_name;
1787c478bd9Sstevel@tonic-gate 	else
1797c478bd9Sstevel@tonic-gate 		str1 =	MSG_INTL(MSG_STR_NULL);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 	if (isp && isp->is_file)
1827c478bd9Sstevel@tonic-gate 		str2 = isp->is_file->ifl_name;
1837c478bd9Sstevel@tonic-gate 	else if (risp && risp->is_file)
1847c478bd9Sstevel@tonic-gate 		str2 = risp->is_file->ifl_name;
1857c478bd9Sstevel@tonic-gate 	else
1867c478bd9Sstevel@tonic-gate 		str2 = MSG_INTL(MSG_STR_NULL);
1877c478bd9Sstevel@tonic-gate 
1885aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1895aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_REL_COLLECT), str1, str2);
1905aefb655Srie 
1917c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
1927c478bd9Sstevel@tonic-gate 		return;
1937c478bd9Sstevel@tonic-gate 
1945aefb655Srie 	Elf_reloc_title(lml, ELF_DBG_LD, risp->is_shdr->sh_type);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate void
Dbg_reloc_doact_title(Lm_list * lml)1985aefb655Srie Dbg_reloc_doact_title(Lm_list *lml)
1997c478bd9Sstevel@tonic-gate {
2005aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2017c478bd9Sstevel@tonic-gate 		return;
2027c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
2037c478bd9Sstevel@tonic-gate 		return;
2047c478bd9Sstevel@tonic-gate 
2055aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
2065aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_REL_ACTIVE));
207635216b6SRod Evans 	Elf_reloc_title(lml, ELF_DBG_LD_ACT, 0);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 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*bf994817SAli Bahrami Dbg_reloc_doact(Lm_list *lml, int caller, Half mach, Word type, Rel_desc *rdesc,
212*bf994817SAli Bahrami     Xword off, Xword value, rel_desc_sname_func_t rel_desc_sname_func)
2137c478bd9Sstevel@tonic-gate {
214de777a60Sab196087 	Conv_inv_buf_t	inv_buf;
2155aefb655Srie 	const char	*secname;
216*bf994817SAli Bahrami 	Os_desc		*osp;
2177c478bd9Sstevel@tonic-gate 
2185aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2197c478bd9Sstevel@tonic-gate 		return;
2207c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
2217c478bd9Sstevel@tonic-gate 		return;
2227c478bd9Sstevel@tonic-gate 
223*bf994817SAli Bahrami 	osp = RELAUX_GET_OSDESC(rdesc);
2247c478bd9Sstevel@tonic-gate 	if (osp) {
2255aefb655Srie 		secname = osp->os_name;
2267c478bd9Sstevel@tonic-gate 		off += osp->os_shdr->sh_offset;
2277c478bd9Sstevel@tonic-gate 	} else
2285aefb655Srie 		secname = MSG_ORIG(MSG_STR_EMPTY);
2297c478bd9Sstevel@tonic-gate 
2305aefb655Srie 	Elf_reloc_entry_2(lml, caller, MSG_ORIG(MSG_STR_EMPTY), type,
231*bf994817SAli Bahrami 	    conv_reloc_type(mach, rdesc->rel_rtype, 0, &inv_buf),
232*bf994817SAli Bahrami 	    off, value, secname, (*rel_desc_sname_func)(rdesc),
233*bf994817SAli Bahrami 	    MSG_ORIG(MSG_STR_EMPTY));
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate void
Dbg_reloc_dooutrel(Lm_list * lml,Word type)2375aefb655Srie Dbg_reloc_dooutrel(Lm_list *lml, Word type)
2387c478bd9Sstevel@tonic-gate {
2395aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2407c478bd9Sstevel@tonic-gate 		return;
2417c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
2427c478bd9Sstevel@tonic-gate 		return;
2437c478bd9Sstevel@tonic-gate 
2445aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
2455aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_REL_CREATING));
2465aefb655Srie 	Elf_reloc_title(lml, ELF_DBG_LD, type);
2475aefb655Srie }
2485aefb655Srie 
2495aefb655Srie void
Dbg_reloc_discard(Lm_list * lml,Half mach,Rel_desc * rsp)2505aefb655Srie Dbg_reloc_discard(Lm_list *lml, Half mach, Rel_desc *rsp)
2515aefb655Srie {
252e23c41c9SAli Bahrami 	dbg_isec_name_buf_t	buf;
253e23c41c9SAli Bahrami 	char			*alloc_mem;
254de777a60Sab196087 	Conv_inv_buf_t		inv_buf;
255051d39bbSrie 	Is_desc			*isp;
256051d39bbSrie 
2575aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2585aefb655Srie 		return;
2595aefb655Srie 	if (DBG_NOTDETAIL())
2605aefb655Srie 		return;
2615aefb655Srie 
262051d39bbSrie 	isp = rsp->rel_isdesc;
263e23c41c9SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_REL_DISCARDED),
264e23c41c9SAli Bahrami 	    dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name,
265de777a60Sab196087 	    conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf),
266c13de8f6Sab196087 	    EC_OFF(rsp->rel_roffset));
267e23c41c9SAli Bahrami 	if (alloc_mem != NULL)
268e23c41c9SAli Bahrami 		free(alloc_mem);
2695aefb655Srie }
2705aefb655Srie 
2715aefb655Srie void
Dbg_reloc_transition(Lm_list * lml,Half mach,Word rtype,Rel_desc * rsp,rel_desc_sname_func_t rel_desc_sname_func)272*bf994817SAli Bahrami Dbg_reloc_transition(Lm_list *lml, Half mach, Word rtype, Rel_desc *rsp,
273*bf994817SAli Bahrami     rel_desc_sname_func_t rel_desc_sname_func)
2745aefb655Srie {
275e23c41c9SAli Bahrami 	dbg_isec_name_buf_t	buf;
276e23c41c9SAli Bahrami 	char			*alloc_mem;
277de777a60Sab196087 	Conv_inv_buf_t		inv_buf1, inv_buf2;
278051d39bbSrie 	Is_desc			*isp;
279051d39bbSrie 
2805aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2815aefb655Srie 		return;
2825aefb655Srie 
283051d39bbSrie 	isp = rsp->rel_isdesc;
284051d39bbSrie 	dbg_print(lml, MSG_INTL(MSG_REL_TRANSITION),
285de777a60Sab196087 	    conv_reloc_type(mach, rsp->rel_rtype, 0, &inv_buf1),
286e23c41c9SAli Bahrami 	    dbg_fmt_isec_name(isp, buf, &alloc_mem), isp->is_file->ifl_name,
287*bf994817SAli Bahrami 	    EC_OFF(rsp->rel_roffset), (*rel_desc_sname_func)(rsp),
288de777a60Sab196087 	    conv_reloc_type(mach, rtype, 0, &inv_buf2));
289e23c41c9SAli Bahrami 	if (alloc_mem != NULL)
290e23c41c9SAli Bahrami 		free(alloc_mem);
2915aefb655Srie }
2925aefb655Srie 
2935aefb655Srie void
Dbg_reloc_out(Ofl_desc * ofl,int caller,Word type,void * reloc,const char * secname,const char * symname)2945aefb655Srie Dbg_reloc_out(Ofl_desc *ofl, int caller, Word type, void *reloc,
2955aefb655Srie     const char *secname, const char *symname)
2965aefb655Srie {
2975aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
2985aefb655Srie 		return;
2995aefb655Srie 	if (DBG_NOTDETAIL())
3005aefb655Srie 		return;
3015aefb655Srie 
3025aefb655Srie 	Elf_reloc_entry_1(ofl->ofl_lml, caller, MSG_ORIG(MSG_STR_EMPTY),
3035aefb655Srie 	    ofl->ofl_dehdr->e_machine, type, reloc, secname, symname,
3045aefb655Srie 	    MSG_ORIG(MSG_STR_EMPTY));
3055aefb655Srie }
3065aefb655Srie 
3075aefb655Srie void
Dbg_reloc_in(Lm_list * lml,int caller,Half mach,Word type,void * reloc,const char * secname,Word secndx,const char * symname)3085aefb655Srie Dbg_reloc_in(Lm_list *lml, int caller, Half mach, Word type, void *reloc,
309e23c41c9SAli Bahrami     const char *secname, Word secndx, const char *symname)
3105aefb655Srie {
311e23c41c9SAli Bahrami 	dbg_isec_name_buf_t	buf;
312e23c41c9SAli Bahrami 	char			*alloc_mem;
313e23c41c9SAli Bahrami 
3145aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
3155aefb655Srie 		return;
3165aefb655Srie 	if (DBG_NOTDETAIL())
3175aefb655Srie 		return;
3185aefb655Srie 
3195aefb655Srie 	Elf_reloc_entry_1(lml, caller, MSG_INTL(MSG_STR_IN), mach, type, reloc,
320e23c41c9SAli Bahrami 	    dbg_fmt_isec_name2(secname, secndx, buf, &alloc_mem), symname,
321e23c41c9SAli Bahrami 	    MSG_ORIG(MSG_STR_EMPTY));
322e23c41c9SAli Bahrami 
323e23c41c9SAli Bahrami 	if (alloc_mem != NULL)
324e23c41c9SAli Bahrami 		free(alloc_mem);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate /*
328d2ef9fe9Sab196087  * Used by ld when '-z relaxreloc' is in use and a relocation
329d2ef9fe9Sab196087  * is redirected to a kept section.
330d2ef9fe9Sab196087  *
331d2ef9fe9Sab196087  * entry:
332d2ef9fe9Sab196087  *	lml - Link map control list
333d2ef9fe9Sab196087  *	sdp - The replacement symbol to be used with the relocation,
334d2ef9fe9Sab196087  *		which references the kept section.
335d2ef9fe9Sab196087  */
336d2ef9fe9Sab196087 void
Dbg_reloc_sloppycomdat(Lm_list * lml,Sym_desc * sdp)337e23c41c9SAli Bahrami Dbg_reloc_sloppycomdat(Lm_list *lml, Sym_desc *sdp)
338d2ef9fe9Sab196087 {
339e23c41c9SAli Bahrami 	dbg_isec_name_buf_t	buf;
340e23c41c9SAli Bahrami 	char			*alloc_mem;
341d2ef9fe9Sab196087 	const char		*nfname;
342d2ef9fe9Sab196087 
343d2ef9fe9Sab196087 	if (DBG_NOTCLASS(DBG_C_RELOC) || DBG_NOTDETAIL())
344d2ef9fe9Sab196087 		return;
345d2ef9fe9Sab196087 
346d2ef9fe9Sab196087 	nfname = (sdp && sdp->sd_file && sdp->sd_file->ifl_name)
347d2ef9fe9Sab196087 	    ? sdp->sd_file->ifl_name : MSG_INTL(MSG_STR_NULL);
348d2ef9fe9Sab196087 
349e23c41c9SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_REL_SLOPPYCOMDAT),
350e23c41c9SAli Bahrami 	    dbg_fmt_isec_name(sdp->sd_isc, buf, &alloc_mem), nfname);
351e23c41c9SAli Bahrami 	if (alloc_mem != NULL)
352e23c41c9SAli Bahrami 		free(alloc_mem);
353d2ef9fe9Sab196087 }
354d2ef9fe9Sab196087 
355d2ef9fe9Sab196087 /*
3567c478bd9Sstevel@tonic-gate  * Print a output relocation structure (Rel_desc).
3577c478bd9Sstevel@tonic-gate  */
3587c478bd9Sstevel@tonic-gate void
Dbg_reloc_ors_entry(Lm_list * lml,int caller,Word type,Half mach,Rel_desc * orsp)3595aefb655Srie Dbg_reloc_ors_entry(Lm_list *lml, int caller, Word type, Half mach,
3605aefb655Srie     Rel_desc *orsp)
3617c478bd9Sstevel@tonic-gate {
362de777a60Sab196087 	Conv_inv_buf_t	inv_buf;
3635aefb655Srie 	const char	*secname, *symname;
3647c478bd9Sstevel@tonic-gate 
3655aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
3667c478bd9Sstevel@tonic-gate 		return;
3677c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
3687c478bd9Sstevel@tonic-gate 		return;
3697c478bd9Sstevel@tonic-gate 
370*bf994817SAli Bahrami 	if (orsp->rel_flags & (FLG_REL_GOT | FLG_REL_RFPTR1 | FLG_REL_RFPTR2)) {
3715aefb655Srie 		secname = MSG_ORIG(MSG_SCN_GOT);
372*bf994817SAli Bahrami 	} else if (orsp->rel_flags & FLG_REL_PLT) {
3735aefb655Srie 		secname = MSG_ORIG(MSG_SCN_PLT);
374*bf994817SAli Bahrami 	} else if (orsp->rel_flags & FLG_REL_BSS) {
3755aefb655Srie 		secname = MSG_ORIG(MSG_SCN_BSS);
376*bf994817SAli Bahrami 	} else {
377*bf994817SAli Bahrami 		Os_desc *osp = RELAUX_GET_OSDESC(orsp);
378*bf994817SAli Bahrami 
379*bf994817SAli Bahrami 		secname = osp ? osp->os_name : MSG_INTL(MSG_STR_NULL);
380*bf994817SAli Bahrami 	}
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	/*
3835aefb655Srie 	 * Register symbols can be relocated/initialized to a constant, which
3845aefb655Srie 	 * is a special case where the symbol index is 0.
3857c478bd9Sstevel@tonic-gate 	 */
3867c478bd9Sstevel@tonic-gate 	if (orsp->rel_sym != NULL)
3875aefb655Srie 		symname = orsp->rel_sym->sd_name;
3887c478bd9Sstevel@tonic-gate 	else
3895aefb655Srie 		symname = MSG_ORIG(MSG_STR_EMPTY);
3907c478bd9Sstevel@tonic-gate 
3915aefb655Srie 	Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_OUT), type,
392de777a60Sab196087 	    conv_reloc_type(mach, orsp->rel_rtype, 0, &inv_buf),
393de777a60Sab196087 	    orsp->rel_roffset, orsp->rel_raddend, secname, symname,
394de777a60Sab196087 	    MSG_ORIG(MSG_STR_EMPTY));
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate /*
3987c478bd9Sstevel@tonic-gate  * Print a Active relocation structure (Rel_desc).
3997c478bd9Sstevel@tonic-gate  */
4007c478bd9Sstevel@tonic-gate void
Dbg_reloc_ars_entry(Lm_list * lml,int caller,Word type,Half mach,Rel_desc * arsp)4015aefb655Srie Dbg_reloc_ars_entry(Lm_list *lml, int caller, Word type, Half mach,
4025aefb655Srie     Rel_desc *arsp)
4037c478bd9Sstevel@tonic-gate {
404de777a60Sab196087 	Conv_inv_buf_t	inv_buf;
4055aefb655Srie 	const char	*secname;
4067c478bd9Sstevel@tonic-gate 
4075aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
4087c478bd9Sstevel@tonic-gate 		return;
4097c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
4107c478bd9Sstevel@tonic-gate 		return;
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	if (arsp->rel_flags & (FLG_REL_GOT | FLG_REL_FPTR))
4135aefb655Srie 		secname = MSG_ORIG(MSG_SCN_GOT);
4147c478bd9Sstevel@tonic-gate 	else
415*bf994817SAli Bahrami 		secname = RELAUX_GET_OSDESC(arsp)->os_name;
4167c478bd9Sstevel@tonic-gate 
4175aefb655Srie 	Elf_reloc_entry_2(lml, caller, MSG_INTL(MSG_STR_ACT), type,
418de777a60Sab196087 	    conv_reloc_type(mach, arsp->rel_rtype, 0, &inv_buf),
419de777a60Sab196087 	    arsp->rel_roffset, arsp->rel_raddend, secname,
420de777a60Sab196087 	    arsp->rel_sym->sd_name, MSG_ORIG(MSG_STR_EMPTY));
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 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)4245aefb655Srie Dbg_reloc_entry(Lm_list *lml, const char *prestr, Half mach, Word type,
4255aefb655Srie     void *reloc, const char *secname, const char *symname, const char *poststr)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate 	/*
4285aefb655Srie 	 * Register relocations can use a constant initializer, in which case
4295aefb655Srie 	 * the associated symbol is 0.
4307c478bd9Sstevel@tonic-gate 	 */
4315aefb655Srie 	if (symname == NULL)
4325aefb655Srie 		symname = MSG_ORIG(MSG_STR_EMPTY);
4337c478bd9Sstevel@tonic-gate 
4345aefb655Srie 	Elf_reloc_entry_1(lml, ELF_DBG_LD, prestr, mach, type, reloc, secname,
4355aefb655Srie 	    symname, poststr);
4367c478bd9Sstevel@tonic-gate }
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate #if	defined(_ELF64)
4395aefb655Srie 
4407c478bd9Sstevel@tonic-gate void
Dbg64_pltpad_to(Lm_list * lml,const char * file,Addr pltpad,const char * dfile,const char * symname)4415aefb655Srie Dbg64_pltpad_to(Lm_list *lml, const char *file, Addr pltpad,
4425aefb655Srie     const char *dfile, const char *symname)
4437c478bd9Sstevel@tonic-gate {
4445aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
4457c478bd9Sstevel@tonic-gate 		return;
4467c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
4477c478bd9Sstevel@tonic-gate 		return;
4485aefb655Srie 
4495aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), file,
4507c478bd9Sstevel@tonic-gate 	    dfile, symname);
4517c478bd9Sstevel@tonic-gate }
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate void
Dbg64_pltpad_from(Lm_list * lml,const char * file,const char * sname,Addr pltpad)4545aefb655Srie Dbg64_pltpad_from(Lm_list *lml, const char *file, const char *sname,
4555aefb655Srie     Addr pltpad)
4567c478bd9Sstevel@tonic-gate {
4575aefb655Srie 	if (DBG_NOTCLASS(DBG_C_RELOC))
4587c478bd9Sstevel@tonic-gate 		return;
4597c478bd9Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
4607c478bd9Sstevel@tonic-gate 		return;
4615aefb655Srie 
4625aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), file,
4635aefb655Srie 	    Dbg_demangle_name(sname));
4647c478bd9Sstevel@tonic-gate }
4655aefb655Srie 
4667c478bd9Sstevel@tonic-gate #endif
4675aefb655Srie 
4685aefb655Srie /*
4695aefb655Srie  * Relocation output can differ depending on the caller and the type of
4705aefb655Srie  * relocation record.  However, the final diagnostic is maintained here so
4715aefb655Srie  * that the various message strings remain consistent.
4725aefb655Srie  *
4735aefb655Srie  * elfdump:
4745aefb655Srie  *               type       offset     addend    section   symbol
4755aefb655Srie  *               X          X          X         X         X              (Rela)
4765aefb655Srie  *
4775aefb655Srie  *               type       offset               section   symbol
4785aefb655Srie  *               X          X                    X         X              (Rel)
4795aefb655Srie  *
4805aefb655Srie  * Note, it could be argued that the section name output with elfdump(1) is
4815aefb655Srie  * unnecessary, as the table itself is identified with a title that reveals
4825aefb655Srie  * the section name.  However, the output does provide for grep(1)'ing for
4835aefb655Srie  * individual entries and obtaining the section name with this type of input.
4845aefb655Srie  *
4855aefb655Srie  * ld.so.1:
4865aefb655Srie  *   (prestr)    type       offset     addend    symbol
4875aefb655Srie  *                                     value
4885aefb655Srie  *       in      X          X          X         X                        (Rela)
4895aefb655Srie  *    apply                 X          X
4905aefb655Srie  *
4915aefb655Srie  *   (prestr)    type       offset     value     symbol
4925aefb655Srie  *       in      X          X                    X                        (Rel)
4935aefb655Srie  *    apply                 X          X
4945aefb655Srie  *
4955aefb655Srie  * ld:
4965aefb655Srie  *   (prestr)    type       offset     addend    section   symbol
4975aefb655Srie  *       in      X          X          X         X         X              (Rela)
4985aefb655Srie  *      act      X          X                    X         X
4995aefb655Srie  *      out      X          X                    X         X
5005aefb655Srie  *
5015aefb655Srie  *   (prestr)    type       offset               section   symbol
5025aefb655Srie  *       in      X          X                    X         X              (Rel)
5035aefb655Srie  *      act      X          X                    X         X
5045aefb655Srie  *      out      X          X                    X         X
5055aefb655Srie  *
5065aefb655Srie  * Both Rela and Rel active relocations are printed as:
5075aefb655Srie  *
5085aefb655Srie  *               type       offset     value     section   symbol
5095aefb655Srie  *               X          X          X         X         X
5105aefb655Srie  */
5115aefb655Srie void
Elf_reloc_title(Lm_list * lml,int caller,Word type)5125aefb655Srie Elf_reloc_title(Lm_list *lml, int caller, Word type)
5135aefb655Srie {
5145aefb655Srie 	if (caller == ELF_DBG_ELFDUMP) {
5155aefb655Srie 		if (type == SHT_RELA) {
5165aefb655Srie 			if (DBG_NOTLONG())
5175aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFSA_TITLE));
5185aefb655Srie 			else
5195aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFLA_TITLE));
5205aefb655Srie 		} else {
5215aefb655Srie 			if (DBG_NOTLONG())
5225aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFSN_TITLE));
5235aefb655Srie 			else
5245aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFLN_TITLE));
5255aefb655Srie 		}
5265aefb655Srie 		return;
5275aefb655Srie 	}
5285aefb655Srie 	if (caller == ELF_DBG_RTLD) {
5295aefb655Srie 		if (type == SHT_RELA) {
5305aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_RTA_TITLE));
5315aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_RTV_TITLE));
5325aefb655Srie 		} else
5335aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_RTN_TITLE));
5345aefb655Srie 		return;
5355aefb655Srie 	}
5365aefb655Srie 	if (caller == ELF_DBG_LD) {
5375aefb655Srie 		if (type == SHT_RELA) {
5385aefb655Srie 			if (DBG_NOTLONG())
5395aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDSA_TITLE));
5405aefb655Srie 			else
5415aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDLA_TITLE));
5425aefb655Srie 		} else {
5435aefb655Srie 			if (DBG_NOTLONG())
5445aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDSN_TITLE));
5455aefb655Srie 			else
5465aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDLN_TITLE));
5475aefb655Srie 		}
548635216b6SRod Evans 		return;
549635216b6SRod Evans 	}
550635216b6SRod Evans 	if (caller == ELF_DBG_LD_ACT) {
551635216b6SRod Evans 		if (DBG_NOTLONG())
552635216b6SRod Evans 			dbg_print(lml, MSG_INTL(MSG_REL_LDSV_TITLE));
553635216b6SRod Evans 		else
554635216b6SRod Evans 			dbg_print(lml, MSG_INTL(MSG_REL_LDLV_TITLE));
555635216b6SRod Evans 		return;
5565aefb655Srie 	}
5575aefb655Srie }
5585aefb655Srie 
5595aefb655Srie 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)5605aefb655Srie Elf_reloc_entry_2(Lm_list *lml, int caller, const char *prestr, Word type,
5615aefb655Srie     const char *typestr, Addr off, Sxword add, const char *secname,
5625aefb655Srie     const char *symname, const char *poststr)
5635aefb655Srie {
5645aefb655Srie 	if (symname)
5655aefb655Srie 		symname = Elf_demangle_name(symname);
5665aefb655Srie 	else
5675aefb655Srie 		symname = MSG_ORIG(MSG_STR_EMPTY);
5685aefb655Srie 
5695aefb655Srie 	if (caller == ELF_DBG_ELFDUMP) {
5705aefb655Srie 		if (type == SHT_RELA) {
5715aefb655Srie 			if (DBG_NOTLONG())
5725aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFSA_ENTRY),
5735aefb655Srie 				    typestr, EC_OFF(off), EC_SXWORD(add),
5745aefb655Srie 				    secname, symname);
5755aefb655Srie 			else
5765aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFLA_ENTRY),
5775aefb655Srie 				    typestr, EC_OFF(off), EC_SXWORD(add),
5785aefb655Srie 				    secname, symname);
5795aefb655Srie 		} else {
5805aefb655Srie 			if (DBG_NOTLONG())
5815aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFSN_ENTRY),
5825aefb655Srie 				    typestr, EC_OFF(off), secname, symname);
5835aefb655Srie 			else
5845aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_EFLN_ENTRY),
5855aefb655Srie 				    typestr, EC_OFF(off), secname, symname);
5865aefb655Srie 		}
5875aefb655Srie 		return;
5885aefb655Srie 	}
5895aefb655Srie 	if (caller == ELF_DBG_RTLD) {
5905aefb655Srie 		if (type == SHT_RELA)
5915aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_RTA_ENTRY), prestr,
592c1c6f601Srie 			    typestr, EC_OFF(off), EC_SXWORD(add), symname,
593c1c6f601Srie 			    poststr);
5945aefb655Srie 		else
5955aefb655Srie 			dbg_print(lml, MSG_INTL(MSG_REL_RTN_ENTRY), prestr,
596c1c6f601Srie 			    typestr, EC_OFF(off), symname, poststr);
5975aefb655Srie 		return;
5985aefb655Srie 	}
5995aefb655Srie 	if (caller == ELF_DBG_LD) {
6005aefb655Srie 		if (type == SHT_RELA) {
6015aefb655Srie 			if (DBG_NOTLONG())
6025aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY),
6035aefb655Srie 				    prestr, typestr, EC_OFF(off),
6045aefb655Srie 				    EC_SXWORD(add), secname, symname, poststr);
6055aefb655Srie 			else
6065aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY),
6075aefb655Srie 				    prestr, typestr, EC_OFF(off),
6085aefb655Srie 				    EC_SXWORD(add), secname, symname, poststr);
6095aefb655Srie 		} else {
6105aefb655Srie 			if (DBG_NOTLONG())
6115aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDSN_ENTRY),
6125aefb655Srie 				    prestr, typestr, EC_OFF(off), secname,
6135aefb655Srie 				    symname, poststr);
6145aefb655Srie 			else
6155aefb655Srie 				dbg_print(lml, MSG_INTL(MSG_REL_LDLN_ENTRY),
6165aefb655Srie 				    prestr, typestr, EC_OFF(off), secname,
6175aefb655Srie 				    symname, poststr);
6185aefb655Srie 		}
619635216b6SRod Evans 		return;
620635216b6SRod Evans 	}
621635216b6SRod Evans 	if (caller == ELF_DBG_LD_ACT) {
622635216b6SRod Evans 		longlong_t	value = EC_SXWORD(add);
623635216b6SRod Evans 
624635216b6SRod Evans 		/*
625635216b6SRod Evans 		 * The following diagnostics are used to create active
626635216b6SRod Evans 		 * relocation output.  A "value" field is specified in the
627635216b6SRod Evans 		 * same column as a RELA addend.
628635216b6SRod Evans 		 *
629635216b6SRod Evans 		 * We have to work around an issue caused by the use of a
630635216b6SRod Evans 		 * common format string to handle both the 32-bit and 64-bit
631635216b6SRod Evans 		 * cases.  'add' is a signed value.  In the ELFCLASS32 case
632635216b6SRod Evans 		 * where add is a 32-bit value, the EC_SXWORD() macro widens
633635216b6SRod Evans 		 * it to a 64-bit signed value, which will cause sign extension
634635216b6SRod Evans 		 * in the upper 32-bits.  As we are displaying the value in hex,
635635216b6SRod Evans 		 * this causes our 32-bit value to be displayed with 16 hex
636635216b6SRod Evans 		 * digits instead of 8, as would be appropriate for ELFCLASS32.
637635216b6SRod Evans 		 *
638635216b6SRod Evans 		 * The solution is to mask off the unwanted bits before
639635216b6SRod Evans 		 * formatting the value.  The use of 'longlong_t' instead of
640635216b6SRod Evans 		 * Elf64_Sxword (used by the EC_SXWORD macro) is for the
641635216b6SRod Evans 		 * benefit of lint.
642635216b6SRod Evans 		 */
643635216b6SRod Evans #if	!defined(_ELF64)
644635216b6SRod Evans 		value &= 0xffffffff;
645635216b6SRod Evans #endif
646635216b6SRod Evans 		if (DBG_NOTLONG())
647635216b6SRod Evans 			dbg_print(lml, MSG_INTL(MSG_REL_LDSA_ENTRY),
648635216b6SRod Evans 			    prestr, typestr, EC_OFF(off),
649635216b6SRod Evans 			    value, secname, symname, poststr);
650635216b6SRod Evans 		else
651635216b6SRod Evans 			dbg_print(lml, MSG_INTL(MSG_REL_LDLA_ENTRY),
652635216b6SRod Evans 			    prestr, typestr, EC_OFF(off),
653635216b6SRod Evans 			    value, secname, symname, poststr);
6545aefb655Srie 	}
6555aefb655Srie }
6565aefb655Srie 
6575aefb655Srie 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)6585aefb655Srie Elf_reloc_entry_1(Lm_list *lml, int caller, const char *prestr, Half mach,
6595aefb655Srie     Word type, void *reloc, const char *secname, const char *symname,
6605aefb655Srie     const char *poststr)
6615aefb655Srie {
662de777a60Sab196087 	Conv_inv_buf_t	inv_buf;
6635aefb655Srie 	Addr		off;
6645aefb655Srie 	Sxword		add;
6655aefb655Srie 	const char	*str;
6665aefb655Srie 
6675aefb655Srie 	if (type == SHT_RELA) {
6685aefb655Srie 		Rela	*rela = (Rela *)reloc;
6695aefb655Srie 
670ba2be530Sab196087 		str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info, mach),
671de777a60Sab196087 		    0, &inv_buf);
6725aefb655Srie 		off = rela->r_offset;
6735aefb655Srie 		add = rela->r_addend;
6745aefb655Srie 	} else {
6755aefb655Srie 		Rel	*rel = (Rel *)reloc;
6765aefb655Srie 
677ba2be530Sab196087 		str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info, mach),
678de777a60Sab196087 		    0, &inv_buf);
6795aefb655Srie 		off = rel->r_offset;
6805aefb655Srie 		add = 0;
6815aefb655Srie 	}
6825aefb655Srie 	Elf_reloc_entry_2(lml, caller, prestr, type, str, off, add, secname,
6835aefb655Srie 	    symname, poststr);
6845aefb655Srie }
6855aefb655Srie 
6865aefb655Srie /*
6875aefb655Srie  * Display any applied relocations.  Presently, these are only called from
6885aefb655Srie  * ld.so.1, but the interfaces are maintained here to insure consistency with
6895aefb655Srie  * other relocation diagnostics.
6905aefb655Srie  */
6915aefb655Srie void
Elf_reloc_apply_val(Lm_list * lml,int caller,Xword offset,Xword value)6925aefb655Srie Elf_reloc_apply_val(Lm_list *lml, int caller, Xword offset, Xword value)
6935aefb655Srie {
6945aefb655Srie 	if (caller == ELF_DBG_RTLD)
6955aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_REL_RT_APLVAL), EC_XWORD(offset),
6965aefb655Srie 		    EC_XWORD(value));
6975aefb655Srie }
6985aefb655Srie void
Elf_reloc_apply_reg(Lm_list * lml,int caller,Half mach,Xword offset,Xword value)6995aefb655Srie Elf_reloc_apply_reg(Lm_list *lml, int caller, Half mach, Xword offset,
7005aefb655Srie     Xword value)
7015aefb655Srie {
702de777a60Sab196087 	Conv_inv_buf_t inv_buf;
703de777a60Sab196087 
7045aefb655Srie 	if (caller == ELF_DBG_RTLD)
7055aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_REL_RT_APLREG),
706de777a60Sab196087 		    conv_sym_value(mach, STT_SPARC_REGISTER,
707de777a60Sab196087 		    offset, &inv_buf), EC_XWORD(value));
7085aefb655Srie }
709