1 /* vi: set sw=4 ts=4: */
2 /* common debug code for ELF shared library loader
3  *
4  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
5  *                         David Engel, Hongjiu Lu and Mitch D'Souza
6  * Copyright (C) 2001-2004 Erik Andersen
7  * Copyright (C) 2002-2004, Axis Communications AB
8  * Copyright (C) 2003, 2004 Red Hat, Inc.
9  * Copyright (C) 2002, Steven J. Hill (sjhill@realitydiluted.com)
10  * Copyright (C) 2001-2002 David A. Schleef
11  * Copyright (C) 2004 Joakim Tjernlund
12  * Copyright (C) 2002, Stefan Allius <allius@atecom.com> and
13  *                     Eddie C. Dost <ecd@atecom.com>
14  * Copyright (C) 2003, 2004, 2005  Paul Mundt <lethal@linux-sh.org>
15  *
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer.
23  * 2. The name of the above contributors may not be
24  *    used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  */
39 
40 #include "ldso.h"
41 
42 #if defined (__SUPPORT_LD_DEBUG__)
43 
44 /* include the arch-specific _dl_reltypes_tab */
45 #include "dl-debug.h"
46 
_dl_reltypes(int type)47 static const char *_dl_reltypes(int type)
48 {
49 	static char buf[50];
50 	const char *str;
51 	int tabsize;
52 
53 	tabsize = (int)(sizeof(_dl_reltypes_tab) / sizeof(_dl_reltypes_tab[0]));
54 
55 	if (type >= tabsize || (str = _dl_reltypes_tab[type]) == NULL)
56 		str = _dl_simple_ltoa(buf, (unsigned long)type);
57 
58 	return str;
59 }
debug_sym(ElfW (Sym)const * symtab,char const * strtab,int symtab_index)60 static void debug_sym(ElfW(Sym) const *symtab, char const *strtab, int symtab_index)
61 {
62 	if (!_dl_debug_symbols || !symtab_index)
63 		return;
64 
65 	_dl_dprintf(_dl_debug_file,
66 		"\n%s\n\tvalue=%zx\tsize=%zx\tinfo=%x\tother=%x\tshndx=%x",
67 		strtab + symtab[symtab_index].st_name,
68 		symtab[symtab_index].st_value,
69 		symtab[symtab_index].st_size,
70 		symtab[symtab_index].st_info,
71 		symtab[symtab_index].st_other,
72 		symtab[symtab_index].st_shndx);
73 }
74 
75 static void
debug_reloc(ElfW (Sym)const * symtab,char const * strtab,ELF_RELOC const * rpnt)76 debug_reloc(ElfW(Sym) const *symtab, char const *strtab, ELF_RELOC const *rpnt)
77 {
78 	if (!_dl_debug_reloc)
79 		return;
80 
81 	if (_dl_debug_symbols) {
82 		_dl_dprintf(_dl_debug_file, "\n\t");
83 	} else {
84 		int symtab_index;
85 		const char *sym;
86 
87 		symtab_index = ELF_R_SYM(rpnt->r_info);
88 		sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
89 
90 		_dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
91 	}
92 
93 	_dl_dprintf(_dl_debug_file, "%s\toffset=%zx",
94 		_dl_reltypes(ELF_R_TYPE(rpnt->r_info)),
95 		rpnt->r_offset);
96 #ifdef ELF_USES_RELOCA
97 	_dl_dprintf(_dl_debug_file, "\taddend=%zx", rpnt->r_addend);
98 #endif
99 	_dl_dprintf(_dl_debug_file, "\n");
100 }
101 
102 #else
103 
104 #define debug_sym(symtab, strtab, symtab_index)
105 #define debug_reloc(symtab, strtab, rpnt)
106 
107 #endif /* __SUPPORT_LD_DEBUG__ */
108 
109 #ifdef __LDSO_PRELINK_SUPPORT__
110 static void
111 internal_function
_dl_debug_lookup(const char * undef_name,struct elf_resolve * undef_map,const ElfW (Sym)* ref,struct symbol_ref * value,int type_class)112 _dl_debug_lookup (const char *undef_name, struct elf_resolve *undef_map,
113 					const ElfW(Sym) *ref, struct symbol_ref *value, int type_class)
114 {
115 #ifdef SHARED
116   unsigned long symbol_addr;
117 
118   if (_dl_trace_prelink)
119     {
120       int conflict = 0;
121       struct symbol_ref val = { ref, NULL };
122 
123       if ((_dl_trace_prelink_map == NULL
124 	   || _dl_trace_prelink_map == _dl_loaded_modules)
125 	  && undef_map != _dl_loaded_modules)
126 	{
127 		symbol_addr = (unsigned long)
128 					  _dl_find_hash(undef_name, &undef_map->symbol_scope,
129 									undef_map, type_class, &val);
130 
131 	  if (val.sym != value->sym || val.tpnt != value->tpnt)
132 	    conflict = 1;
133 	}
134 
135       if (value->sym
136 	  && (__builtin_expect (ELF_ST_TYPE(value->sym->st_info)
137 				== STT_TLS, 0)))
138 	type_class = 4;
139 
140       if (conflict
141 	  || _dl_trace_prelink_map == undef_map
142 	  || _dl_trace_prelink_map == NULL
143 	  || type_class == 4)
144 	{
145 	  _dl_dprintf (1, "%s %x %x -> %x %x ",
146 		      conflict ? "conflict" : "lookup",
147 		      (size_t) undef_map->mapaddr,
148 		      (size_t) (((ElfW(Addr)) ref) - undef_map->mapaddr),
149 		      (size_t) (value->tpnt ? value->tpnt->mapaddr : 0),
150 		      (size_t) (value->sym ? value->sym->st_value : 0));
151 	  if (conflict)
152 	    _dl_dprintf (1, "x %x %x ",
153 			(size_t) (val.tpnt ? val.tpnt->mapaddr : 0),
154 			(size_t) (val.sym ? val.sym->st_value : 0));
155 	  _dl_dprintf (1, "/%x %s\n", type_class, undef_name);
156 	}
157 }
158 #endif
159 }
160 
161 #else
162 #define _dl_debug_lookup(undef_name, undef_map, ref, value, type_class)
163 #endif
164