Print this page
10812 ctf tools shouldn't add blank labels
10813 ctf symbol mapping needs work
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>


   7  * with the License.
   8  *
   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.
  13  *
  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]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright (c) 2015, Joyent, Inc.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/stat.h>
  32 #include <sys/mman.h>
  33 #include <ctf_impl.h>
  34 #include <unistd.h>
  35 #include <fcntl.h>
  36 #include <errno.h>
  37 #include <dlfcn.h>
  38 #include <gelf.h>
  39 #include <zlib.h>
  40 #include <sys/debug.h>
  41 
  42 #ifdef _LP64
  43 static const char *_libctf_zlib = "/usr/lib/64/libz.so.1";
  44 #else
  45 static const char *_libctf_zlib = "/usr/lib/libz.so.1";
  46 #endif
  47 
  48 static struct {
  49         int (*z_uncompress)(uchar_t *, ulong_t *, const uchar_t *, ulong_t);
  50         int (*z_initcomp)(z_stream *, int, const char *, int);
  51         int (*z_compress)(z_stream *, int);
  52         int (*z_finicomp)(z_stream *);
  53         const char *(*z_error)(int);


 730                 errno = EINVAL;
 731                 return (-1);
 732         }
 733 
 734         if (version > 0) {
 735                 if (version > CTF_VERSION) {
 736                         errno = ENOTSUP;
 737                         return (-1);
 738                 }
 739                 ctf_dprintf("ctf_version: client using version %d\n", version);
 740                 _libctf_version = version;
 741         }
 742 
 743         return (_libctf_version);
 744 }
 745 
 746 /*
 747  * A utility function for folks debugging CTF conversion and merging.
 748  */
 749 void
 750 ctf_phase_dump(ctf_file_t *fp, const char *phase)
 751 {
 752         int fd;
 753         static char *base;
 754         char path[MAXPATHLEN];
 755 
 756         if (base == NULL && (base = getenv("LIBCTF_WRITE_PHASES")) == NULL)
 757                 return;
 758 
 759         (void) snprintf(path, sizeof (path), "%s/libctf.%s.%d.ctf", base,



 760             phase != NULL ? phase : "",
 761             ctf_phase);
 762         if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0777)) < 0)
 763                 return;
 764         (void) ctf_write(fp, fd);
 765         (void) close(fd);






















































































 766 }


   7  * with the License.
   8  *
   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.
  13  *
  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]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright (c) 2019, Joyent, Inc.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/stat.h>
  32 #include <sys/mman.h>
  33 #include <libctf_impl.h>
  34 #include <unistd.h>
  35 #include <fcntl.h>
  36 #include <errno.h>
  37 #include <dlfcn.h>
  38 #include <gelf.h>
  39 #include <zlib.h>
  40 #include <sys/debug.h>
  41 
  42 #ifdef _LP64
  43 static const char *_libctf_zlib = "/usr/lib/64/libz.so.1";
  44 #else
  45 static const char *_libctf_zlib = "/usr/lib/libz.so.1";
  46 #endif
  47 
  48 static struct {
  49         int (*z_uncompress)(uchar_t *, ulong_t *, const uchar_t *, ulong_t);
  50         int (*z_initcomp)(z_stream *, int, const char *, int);
  51         int (*z_compress)(z_stream *, int);
  52         int (*z_finicomp)(z_stream *);
  53         const char *(*z_error)(int);


 730                 errno = EINVAL;
 731                 return (-1);
 732         }
 733 
 734         if (version > 0) {
 735                 if (version > CTF_VERSION) {
 736                         errno = ENOTSUP;
 737                         return (-1);
 738                 }
 739                 ctf_dprintf("ctf_version: client using version %d\n", version);
 740                 _libctf_version = version;
 741         }
 742 
 743         return (_libctf_version);
 744 }
 745 
 746 /*
 747  * A utility function for folks debugging CTF conversion and merging.
 748  */
 749 void
 750 ctf_phase_dump(ctf_file_t *fp, const char *phase, const char *name)
 751 {
 752         int fd;
 753         static char *base;
 754         char path[MAXPATHLEN];
 755 
 756         if (base == NULL && (base = getenv("LIBCTF_WRITE_PHASES")) == NULL)
 757                 return;
 758 
 759         if (name == NULL)
 760                 name = "libctf";
 761 
 762         (void) snprintf(path, sizeof (path), "%s/%s.%s.%d.ctf", base, name,
 763             phase != NULL ? phase : "",
 764             ctf_phase);
 765         if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0777)) < 0)
 766                 return;
 767         (void) ctf_write(fp, fd);
 768         (void) close(fd);
 769 }
 770 
 771 void
 772 ctf_phase_bump(void)
 773 {
 774         ctf_phase++;
 775 }
 776 
 777 int
 778 ctf_symtab_iter(ctf_file_t *fp, ctf_symtab_f func, void *arg)
 779 {
 780         ulong_t i;
 781         uintptr_t symbase;
 782         uintptr_t strbase;
 783         const char *file = NULL;
 784         boolean_t primary = B_TRUE;
 785 
 786         if (fp->ctf_symtab.cts_data == NULL ||
 787             fp->ctf_strtab.cts_data == NULL) {
 788                 return (ECTF_NOSYMTAB);
 789         }
 790 
 791         symbase = (uintptr_t)fp->ctf_symtab.cts_data;
 792         strbase = (uintptr_t)fp->ctf_strtab.cts_data;
 793 
 794         for (i = 0; i < fp->ctf_nsyms; i++) {
 795                 const char *name;
 796                 int ret;
 797                 uint_t type;
 798                 Elf64_Sym sym;
 799 
 800                 /*
 801                  * The CTF library has historically tried to handle large file
 802                  * offsets itself so that way clients can be unaware of such
 803                  * isseus. Therefore, we translate everything to a 64-bit ELF
 804                  * symbol, this is done to make it so that the rest of the
 805                  * library doesn't have to know about these differences. For
 806                  * more information see, lib/libctf/common/ctf_lib.c.
 807                  */
 808                 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
 809                         const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
 810                         uint_t bind, itype;
 811 
 812                         sym.st_name = symp->st_name;
 813                         sym.st_value = symp->st_value;
 814                         sym.st_size = symp->st_size;
 815                         bind = ELF32_ST_BIND(symp->st_info);
 816                         itype = ELF32_ST_TYPE(symp->st_info);
 817                         sym.st_info = ELF64_ST_INFO(bind, itype);
 818                         sym.st_other = symp->st_other;
 819                         sym.st_shndx = symp->st_shndx;
 820                 } else {
 821                         const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
 822 
 823                         sym = *symp;
 824                 }
 825 
 826                 type = ELF64_ST_TYPE(sym.st_info);
 827                 name = (const char *)(strbase + sym.st_name);
 828 
 829                 /*
 830                  * Check first if we have an STT_FILE entry. This is used to
 831                  * distinguish between various local symbols when merging.
 832                  */
 833                 if (type == STT_FILE) {
 834                         if (file != NULL) {
 835                                 primary = B_FALSE;
 836                         }
 837                         file = name;
 838                         continue;
 839                 }
 840 
 841                 /*
 842                  * Check if this is a symbol that we care about.
 843                  */
 844                 if (!ctf_sym_valid(strbase, type, sym.st_shndx, sym.st_value,
 845                     sym.st_name)) {
 846                         continue;
 847                 }
 848 
 849                 if ((ret = func(&sym, i, file, name, primary, arg)) != 0) {
 850                         return (ret);
 851                 }
 852         }
 853 
 854         return (0);
 855 }