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 }
|