1*702941cdSRichard Lowe /* 2*702941cdSRichard Lowe * CDDL HEADER START 3*702941cdSRichard Lowe * 4*702941cdSRichard Lowe * The contents of this file are subject to the terms of the 5*702941cdSRichard Lowe * Common Development and Distribution License (the "License"). 6*702941cdSRichard Lowe * You may not use this file except in compliance with the License. 7*702941cdSRichard Lowe * 8*702941cdSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*702941cdSRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*702941cdSRichard Lowe * See the License for the specific language governing permissions 11*702941cdSRichard Lowe * and limitations under the License. 12*702941cdSRichard Lowe * 13*702941cdSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*702941cdSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*702941cdSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*702941cdSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*702941cdSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*702941cdSRichard Lowe * 19*702941cdSRichard Lowe * CDDL HEADER END 20*702941cdSRichard Lowe */ 21*702941cdSRichard Lowe 22*702941cdSRichard Lowe /* 23*702941cdSRichard Lowe * Copyright (c) 2011, Joyent, Inc. All rights reserved. 24*702941cdSRichard Lowe * Copyright (c) 2011, Robert Mustacchi, Inc. All rights reserved. 25*702941cdSRichard Lowe * Copyright 2013, Richard Lowe. 26*702941cdSRichard Lowe */ 27*702941cdSRichard Lowe 28*702941cdSRichard Lowe #include <err.h> 29*702941cdSRichard Lowe #include <fcntl.h> 30*702941cdSRichard Lowe #include <gelf.h> 31*702941cdSRichard Lowe #include <libctf.h> 32*702941cdSRichard Lowe #include <saveargs.h> 33*702941cdSRichard Lowe #include <stdarg.h> 34*702941cdSRichard Lowe #include <stdio.h> 35*702941cdSRichard Lowe #include <stdlib.h> 36*702941cdSRichard Lowe #include <strings.h> 37*702941cdSRichard Lowe #include <unistd.h> 38*702941cdSRichard Lowe 39*702941cdSRichard Lowe extern const char *__progname; 40*702941cdSRichard Lowe 41*702941cdSRichard Lowe typedef struct symtab_sym { 42*702941cdSRichard Lowe GElf_Sym ss_sym; 43*702941cdSRichard Lowe char *ss_name; 44*702941cdSRichard Lowe ctf_funcinfo_t ss_finfo; 45*702941cdSRichard Lowe uint8_t *ss_data; 46*702941cdSRichard Lowe size_t ss_size; 47*702941cdSRichard Lowe } symtab_sym_t; 48*702941cdSRichard Lowe 49*702941cdSRichard Lowe static void 50*702941cdSRichard Lowe walk_symtab(Elf *elf, char *fname, ctf_file_t *fp, 51*702941cdSRichard Lowe void (*callback)(ctf_file_t *, symtab_sym_t *)) 52*702941cdSRichard Lowe { 53*702941cdSRichard Lowe Elf_Scn *stab = NULL; 54*702941cdSRichard Lowe Elf_Scn *text = NULL; 55*702941cdSRichard Lowe Elf_Data *stabdata = NULL; 56*702941cdSRichard Lowe Elf_Data *textdata = NULL; 57*702941cdSRichard Lowe GElf_Ehdr ehdr; 58*702941cdSRichard Lowe GElf_Shdr stabshdr; 59*702941cdSRichard Lowe GElf_Shdr textshdr; 60*702941cdSRichard Lowe int foundtext = 0, foundstab = 0; 61*702941cdSRichard Lowe symtab_sym_t ss; 62*702941cdSRichard Lowe 63*702941cdSRichard Lowe if ((gelf_getehdr(elf, &ehdr)) == NULL) 64*702941cdSRichard Lowe errx(1, "could not read ELF header from %s\n", 65*702941cdSRichard Lowe fname); 66*702941cdSRichard Lowe 67*702941cdSRichard Lowe while ((stab = elf_nextscn(elf, stab)) != NULL) { 68*702941cdSRichard Lowe (void) gelf_getshdr(stab, &stabshdr); 69*702941cdSRichard Lowe 70*702941cdSRichard Lowe if (stabshdr.sh_type == SHT_SYMTAB) { 71*702941cdSRichard Lowe foundstab = 1; 72*702941cdSRichard Lowe break; 73*702941cdSRichard Lowe } 74*702941cdSRichard Lowe } 75*702941cdSRichard Lowe 76*702941cdSRichard Lowe while ((text = elf_nextscn(elf, text)) != NULL) { 77*702941cdSRichard Lowe (void) gelf_getshdr(text, &textshdr); 78*702941cdSRichard Lowe 79*702941cdSRichard Lowe if (strcmp(".text", elf_strptr(elf, 80*702941cdSRichard Lowe ehdr.e_shstrndx, (size_t)textshdr.sh_name)) == 0) { 81*702941cdSRichard Lowe foundtext = 1; 82*702941cdSRichard Lowe break; 83*702941cdSRichard Lowe } 84*702941cdSRichard Lowe } 85*702941cdSRichard Lowe 86*702941cdSRichard Lowe if (!foundstab || !foundtext) 87*702941cdSRichard Lowe return; 88*702941cdSRichard Lowe 89*702941cdSRichard Lowe stabdata = elf_getdata(stab, NULL); 90*702941cdSRichard Lowe textdata = elf_rawdata(text, NULL); 91*702941cdSRichard Lowe for (unsigned symdx = 0; 92*702941cdSRichard Lowe symdx < (stabshdr.sh_size / stabshdr.sh_entsize); 93*702941cdSRichard Lowe symdx++) { 94*702941cdSRichard Lowe (void) gelf_getsym(stabdata, symdx, &ss.ss_sym); 95*702941cdSRichard Lowe 96*702941cdSRichard Lowe if ((GELF_ST_TYPE(ss.ss_sym.st_info) != STT_FUNC) || 97*702941cdSRichard Lowe (ss.ss_sym.st_shndx == SHN_UNDEF)) 98*702941cdSRichard Lowe continue; 99*702941cdSRichard Lowe 100*702941cdSRichard Lowe ss.ss_name = elf_strptr(elf, stabshdr.sh_link, 101*702941cdSRichard Lowe ss.ss_sym.st_name); 102*702941cdSRichard Lowe ss.ss_data = ((uint8_t *)(textdata->d_buf)) + 103*702941cdSRichard Lowe (ss.ss_sym.st_value - textshdr.sh_addr); 104*702941cdSRichard Lowe 105*702941cdSRichard Lowe if (ctf_func_info(fp, symdx, &ss.ss_finfo) == CTF_ERR) { 106*702941cdSRichard Lowe fprintf(stderr, "failed to get funcinfo for: %s\n", 107*702941cdSRichard Lowe ss.ss_name); 108*702941cdSRichard Lowe continue; 109*702941cdSRichard Lowe } 110*702941cdSRichard Lowe 111*702941cdSRichard Lowe (void) callback(fp, &ss); 112*702941cdSRichard Lowe } 113*702941cdSRichard Lowe } 114*702941cdSRichard Lowe 115*702941cdSRichard Lowe void 116*702941cdSRichard Lowe check_sym(ctf_file_t *ctfp, symtab_sym_t *ss) 117*702941cdSRichard Lowe { 118*702941cdSRichard Lowe int rettype = ctf_type_kind(ctfp, ss->ss_finfo.ctc_return); 119*702941cdSRichard Lowe int start_index = 0; 120*702941cdSRichard Lowe 121*702941cdSRichard Lowe if (ss->ss_finfo.ctc_argc == 0) /* No arguments, no point */ 122*702941cdSRichard Lowe return; 123*702941cdSRichard Lowe 124*702941cdSRichard Lowe if (((rettype == CTF_K_STRUCT) || (rettype == CTF_K_UNION)) && 125*702941cdSRichard Lowe ctf_type_size(ctfp, ss->ss_finfo.ctc_return) > 16) 126*702941cdSRichard Lowe start_index = 1; 127*702941cdSRichard Lowe 128*702941cdSRichard Lowe if (saveargs_has_args(ss->ss_data, ss->ss_sym.st_size, 129*702941cdSRichard Lowe ss->ss_finfo.ctc_argc, start_index) != SAVEARGS_NO_ARGS) 130*702941cdSRichard Lowe printf("%s has %d saved args\n", ss->ss_name, 131*702941cdSRichard Lowe ss->ss_finfo.ctc_argc); 132*702941cdSRichard Lowe } 133*702941cdSRichard Lowe 134*702941cdSRichard Lowe int 135*702941cdSRichard Lowe main(int argc, char **argv) 136*702941cdSRichard Lowe { 137*702941cdSRichard Lowe Elf *elf; 138*702941cdSRichard Lowe ctf_file_t *ctfp; 139*702941cdSRichard Lowe int errp, fd; 140*702941cdSRichard Lowe 141*702941cdSRichard Lowe if (ctf_version(CTF_VERSION) == -1) 142*702941cdSRichard Lowe errx(1, "mismatched libctf versions\n"); 143*702941cdSRichard Lowe 144*702941cdSRichard Lowe if (elf_version(EV_CURRENT) == EV_NONE) 145*702941cdSRichard Lowe errx(1, "mismatched libelf versions\n"); 146*702941cdSRichard Lowe 147*702941cdSRichard Lowe if (argc != 2) 148*702941cdSRichard Lowe errx(2, "usage: %s <file>\n", __progname); 149*702941cdSRichard Lowe 150*702941cdSRichard Lowe if ((ctfp = ctf_open(argv[1], &errp)) == NULL) 151*702941cdSRichard Lowe errx(1, "failed to ctf_open file: %s: %s\n", argv[1], 152*702941cdSRichard Lowe ctf_errmsg(errp)); 153*702941cdSRichard Lowe 154*702941cdSRichard Lowe if ((fd = open(argv[1], O_RDONLY)) == -1) 155*702941cdSRichard Lowe errx(1, "could not open %s\n", argv[1]); 156*702941cdSRichard Lowe 157*702941cdSRichard Lowe if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) 158*702941cdSRichard Lowe errx(1, "could not interpret ELF from %s\n", 159*702941cdSRichard Lowe argv[1]); 160*702941cdSRichard Lowe 161*702941cdSRichard Lowe walk_symtab(elf, argv[1], ctfp, check_sym); 162*702941cdSRichard Lowe 163*702941cdSRichard Lowe (void) elf_end(elf); 164*702941cdSRichard Lowe (void) close(fd); 165*702941cdSRichard Lowe 166*702941cdSRichard Lowe return (0); 167*702941cdSRichard Lowe } 168