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
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.
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]
23 * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
24 * All rights reserved.
37 #include <sys/types.h>
43 #include <sys/machelf.h>
46 #include <sys/cpuvar.h>
48 typedef struct syment
{
54 static syment_t
*symbol_table
;
55 static int nsyms
, maxsyms
;
56 static char maxsymname
[64];
59 #define elf_getshdr elf64_getshdr
61 #define elf_getshdr elf32_getshdr
65 add_symbol(char *name
, uintptr_t addr
, size_t size
)
69 if (nsyms
>= maxsyms
) {
71 symbol_table
= reallocarray(symbol_table
, maxsyms
,
73 if (symbol_table
== NULL
) {
74 (void) fprintf(stderr
, "can't allocate symbol table\n");
78 sep
= &symbol_table
[nsyms
++];
86 remove_symbol(uintptr_t addr
)
89 syment_t
*sep
= symbol_table
;
91 for (i
= 0; i
< nsyms
; i
++, sep
++)
92 if (sep
->addr
== addr
)
97 fake_up_certain_popular_kernel_symbols(void)
103 if ((kc
= kstat_open()) == NULL
)
106 for (ksp
= kc
->kc_chain
; ksp
; ksp
= ksp
->ks_next
) {
107 if (strcmp(ksp
->ks_module
, "cpu_info") == 0) {
108 if ((name
= malloc(20)) == NULL
)
111 * For consistency, keep cpu[0] and toss cpu0
112 * or any other such symbols.
114 if (ksp
->ks_instance
== 0)
115 remove_symbol((uintptr_t)ksp
->ks_private
);
116 (void) sprintf(name
, "cpu[%d]", ksp
->ks_instance
);
117 add_symbol(name
, (uintptr_t)ksp
->ks_private
,
118 sizeof (struct cpu
));
121 (void) kstat_close(kc
);
125 symcmp(const void *p1
, const void *p2
)
127 uintptr_t a1
= ((syment_t
*)p1
)->addr
;
128 uintptr_t a2
= ((syment_t
*)p2
)->addr
;
142 Sym
*symtab
, *symp
, *lastsym
;
149 if ((fd
= open("/dev/ksyms", O_RDONLY
)) == -1)
152 (void) elf_version(EV_CURRENT
);
154 elf
= elf_begin(fd
, ELF_C_READ
, NULL
);
156 for (cnt
= 1; (scn
= elf_nextscn(elf
, scn
)) != NULL
; cnt
++) {
157 Shdr
*shdr
= elf_getshdr(scn
);
158 if (shdr
->sh_type
== SHT_SYMTAB
) {
159 symtab
= (Sym
*)elf_getdata(scn
, NULL
)->d_buf
;
160 nsyms
= shdr
->sh_size
/ shdr
->sh_entsize
;
161 strindex
= shdr
->sh_link
;
165 for (cnt
= 1; (scn
= elf_nextscn(elf
, scn
)) != NULL
; cnt
++) {
167 strtab
= (char *)elf_getdata(scn
, NULL
)->d_buf
;
170 lastsym
= symtab
+ nsyms
;
172 for (symp
= symtab
; symp
< lastsym
; symp
++)
173 if ((uint_t
)ELF32_ST_TYPE(symp
->st_info
) <= STT_FUNC
&&
175 add_symbol(symp
->st_name
+ strtab
,
176 (uintptr_t)symp
->st_value
, (size_t)symp
->st_size
);
178 fake_up_certain_popular_kernel_symbols();
179 (void) sprintf(maxsymname
, "0x%lx", ULONG_MAX
);
180 add_symbol(maxsymname
, ULONG_MAX
, 1);
182 qsort(symbol_table
, nsyms
, sizeof (syment_t
), symcmp
);
185 * Destroy all duplicate symbols, then sort it again.
187 for (i
= 0; i
< nsyms
- 1; i
++)
188 if (symbol_table
[i
].addr
== symbol_table
[i
+ 1].addr
)
189 symbol_table
[i
].addr
= 0;
191 qsort(symbol_table
, nsyms
, sizeof (syment_t
), symcmp
);
193 while (symbol_table
[1].addr
== 0) {
197 symbol_table
[0].name
= "(usermode)";
198 symbol_table
[0].addr
= 0;
199 symbol_table
[0].size
= 1;
205 addr_to_sym(uintptr_t addr
, uintptr_t *offset
, size_t *sizep
)
212 while (hi
- lo
> 1) {
214 if (addr
>= symbol_table
[mid
].addr
) {
220 sep
= &symbol_table
[lo
];
221 *offset
= addr
- sep
->addr
;
227 sym_to_addr(char *name
)
230 syment_t
*sep
= symbol_table
;
232 for (i
= 0; i
< nsyms
; i
++) {
233 if (strcmp(name
, sep
->name
) == 0)
244 syment_t
*sep
= symbol_table
;
246 for (i
= 0; i
< nsyms
; i
++) {
247 if (strcmp(name
, sep
->name
) == 0)