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.
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.
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]
23 * Copyright (c) 2011, Joyent, Inc. All rights reserved.
24 * Copyright (c) 2011, Robert Mustacchi, Inc. All rights reserved.
25 * Copyright 2013, Richard Lowe.
39 extern const char *__progname
;
41 typedef struct symtab_sym
{
44 ctf_funcinfo_t ss_finfo
;
50 walk_symtab(Elf
*elf
, char *fname
, ctf_file_t
*fp
,
51 void (*callback
)(ctf_file_t
*, symtab_sym_t
*))
55 Elf_Data
*stabdata
= NULL
;
56 Elf_Data
*textdata
= NULL
;
60 int foundtext
= 0, foundstab
= 0;
63 if ((gelf_getehdr(elf
, &ehdr
)) == NULL
)
64 errx(1, "could not read ELF header from %s\n",
67 while ((stab
= elf_nextscn(elf
, stab
)) != NULL
) {
68 (void) gelf_getshdr(stab
, &stabshdr
);
70 if (stabshdr
.sh_type
== SHT_SYMTAB
) {
76 while ((text
= elf_nextscn(elf
, text
)) != NULL
) {
77 (void) gelf_getshdr(text
, &textshdr
);
79 if (strcmp(".text", elf_strptr(elf
,
80 ehdr
.e_shstrndx
, (size_t)textshdr
.sh_name
)) == 0) {
86 if (!foundstab
|| !foundtext
)
89 stabdata
= elf_getdata(stab
, NULL
);
90 textdata
= elf_rawdata(text
, NULL
);
91 for (unsigned symdx
= 0;
92 symdx
< (stabshdr
.sh_size
/ stabshdr
.sh_entsize
);
94 (void) gelf_getsym(stabdata
, symdx
, &ss
.ss_sym
);
96 if ((GELF_ST_TYPE(ss
.ss_sym
.st_info
) != STT_FUNC
) ||
97 (ss
.ss_sym
.st_shndx
== SHN_UNDEF
))
100 ss
.ss_name
= elf_strptr(elf
, stabshdr
.sh_link
,
102 ss
.ss_data
= ((uint8_t *)(textdata
->d_buf
)) +
103 (ss
.ss_sym
.st_value
- textshdr
.sh_addr
);
105 if (ctf_func_info(fp
, symdx
, &ss
.ss_finfo
) == CTF_ERR
) {
106 fprintf(stderr
, "failed to get funcinfo for: %s\n",
111 (void) callback(fp
, &ss
);
116 check_sym(ctf_file_t
*ctfp
, symtab_sym_t
*ss
)
118 int rettype
= ctf_type_kind(ctfp
, ss
->ss_finfo
.ctc_return
);
121 if (ss
->ss_finfo
.ctc_argc
== 0) /* No arguments, no point */
124 if (((rettype
== CTF_K_STRUCT
) || (rettype
== CTF_K_UNION
)) &&
125 ctf_type_size(ctfp
, ss
->ss_finfo
.ctc_return
) > 16)
128 if (saveargs_has_args(ss
->ss_data
, ss
->ss_sym
.st_size
,
129 ss
->ss_finfo
.ctc_argc
, start_index
) != SAVEARGS_NO_ARGS
)
130 printf("%s has %d saved args\n", ss
->ss_name
,
131 ss
->ss_finfo
.ctc_argc
);
135 main(int argc
, char **argv
)
141 if (ctf_version(CTF_VERSION
) == -1)
142 errx(1, "mismatched libctf versions\n");
144 if (elf_version(EV_CURRENT
) == EV_NONE
)
145 errx(1, "mismatched libelf versions\n");
148 errx(2, "usage: %s <file>\n", __progname
);
150 if ((ctfp
= ctf_open(argv
[1], &errp
)) == NULL
)
151 errx(1, "failed to ctf_open file: %s: %s\n", argv
[1],
154 if ((fd
= open(argv
[1], O_RDONLY
)) == -1)
155 errx(1, "could not open %s\n", argv
[1]);
157 if ((elf
= elf_begin(fd
, ELF_C_READ
, NULL
)) == NULL
)
158 errx(1, "could not interpret ELF from %s\n",
161 walk_symtab(elf
, argv
[1], ctfp
, check_sym
);