diff options
Diffstat (limited to 'usr/src/tools/ctf')
26 files changed, 462 insertions, 1073 deletions
diff --git a/usr/src/tools/ctf/Makefile b/usr/src/tools/ctf/Makefile index dee410e27c..e31268df97 100644 --- a/usr/src/tools/ctf/Makefile +++ b/usr/src/tools/ctf/Makefile @@ -26,7 +26,7 @@ include ../Makefile.tools -SUBDIRS = cvt dump stabs ctfstrip +SUBDIRS = cvt stabs ctfstrip libctf ctfdiff ctfmerge ctfdump .PARALLEL: $(SUBDIRS) @@ -38,6 +38,10 @@ lint := TARGET= lint .KEEP_STATE: +ctfmerge: libctf +ctfdiff: libctf +ctfdump: libctf + all clean clobber install lint: dwarf .WAIT $(SUBDIRS) dwarf $(SUBDIRS): FRC diff --git a/usr/src/tools/ctf/Makefile.ctf b/usr/src/tools/ctf/Makefile.ctf index 7c5b041746..0cf32bf1bc 100644 --- a/usr/src/tools/ctf/Makefile.ctf +++ b/usr/src/tools/ctf/Makefile.ctf @@ -41,6 +41,7 @@ HDRDIRS= \ -I$(SRC) \ -I/usr/include \ -I$(SRC)/uts/common \ + -I$(SRC)/common/ctf \ -I$(NATIVE_ADJUNCT)/include CPPFLAGS += $(HDRDIRS) diff --git a/usr/src/tools/ctf/common/ctf_headers.h b/usr/src/tools/ctf/common/ctf_headers.h index b00b8fd9a6..453c6450ed 100644 --- a/usr/src/tools/ctf/common/ctf_headers.h +++ b/usr/src/tools/ctf/common/ctf_headers.h @@ -27,8 +27,6 @@ #ifndef _CTF_HEADERS_H #define _CTF_HEADERS_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Because the ON tools are executed on the system where they are built, * the tools need to include the headers installed on the build system, @@ -67,6 +65,18 @@ #include <uts/common/sys/ctf.h> #include <uts/common/sys/ctf_api.h> +#include <common/ctf/ctf_impl.h> #include <lib/libctf/common/libctf.h> +/* + * XXX: This is hack to deal with GCC 4.x removing __builtin_stdarg_start + * + * We need to build on systems that don't have the fixed va_impl.h on the + * system, to achieve that, we stub it out here and in all similar places to + * give us a leg up. + */ +#if __GNUC__ >= 4 +#define __builtin_stdarg_start(list, name) __builtin_va_start(list, name) +#endif + #endif /* _CTF_HEADERS_H */ diff --git a/usr/src/tools/ctf/common/utils.h b/usr/src/tools/ctf/common/utils.h index 9b07361a53..4ae2dd0917 100644 --- a/usr/src/tools/ctf/common/utils.h +++ b/usr/src/tools/ctf/common/utils.h @@ -27,9 +27,8 @@ #ifndef _UTILS_H #define _UTILS_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdarg.h> +#include <ctf_headers.h> #ifdef __cplusplus extern "C" { diff --git a/usr/src/tools/ctf/dump/Makefile b/usr/src/tools/ctf/ctfdiff/Makefile index 16d8280cdd..07fadc5f8f 100644 --- a/usr/src/tools/ctf/dump/Makefile +++ b/usr/src/tools/ctf/ctfdiff/Makefile @@ -23,7 +23,6 @@ # Copyright (c) 2001 by Sun Microsystems, Inc. # All rights reserved. # -#ident "%Z%%M% %I% %E% SMI" include ../../Makefile.tools diff --git a/usr/src/tools/ctf/ctfdiff/Makefile.com b/usr/src/tools/ctf/ctfdiff/Makefile.com new file mode 100644 index 0000000000..3c5e19fb6e --- /dev/null +++ b/usr/src/tools/ctf/ctfdiff/Makefile.com @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +PROG = ctfdiff +SRCS = ctfdiff.c + +include ../../Makefile.ctf + +CFLAGS += $(CCVERBOSE) +LDLIBS += -lctf + +LDFLAGS = \ + -L$(ROOTONBLDLIBMACH) \ + '-R$$ORIGIN/../../lib/$(MACH)' \ + +CPPFLAGS += -include ../../common/ctf_headers.h + +OBJS = $(SRCS:%.c=%.o) + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +%.o: $(SRC)/cmd/ctfdiff/%.c + $(COMPILE.c) $< + +$(ROOTONBLDMACHPROG): $(PROG) + +install: $(ROOTONBLDMACHPROG) + +clean: + $(RM) $(OBJS) $(LINTFILES) + +include $(SRC)/tools/Makefile.targ diff --git a/usr/src/tools/ctf/ctfdiff/i386/Makefile b/usr/src/tools/ctf/ctfdiff/i386/Makefile new file mode 100644 index 0000000000..92c756cb42 --- /dev/null +++ b/usr/src/tools/ctf/ctfdiff/i386/Makefile @@ -0,0 +1,16 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com diff --git a/usr/src/tools/ctf/ctfdiff/sparc/Makefile b/usr/src/tools/ctf/ctfdiff/sparc/Makefile new file mode 100644 index 0000000000..92c756cb42 --- /dev/null +++ b/usr/src/tools/ctf/ctfdiff/sparc/Makefile @@ -0,0 +1,16 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com diff --git a/usr/src/tools/ctf/ctfdump/Makefile b/usr/src/tools/ctf/ctfdump/Makefile new file mode 100644 index 0000000000..20d304216a --- /dev/null +++ b/usr/src/tools/ctf/ctfdump/Makefile @@ -0,0 +1,33 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../../Makefile.tools + +SUBDIRS = $(MACH) + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +install all clean clobber lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/tools/ctf/ctfdump/Makefile.com b/usr/src/tools/ctf/ctfdump/Makefile.com new file mode 100644 index 0000000000..3e1414ea59 --- /dev/null +++ b/usr/src/tools/ctf/ctfdump/Makefile.com @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +PROG = ctfdump +SRCS = ctfdump.c + +include ../../Makefile.ctf + +CFLAGS += $(CCVERBOSE) +LDLIBS += -lctf + +LDFLAGS = \ + -L$(ROOTONBLDLIBMACH) \ + '-R$$ORIGIN/../../lib/$(MACH)' \ + +CPPFLAGS += -include ../../common/ctf_headers.h + +OBJS = $(SRCS:%.c=%.o) + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +%.o: $(SRC)/cmd/ctfdump/%.c + $(COMPILE.c) $< + +$(ROOTONBLDMACHPROG): $(PROG) + +install: $(ROOTONBLDMACHPROG) + +clean: + $(RM) $(OBJS) $(LINTFILES) + +include $(SRC)/tools/Makefile.targ diff --git a/usr/src/tools/ctf/ctfdump/i386/Makefile b/usr/src/tools/ctf/ctfdump/i386/Makefile new file mode 100644 index 0000000000..92c756cb42 --- /dev/null +++ b/usr/src/tools/ctf/ctfdump/i386/Makefile @@ -0,0 +1,16 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com diff --git a/usr/src/tools/ctf/ctfdump/sparc/Makefile b/usr/src/tools/ctf/ctfdump/sparc/Makefile new file mode 100644 index 0000000000..92c756cb42 --- /dev/null +++ b/usr/src/tools/ctf/ctfdump/sparc/Makefile @@ -0,0 +1,16 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com diff --git a/usr/src/tools/ctf/ctfmerge/Makefile b/usr/src/tools/ctf/ctfmerge/Makefile new file mode 100644 index 0000000000..07fadc5f8f --- /dev/null +++ b/usr/src/tools/ctf/ctfmerge/Makefile @@ -0,0 +1,44 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2001 by Sun Microsystems, Inc. +# All rights reserved. +# + +include ../../Makefile.tools + +SUBDIRS = $(MACH) + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +install all clean clobber lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/tools/ctf/ctfmerge/Makefile.com b/usr/src/tools/ctf/ctfmerge/Makefile.com new file mode 100644 index 0000000000..b227e8b7b0 --- /dev/null +++ b/usr/src/tools/ctf/ctfmerge/Makefile.com @@ -0,0 +1,46 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +PROG = ctfmerge-altexec +SRCS = ctfmerge.c + +include ../../Makefile.ctf + +CFLAGS += $(CCVERBOSE) +LDLIBS += -lctf -lelf + +LDFLAGS = \ + -L$(ROOTONBLDLIBMACH) \ + '-R$$ORIGIN/../../lib/$(MACH)' \ + +CPPFLAGS += -include ../../common/ctf_headers.h +CERRWARN += -_gcc=-Wno-unused-variable +CERRWARN += -_gcc=-Wno-uninitialized + +OBJS = $(SRCS:%.c=%.o) + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +%.o: $(SRC)/cmd/ctfmerge/%.c + $(COMPILE.c) $< + +$(ROOTONBLDMACHPROG): $(PROG) + +install: $(ROOTONBLDMACHPROG) + +clean: + $(RM) $(OBJS) $(LINTFILES) + +include $(SRC)/tools/Makefile.targ diff --git a/usr/src/tools/ctf/dump/sparc/Makefile b/usr/src/tools/ctf/ctfmerge/i386/Makefile index 94e5883ae2..cd5462bee3 100644 --- a/usr/src/tools/ctf/dump/sparc/Makefile +++ b/usr/src/tools/ctf/ctfmerge/i386/Makefile @@ -23,6 +23,5 @@ # Copyright (c) 2001 by Sun Microsystems, Inc. # All rights reserved. # -#ident "%Z%%M% %I% %E% SMI" include ../Makefile.com diff --git a/usr/src/tools/ctf/dump/i386/Makefile b/usr/src/tools/ctf/ctfmerge/sparc/Makefile index 94e5883ae2..cd5462bee3 100644 --- a/usr/src/tools/ctf/dump/i386/Makefile +++ b/usr/src/tools/ctf/ctfmerge/sparc/Makefile @@ -23,6 +23,5 @@ # Copyright (c) 2001 by Sun Microsystems, Inc. # All rights reserved. # -#ident "%Z%%M% %I% %E% SMI" include ../Makefile.com diff --git a/usr/src/tools/ctf/cvt/Makefile.com b/usr/src/tools/ctf/cvt/Makefile.com index 5385b3769f..d909031167 100644 --- a/usr/src/tools/ctf/cvt/Makefile.com +++ b/usr/src/tools/ctf/cvt/Makefile.com @@ -32,6 +32,7 @@ PROG=ctfconvert ctfmerge GENSRCS= \ alist.c \ + altexec.c \ barrier.c \ ctf.c \ fifo.c \ diff --git a/usr/src/tools/ctf/cvt/altexec.c b/usr/src/tools/ctf/cvt/altexec.c new file mode 100644 index 0000000000..c986c0731a --- /dev/null +++ b/usr/src/tools/ctf/cvt/altexec.c @@ -0,0 +1,45 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2015, Joyent, Inc. + */ + +/* + * Alternate execution engine for CTF tools + */ + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "ctftools.h" + +void +ctf_altexec(const char *env, int argc, char **argv) +{ + const char *alt; + char *altexec; + + alt = getenv(env); + if (alt == NULL || *alt == '\0') + return; + + altexec = strdup(alt); + if (altexec == NULL) + terminate("failed to allocate memory for altexec\n"); + + if (unsetenv(env) != 0) + aborterr("failed to remove %s from environment", env); + + (void) execv(altexec, argv); + terminate("failed to altexec %s", altexec); +} diff --git a/usr/src/tools/ctf/cvt/ctfconvert.c b/usr/src/tools/ctf/cvt/ctfconvert.c index 36496c5e9d..af005e1934 100644 --- a/usr/src/tools/ctf/cvt/ctfconvert.c +++ b/usr/src/tools/ctf/cvt/ctfconvert.c @@ -146,6 +146,7 @@ main(int argc, char **argv) { tdata_t *filetd, *mstrtd; char *label = NULL; + char *altexec; int verbose = 0; int ignore_non_c = 0; int c; @@ -156,12 +157,21 @@ main(int argc, char **argv) progname = basename(argv[0]); + ctf_altexec("CTFCONVERT_ALTEXEC", argc, argv); + if (getenv("CTFCONVERT_DEBUG_LEVEL")) debug_level = atoi(getenv("CTFCONVERT_DEBUG_LEVEL")); if (getenv("CTFCONVERT_DEBUG_PARSE")) debug_parse = atoi(getenv("CTFCONVERT_DEBUG_PARSE")); - while ((c = getopt(argc, argv, ":l:L:o:ivs")) != EOF) { + if ((altexec = getenv("CTFCONVERT_ALTEXEC")) != NULL) { + (void) unsetenv("CTFCONVERT_ALTEXEC"); + (void) execv(altexec, argv); + (void) fprintf(stderr, "ctfconvert altexec failed to " + "run %s: %s\n", altexec, strerror(errno)); + } + + while ((c = getopt(argc, argv, ":l:L:o:givs")) != EOF) { switch (c) { case 'l': label = optarg; diff --git a/usr/src/tools/ctf/cvt/ctfmerge.c b/usr/src/tools/ctf/cvt/ctfmerge.c index 5706cceb17..b8053a7a23 100644 --- a/usr/src/tools/ctf/cvt/ctfmerge.c +++ b/usr/src/tools/ctf/cvt/ctfmerge.c @@ -745,6 +745,8 @@ main(int argc, char **argv) progname = basename(argv[0]); + ctf_altexec("CTFMERGE_ALTEXEC", argc, argv); + if (getenv("CTFMERGE_DEBUG_LEVEL")) debug_level = atoi(getenv("CTFMERGE_DEBUG_LEVEL")); diff --git a/usr/src/tools/ctf/cvt/ctftools.h b/usr/src/tools/ctf/cvt/ctftools.h index 708dfd82ef..755af5176d 100644 --- a/usr/src/tools/ctf/cvt/ctftools.h +++ b/usr/src/tools/ctf/cvt/ctftools.h @@ -43,6 +43,17 @@ extern "C" { #endif +/* + * XXX: This is hack to deal with GCC 4.x removing __builtin_stdarg_start + * + * We need to build on systems that don't have the fixed va_impl.h on the + * system, to achieve that, we stub it out here and in all similar places to + * give us a leg up. + */ +#if __GNUC__ >= 4 +#define __builtin_stdarg_start(list, name) __builtin_va_start(list, name) +#endif + #include "list.h" #include "hash.h" @@ -441,6 +452,9 @@ void warning(char *, ...); void vadebug(int, char *, va_list); void debug(int, char *, ...); +/* altexec.c */ +void ctf_altexec(const char *, int argc, char **); + #ifdef __cplusplus } #endif diff --git a/usr/src/tools/ctf/dump/dump.c b/usr/src/tools/ctf/dump/dump.c deleted file mode 100644 index 5579bae596..0000000000 --- a/usr/src/tools/ctf/dump/dump.c +++ /dev/null @@ -1,1028 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/sysmacros.h> -#include <sys/stat.h> -#include <sys/mman.h> - -#include <strings.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <gelf.h> -#include <zlib.h> - -#include "ctf_headers.h" -#include "utils.h" -#include "symbol.h" - -#define WARN(x) { warn(x); return (E_ERROR); } - -/* - * Flags that indicate what data is to be displayed. An explicit `all' value is - * provided to allow the code to distinguish between a request for everything - * (currently requested by invoking ctfdump without flags) and individual - * requests for all of the types of data (an invocation with all flags). In the - * former case, we want to be able to implicitly adjust the definition of `all' - * based on the CTF version of the file being dumped. For example, if a v2 file - * is being dumped, `all' includes F_LABEL - a request to dump the label - * section. If a v1 file is being dumped, `all' does not include F_LABEL, - * because v1 CTF doesn't support labels. We need to be able to distinguish - * between `ctfdump foo', which has an implicit request for labels if `foo' - * supports them, and `ctfdump -l foo', which has an explicity request. In the - * latter case, we exit with an error if `foo' is a v1 CTF file. - */ -static enum { - F_DATA = 0x01, /* show data object section */ - F_FUNC = 0x02, /* show function section */ - F_HDR = 0x04, /* show header */ - F_STR = 0x08, /* show string table */ - F_TYPES = 0x10, /* show type section */ - F_STATS = 0x20, /* show statistics */ - F_LABEL = 0x40, /* show label section */ - F_ALL = 0x80, /* explicit request for `all' */ - F_ALLMSK = 0xff /* show all sections and statistics */ -} flags = 0; - -static struct { - ulong_t s_ndata; /* total number of data objects */ - ulong_t s_nfunc; /* total number of functions */ - ulong_t s_nargs; /* total number of function arguments */ - ulong_t s_argmax; /* longest argument list */ - ulong_t s_ntypes; /* total number of types */ - ulong_t s_types[16]; /* number of types by kind */ - ulong_t s_nsmem; /* total number of struct members */ - ulong_t s_nsbytes; /* total size of all structs */ - ulong_t s_smmax; /* largest struct in terms of members */ - ulong_t s_sbmax; /* largest struct in terms of bytes */ - ulong_t s_numem; /* total number of union members */ - ulong_t s_nubytes; /* total size of all unions */ - ulong_t s_ummax; /* largest union in terms of members */ - ulong_t s_ubmax; /* largest union in terms of bytes */ - ulong_t s_nemem; /* total number of enum members */ - ulong_t s_emmax; /* largest enum in terms of members */ - ulong_t s_nstr; /* total number of strings */ - size_t s_strlen; /* total length of all strings */ - size_t s_strmax; /* longest string length */ -} stats; - -typedef struct ctf_data { - caddr_t cd_ctfdata; /* Pointer to the CTF data */ - size_t cd_ctflen; /* Length of CTF data */ - - /* - * cd_symdata will be non-NULL if the CTF data is being retrieved from - * an ELF file with a symbol table. cd_strdata and cd_nsyms should be - * used only if cd_symdata is non-NULL. - */ - Elf_Data *cd_symdata; /* Symbol table */ - Elf_Data *cd_strdata; /* Symbol table strings */ - int cd_nsyms; /* Number of symbol table entries */ -} ctf_data_t; - -static const char * -ref_to_str(uint_t name, const ctf_header_t *hp, const ctf_data_t *cd) -{ - size_t offset = CTF_NAME_OFFSET(name); - const char *s = cd->cd_ctfdata + hp->cth_stroff + offset; - - if (CTF_NAME_STID(name) != CTF_STRTAB_0) - return ("<< ??? - name in external strtab >>"); - - if (offset >= hp->cth_strlen) - return ("<< ??? - name exceeds strlab len >>"); - - if (hp->cth_stroff + offset >= cd->cd_ctflen) - return ("<< ??? - file truncated >>"); - - if (s[0] == '\0') - return ("(anon)"); - - return (s); -} - -static const char * -int_encoding_to_str(uint_t encoding) -{ - static char buf[32]; - - if (encoding == 0 || (encoding & ~(CTF_INT_SIGNED | CTF_INT_CHAR | - CTF_INT_BOOL | CTF_INT_VARARGS)) != 0) - (void) snprintf(buf, sizeof (buf), " 0x%x", encoding); - else { - buf[0] = '\0'; - if (encoding & CTF_INT_SIGNED) - (void) strcat(buf, " SIGNED"); - if (encoding & CTF_INT_CHAR) - (void) strcat(buf, " CHAR"); - if (encoding & CTF_INT_BOOL) - (void) strcat(buf, " BOOL"); - if (encoding & CTF_INT_VARARGS) - (void) strcat(buf, " VARARGS"); - } - - return (buf + 1); -} - -static const char * -fp_encoding_to_str(uint_t encoding) -{ - static const char *const encs[] = { - NULL, "SINGLE", "DOUBLE", "COMPLEX", "DCOMPLEX", "LDCOMPLEX", - "LDOUBLE", "INTERVAL", "DINTERVAL", "LDINTERVAL", "IMAGINARY", - "DIMAGINARY", "LDIMAGINARY" - }; - - static char buf[16]; - - if (encoding < 1 || encoding >= (sizeof (encs) / sizeof (char *))) { - (void) snprintf(buf, sizeof (buf), "%u", encoding); - return (buf); - } - - return (encs[encoding]); -} - -static void -print_line(const char *s) -{ - static const char line[] = "----------------------------------------" - "----------------------------------------"; - (void) printf("\n%s%.*s\n\n", s, (int)(78 - strlen(s)), line); -} - -static int -print_header(const ctf_header_t *hp, const ctf_data_t *cd) -{ - print_line("- CTF Header "); - - (void) printf(" cth_magic = 0x%04x\n", hp->cth_magic); - (void) printf(" cth_version = %u\n", hp->cth_version); - (void) printf(" cth_flags = 0x%02x\n", hp->cth_flags); - (void) printf(" cth_parlabel = %s\n", - ref_to_str(hp->cth_parlabel, hp, cd)); - (void) printf(" cth_parname = %s\n", - ref_to_str(hp->cth_parname, hp, cd)); - (void) printf(" cth_lbloff = %u\n", hp->cth_lbloff); - (void) printf(" cth_objtoff = %u\n", hp->cth_objtoff); - (void) printf(" cth_funcoff = %u\n", hp->cth_funcoff); - (void) printf(" cth_typeoff = %u\n", hp->cth_typeoff); - (void) printf(" cth_stroff = %u\n", hp->cth_stroff); - (void) printf(" cth_strlen = %u\n", hp->cth_strlen); - - return (E_SUCCESS); -} - -static int -print_labeltable(const ctf_header_t *hp, const ctf_data_t *cd) -{ - /* LINTED - pointer alignment */ - const ctf_lblent_t *ctl = (ctf_lblent_t *)(cd->cd_ctfdata + - hp->cth_lbloff); - ulong_t i, n = (hp->cth_objtoff - hp->cth_lbloff) / sizeof (*ctl); - - print_line("- Label Table "); - - if (hp->cth_lbloff & 3) - WARN("cth_lbloff is not aligned properly\n"); - if (hp->cth_lbloff >= cd->cd_ctflen) - WARN("file is truncated or cth_lbloff is corrupt\n"); - if (hp->cth_objtoff >= cd->cd_ctflen) - WARN("file is truncated or cth_objtoff is corrupt\n"); - if (hp->cth_lbloff > hp->cth_objtoff) - WARN("file is corrupt -- cth_lbloff > cth_objtoff\n"); - - for (i = 0; i < n; i++, ctl++) { - (void) printf(" %5u %s\n", ctl->ctl_typeidx, - ref_to_str(ctl->ctl_label, hp, cd)); - } - - return (E_SUCCESS); -} - -/* - * Given the current symbol index (-1 to start at the beginning of the symbol - * table) and the type of symbol to match, this function returns the index of - * the next matching symbol (if any), and places the name of that symbol in - * *namep. If no symbol is found, -1 is returned. - */ -static int -next_sym(const ctf_data_t *cd, const int symidx, const uchar_t matchtype, - char **namep) -{ - int i; - - for (i = symidx + 1; i < cd->cd_nsyms; i++) { - GElf_Sym sym; - char *name; - int type; - - if (gelf_getsym(cd->cd_symdata, i, &sym) == 0) - return (-1); - - name = (char *)cd->cd_strdata->d_buf + sym.st_name; - type = GELF_ST_TYPE(sym.st_info); - - /* - * Skip various types of symbol table entries. - */ - if (type != matchtype || ignore_symbol(&sym, name)) - continue; - - /* Found one */ - *namep = name; - return (i); - } - - return (-1); -} - -static int -read_data(const ctf_header_t *hp, const ctf_data_t *cd) -{ - /* LINTED - pointer alignment */ - const ushort_t *idp = (ushort_t *)(cd->cd_ctfdata + hp->cth_objtoff); - ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / sizeof (ushort_t); - - if (flags != F_STATS) - print_line("- Data Objects "); - - if (hp->cth_objtoff & 1) - WARN("cth_objtoff is not aligned properly\n"); - if (hp->cth_objtoff >= cd->cd_ctflen) - WARN("file is truncated or cth_objtoff is corrupt\n"); - if (hp->cth_funcoff >= cd->cd_ctflen) - WARN("file is truncated or cth_funcoff is corrupt\n"); - if (hp->cth_objtoff > hp->cth_funcoff) - WARN("file is corrupt -- cth_objtoff > cth_funcoff\n"); - - if (flags != F_STATS) { - int symidx, len, i; - char *name = NULL; - - for (symidx = -1, i = 0; i < n; i++) { - int nextsym; - - if (cd->cd_symdata == NULL || (nextsym = next_sym(cd, - symidx, STT_OBJECT, &name)) < 0) - name = NULL; - else - symidx = nextsym; - - len = printf(" [%u] %u", i, *idp++); - if (name != NULL) - (void) printf("%*s%s (%u)", (15 - len), "", - name, symidx); - (void) putchar('\n'); - } - } - - stats.s_ndata = n; - return (E_SUCCESS); -} - -static int -read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) -{ - /* LINTED - pointer alignment */ - const ushort_t *fp = (ushort_t *)(cd->cd_ctfdata + hp->cth_funcoff); - - /* LINTED - pointer alignment */ - const ushort_t *end = (ushort_t *)(cd->cd_ctfdata + hp->cth_typeoff); - - ulong_t id; - int symidx; - - if (flags != F_STATS) - print_line("- Functions "); - - if (hp->cth_funcoff & 1) - WARN("cth_funcoff is not aligned properly\n"); - if (hp->cth_funcoff >= cd->cd_ctflen) - WARN("file is truncated or cth_funcoff is corrupt\n"); - if (hp->cth_typeoff >= cd->cd_ctflen) - WARN("file is truncated or cth_typeoff is corrupt\n"); - if (hp->cth_funcoff > hp->cth_typeoff) - WARN("file is corrupt -- cth_funcoff > cth_typeoff\n"); - - for (symidx = -1, id = 0; fp < end; id++) { - ushort_t info = *fp++; - ushort_t kind = CTF_INFO_KIND(info); - ushort_t n = CTF_INFO_VLEN(info); - ushort_t i; - int nextsym; - char *name; - - if (cd->cd_symdata == NULL || (nextsym = next_sym(cd, symidx, - STT_FUNC, &name)) < 0) - name = NULL; - else - symidx = nextsym; - - if (kind == CTF_K_UNKNOWN && n == 0) - continue; /* skip padding */ - - if (kind != CTF_K_FUNCTION) { - (void) printf(" [%lu] unexpected kind -- %u\n", - id, kind); - return (E_ERROR); - } - - if (fp + n > end) { - (void) printf(" [%lu] vlen %u extends past section " - "boundary\n", id, n); - return (E_ERROR); - } - - if (flags != F_STATS) { - (void) printf(" [%lu] FUNC ", id); - if (name != NULL) - (void) printf("(%s) ", name); - (void) printf("returns: %u args: (", *fp++); - - if (n != 0) { - (void) printf("%u", *fp++); - for (i = 1; i < n; i++) - (void) printf(", %u", *fp++); - } - - (void) printf(")\n"); - } else - fp += n + 1; /* skip to next function definition */ - - stats.s_nfunc++; - stats.s_nargs += n; - stats.s_argmax = MAX(stats.s_argmax, n); - } - - return (E_SUCCESS); -} - -static int -read_types(const ctf_header_t *hp, const ctf_data_t *cd) -{ - /* LINTED - pointer alignment */ - const ctf_type_t *tp = (ctf_type_t *)(cd->cd_ctfdata + hp->cth_typeoff); - - /* LINTED - pointer alignment */ - const ctf_type_t *end = (ctf_type_t *)(cd->cd_ctfdata + hp->cth_stroff); - - ulong_t id; - - if (flags != F_STATS) - print_line("- Types "); - - if (hp->cth_typeoff & 3) - WARN("cth_typeoff is not aligned properly\n"); - if (hp->cth_typeoff >= cd->cd_ctflen) - WARN("file is truncated or cth_typeoff is corrupt\n"); - if (hp->cth_stroff >= cd->cd_ctflen) - WARN("file is truncated or cth_stroff is corrupt\n"); - if (hp->cth_typeoff > hp->cth_stroff) - WARN("file is corrupt -- cth_typeoff > cth_stroff\n"); - - id = 1; - if (hp->cth_parlabel || hp->cth_parname) - id += 1 << CTF_PARENT_SHIFT; - - for (/* */; tp < end; id++) { - ulong_t i, n = CTF_INFO_VLEN(tp->ctt_info); - size_t size, increment, vlen = 0; - int kind = CTF_INFO_KIND(tp->ctt_info); - - union { - const void *ptr; - const ctf_array_t *ap; - const ctf_member_t *mp; - const ctf_lmember_t *lmp; - const ctf_enum_t *ep; - const ushort_t *argp; - } u; - - if (flags != F_STATS) { - (void) printf(" %c%lu%c ", - "[<"[CTF_INFO_ISROOT(tp->ctt_info)], id, - "]>"[CTF_INFO_ISROOT(tp->ctt_info)]); - } - - if (tp->ctt_size == CTF_LSIZE_SENT) { - increment = sizeof (ctf_type_t); - size = (size_t)CTF_TYPE_LSIZE(tp); - } else { - increment = sizeof (ctf_stype_t); - size = tp->ctt_size; - } - u.ptr = (caddr_t)tp + increment; - - switch (kind) { - case CTF_K_INTEGER: - if (flags != F_STATS) { - uint_t encoding = *((const uint_t *)u.ptr); - - (void) printf("INTEGER %s encoding=%s offset=%u" - " bits=%u", ref_to_str(tp->ctt_name, hp, - cd), int_encoding_to_str( - CTF_INT_ENCODING(encoding)), - CTF_INT_OFFSET(encoding), - CTF_INT_BITS(encoding)); - } - vlen = sizeof (uint_t); - break; - - case CTF_K_FLOAT: - if (flags != F_STATS) { - uint_t encoding = *((const uint_t *)u.ptr); - - (void) printf("FLOAT %s encoding=%s offset=%u " - "bits=%u", ref_to_str(tp->ctt_name, hp, - cd), fp_encoding_to_str( - CTF_FP_ENCODING(encoding)), - CTF_FP_OFFSET(encoding), - CTF_FP_BITS(encoding)); - } - vlen = sizeof (uint_t); - break; - - case CTF_K_POINTER: - if (flags != F_STATS) { - (void) printf("POINTER %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - } - break; - - case CTF_K_ARRAY: - if (flags != F_STATS) { - (void) printf("ARRAY %s content: %u index: %u " - "nelems: %u\n", ref_to_str(tp->ctt_name, - hp, cd), u.ap->cta_contents, - u.ap->cta_index, u.ap->cta_nelems); - } - vlen = sizeof (ctf_array_t); - break; - - case CTF_K_FUNCTION: - if (flags != F_STATS) { - (void) printf("FUNCTION %s returns: %u args: (", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - - if (n != 0) { - (void) printf("%u", *u.argp++); - for (i = 1; i < n; i++, u.argp++) - (void) printf(", %u", *u.argp); - } - - (void) printf(")"); - } - - vlen = sizeof (ushort_t) * (n + (n & 1)); - break; - - case CTF_K_STRUCT: - case CTF_K_UNION: - if (kind == CTF_K_STRUCT) { - stats.s_nsmem += n; - stats.s_smmax = MAX(stats.s_smmax, n); - stats.s_nsbytes += size; - stats.s_sbmax = MAX(stats.s_sbmax, size); - - if (flags != F_STATS) - (void) printf("STRUCT"); - } else { - stats.s_numem += n; - stats.s_ummax = MAX(stats.s_ummax, n); - stats.s_nubytes += size; - stats.s_ubmax = MAX(stats.s_ubmax, size); - - if (flags != F_STATS) - (void) printf("UNION"); - } - - if (flags != F_STATS) { - (void) printf(" %s (%d bytes)\n", - ref_to_str(tp->ctt_name, hp, cd), size); - - if (size >= CTF_LSTRUCT_THRESH) { - for (i = 0; i < n; i++, u.lmp++) { - (void) printf( - "\t%s type=%u off=%llu\n", - ref_to_str(u.lmp->ctlm_name, - hp, cd), u.lmp->ctlm_type, - CTF_LMEM_OFFSET(u.lmp)); - } - } else { - for (i = 0; i < n; i++, u.mp++) { - (void) printf( - "\t%s type=%u off=%u\n", - ref_to_str(u.mp->ctm_name, - hp, cd), u.mp->ctm_type, - u.mp->ctm_offset); - } - } - } - - vlen = n * (size >= CTF_LSTRUCT_THRESH ? - sizeof (ctf_lmember_t) : sizeof (ctf_member_t)); - break; - - case CTF_K_ENUM: - if (flags != F_STATS) { - (void) printf("ENUM %s\n", - ref_to_str(tp->ctt_name, hp, cd)); - - for (i = 0; i < n; i++, u.ep++) { - (void) printf("\t%s = %d\n", - ref_to_str(u.ep->cte_name, hp, cd), - u.ep->cte_value); - } - } - - stats.s_nemem += n; - stats.s_emmax = MAX(stats.s_emmax, n); - - vlen = sizeof (ctf_enum_t) * n; - break; - - case CTF_K_FORWARD: - if (flags != F_STATS) { - (void) printf("FORWARD %s", - ref_to_str(tp->ctt_name, hp, cd)); - } - break; - - case CTF_K_TYPEDEF: - if (flags != F_STATS) { - (void) printf("TYPEDEF %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - } - break; - - case CTF_K_VOLATILE: - if (flags != F_STATS) { - (void) printf("VOLATILE %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - } - break; - - case CTF_K_CONST: - if (flags != F_STATS) { - (void) printf("CONST %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - } - break; - - case CTF_K_RESTRICT: - if (flags != F_STATS) { - (void) printf("RESTRICT %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); - } - break; - - case CTF_K_UNKNOWN: - break; /* hole in type id space */ - - default: - (void) printf("unexpected kind %u\n", kind); - return (E_ERROR); - } - - if (flags != F_STATS) - (void) printf("\n"); - - stats.s_ntypes++; - stats.s_types[kind]++; - - tp = (ctf_type_t *)((uintptr_t)tp + increment + vlen); - } - - return (E_SUCCESS); -} - -static int -read_strtab(const ctf_header_t *hp, const ctf_data_t *cd) -{ - size_t n, off, len = hp->cth_strlen; - const char *s = cd->cd_ctfdata + hp->cth_stroff; - - if (flags != F_STATS) - print_line("- String Table "); - - if (hp->cth_stroff >= cd->cd_ctflen) - WARN("file is truncated or cth_stroff is corrupt\n"); - if (hp->cth_stroff + hp->cth_strlen > cd->cd_ctflen) - WARN("file is truncated or cth_strlen is corrupt\n"); - - for (off = 0; len != 0; off += n) { - if (flags != F_STATS) { - (void) printf(" [%lu] %s\n", (ulong_t)off, - s[0] == '\0' ? "\\0" : s); - } - n = strlen(s) + 1; - len -= n; - s += n; - - stats.s_nstr++; - stats.s_strlen += n; - stats.s_strmax = MAX(stats.s_strmax, n); - } - - return (E_SUCCESS); -} - -static void -long_stat(const char *name, ulong_t value) -{ - (void) printf(" %-36s= %lu\n", name, value); -} - -static void -fp_stat(const char *name, float value) -{ - (void) printf(" %-36s= %.2f\n", name, value); -} - -static int -print_stats(void) -{ - print_line("- CTF Statistics "); - - long_stat("total number of data objects", stats.s_ndata); - (void) printf("\n"); - - long_stat("total number of functions", stats.s_nfunc); - long_stat("total number of function arguments", stats.s_nargs); - long_stat("maximum argument list length", stats.s_argmax); - - if (stats.s_nfunc != 0) { - fp_stat("average argument list length", - (float)stats.s_nargs / (float)stats.s_nfunc); - } - - (void) printf("\n"); - - long_stat("total number of types", stats.s_ntypes); - long_stat("total number of integers", stats.s_types[CTF_K_INTEGER]); - long_stat("total number of floats", stats.s_types[CTF_K_FLOAT]); - long_stat("total number of pointers", stats.s_types[CTF_K_POINTER]); - long_stat("total number of arrays", stats.s_types[CTF_K_ARRAY]); - long_stat("total number of func types", stats.s_types[CTF_K_FUNCTION]); - long_stat("total number of structs", stats.s_types[CTF_K_STRUCT]); - long_stat("total number of unions", stats.s_types[CTF_K_UNION]); - long_stat("total number of enums", stats.s_types[CTF_K_ENUM]); - long_stat("total number of forward tags", stats.s_types[CTF_K_FORWARD]); - long_stat("total number of typedefs", stats.s_types[CTF_K_TYPEDEF]); - long_stat("total number of volatile types", - stats.s_types[CTF_K_VOLATILE]); - long_stat("total number of const types", stats.s_types[CTF_K_CONST]); - long_stat("total number of restrict types", - stats.s_types[CTF_K_RESTRICT]); - long_stat("total number of unknowns (holes)", - stats.s_types[CTF_K_UNKNOWN]); - - (void) printf("\n"); - - long_stat("total number of struct members", stats.s_nsmem); - long_stat("maximum number of struct members", stats.s_smmax); - long_stat("total size of all structs", stats.s_nsbytes); - long_stat("maximum size of a struct", stats.s_sbmax); - - if (stats.s_types[CTF_K_STRUCT] != 0) { - fp_stat("average number of struct members", - (float)stats.s_nsmem / (float)stats.s_types[CTF_K_STRUCT]); - fp_stat("average size of a struct", (float)stats.s_nsbytes / - (float)stats.s_types[CTF_K_STRUCT]); - } - - (void) printf("\n"); - - long_stat("total number of union members", stats.s_numem); - long_stat("maximum number of union members", stats.s_ummax); - long_stat("total size of all unions", stats.s_nubytes); - long_stat("maximum size of a union", stats.s_ubmax); - - if (stats.s_types[CTF_K_UNION] != 0) { - fp_stat("average number of union members", - (float)stats.s_numem / (float)stats.s_types[CTF_K_UNION]); - fp_stat("average size of a union", (float)stats.s_nubytes / - (float)stats.s_types[CTF_K_UNION]); - } - - (void) printf("\n"); - - long_stat("total number of enum members", stats.s_nemem); - long_stat("maximum number of enum members", stats.s_emmax); - - if (stats.s_types[CTF_K_ENUM] != 0) { - fp_stat("average number of enum members", - (float)stats.s_nemem / (float)stats.s_types[CTF_K_ENUM]); - } - - (void) printf("\n"); - - long_stat("total number of unique strings", stats.s_nstr); - long_stat("bytes of string data", stats.s_strlen); - long_stat("maximum string length", stats.s_strmax); - - if (stats.s_nstr != 0) { - fp_stat("average string length", - (float)stats.s_strlen / (float)stats.s_nstr); - } - - (void) printf("\n"); - return (E_SUCCESS); -} - -static int -print_usage(FILE *fp, int verbose) -{ - (void) fprintf(fp, "Usage: %s [-dfhlsSt] [-u file] file\n", getpname()); - - if (verbose) { - (void) fprintf(fp, - "\t-d dump data object section\n" - "\t-f dump function section\n" - "\t-h dump file header\n" - "\t-l dump label table\n" - "\t-s dump string table\n" - "\t-S dump statistics\n" - "\t-t dump type section\n" - "\t-u save uncompressed CTF to a file\n"); - } - - return (E_USAGE); -} - -static Elf_Scn * -findelfscn(Elf *elf, GElf_Ehdr *ehdr, char *secname) -{ - GElf_Shdr shdr; - Elf_Scn *scn; - char *name; - - for (scn = NULL; (scn = elf_nextscn(elf, scn)) != NULL; ) { - if (gelf_getshdr(scn, &shdr) != NULL && (name = - elf_strptr(elf, ehdr->e_shstrndx, shdr.sh_name)) != NULL && - strcmp(name, secname) == 0) - return (scn); - } - - return (NULL); -} - -int -main(int argc, char *argv[]) -{ - const char *filename = NULL; - const char *ufile = NULL; - int error = 0; - int c, fd, ufd; - - ctf_data_t cd; - const ctf_preamble_t *pp; - ctf_header_t *hp; - Elf *elf; - GElf_Ehdr ehdr; - - (void) elf_version(EV_CURRENT); - - for (opterr = 0; optind < argc; optind++) { - while ((c = getopt(argc, argv, "dfhlsStu:")) != (int)EOF) { - switch (c) { - case 'd': - flags |= F_DATA; - break; - case 'f': - flags |= F_FUNC; - break; - case 'h': - flags |= F_HDR; - break; - case 'l': - flags |= F_LABEL; - break; - case 's': - flags |= F_STR; - break; - case 'S': - flags |= F_STATS; - break; - case 't': - flags |= F_TYPES; - break; - case 'u': - ufile = optarg; - break; - default: - if (optopt == '?') - return (print_usage(stdout, 1)); - warn("illegal option -- %c\n", optopt); - return (print_usage(stderr, 0)); - } - } - - if (optind < argc) { - if (filename != NULL) - return (print_usage(stderr, 0)); - filename = argv[optind]; - } - } - - if (filename == NULL) - return (print_usage(stderr, 0)); - - if (flags == 0 && ufile == NULL) - flags = F_ALLMSK; - - if ((fd = open(filename, O_RDONLY)) == -1) - die("failed to open %s", filename); - - if ((elf = elf_begin(fd, ELF_C_READ, NULL)) != NULL && - gelf_getehdr(elf, &ehdr) != NULL) { - - Elf_Data *dp; - Elf_Scn *ctfscn = findelfscn(elf, &ehdr, ".SUNW_ctf"); - Elf_Scn *symscn; - GElf_Shdr ctfshdr; - - if (ctfscn == NULL || (dp = elf_getdata(ctfscn, NULL)) == NULL) - die("%s does not contain .SUNW_ctf data\n", filename); - - cd.cd_ctfdata = dp->d_buf; - cd.cd_ctflen = dp->d_size; - - /* - * If the sh_link field of the CTF section header is non-zero - * it indicates which section contains the symbol table that - * should be used. We default to the .symtab section if sh_link - * is zero or if there's an error reading the section header. - */ - if (gelf_getshdr(ctfscn, &ctfshdr) != NULL && - ctfshdr.sh_link != 0) { - symscn = elf_getscn(elf, ctfshdr.sh_link); - } else { - symscn = findelfscn(elf, &ehdr, ".symtab"); - } - - /* If we found a symbol table, find the corresponding strings */ - if (symscn != NULL) { - GElf_Shdr shdr; - Elf_Scn *symstrscn; - - if (gelf_getshdr(symscn, &shdr) != NULL) { - symstrscn = elf_getscn(elf, shdr.sh_link); - - cd.cd_nsyms = shdr.sh_size / shdr.sh_entsize; - cd.cd_symdata = elf_getdata(symscn, NULL); - cd.cd_strdata = elf_getdata(symstrscn, NULL); - } - } - } else { - struct stat st; - - if (fstat(fd, &st) == -1) - die("failed to fstat %s", filename); - - cd.cd_ctflen = st.st_size; - cd.cd_ctfdata = mmap(NULL, cd.cd_ctflen, PROT_READ, - MAP_PRIVATE, fd, 0); - if (cd.cd_ctfdata == MAP_FAILED) - die("failed to mmap %s", filename); - } - - /* - * Get a pointer to the CTF data buffer and interpret the first portion - * as a ctf_header_t. Validate the magic number and size. - */ - - if (cd.cd_ctflen < sizeof (ctf_preamble_t)) - die("%s does not contain a CTF preamble\n", filename); - - /* LINTED - pointer alignment */ - pp = (const ctf_preamble_t *)cd.cd_ctfdata; - - if (pp->ctp_magic != CTF_MAGIC) - die("%s does not appear to contain CTF data\n", filename); - - if (pp->ctp_version == CTF_VERSION) { - /* LINTED - pointer alignment */ - hp = (ctf_header_t *)cd.cd_ctfdata; - cd.cd_ctfdata = (caddr_t)cd.cd_ctfdata + sizeof (ctf_header_t); - - if (cd.cd_ctflen < sizeof (ctf_header_t)) { - die("%s does not contain a v%d CTF header\n", filename, - CTF_VERSION); - } - - } else { - die("%s contains unsupported CTF version %d\n", filename, - pp->ctp_version); - } - - /* - * If the data buffer is compressed, then malloc a buffer large enough - * to hold the decompressed data, and use zlib to decompress it. - */ - if (hp->cth_flags & CTF_F_COMPRESS) { - z_stream zstr; - void *buf; - int rc; - - if ((buf = malloc(hp->cth_stroff + hp->cth_strlen)) == NULL) - die("failed to allocate decompression buffer"); - - bzero(&zstr, sizeof (z_stream)); - zstr.next_in = (void *)cd.cd_ctfdata; - zstr.avail_in = cd.cd_ctflen; - zstr.next_out = buf; - zstr.avail_out = hp->cth_stroff + hp->cth_strlen; - - if ((rc = inflateInit(&zstr)) != Z_OK) - die("failed to initialize zlib: %s\n", zError(rc)); - - if ((rc = inflate(&zstr, Z_FINISH)) != Z_STREAM_END) - die("failed to decompress CTF data: %s\n", zError(rc)); - - if ((rc = inflateEnd(&zstr)) != Z_OK) - die("failed to finish decompression: %s\n", zError(rc)); - - if (zstr.total_out != hp->cth_stroff + hp->cth_strlen) - die("CTF data is corrupt -- short decompression\n"); - - cd.cd_ctfdata = buf; - cd.cd_ctflen = hp->cth_stroff + hp->cth_strlen; - } - - if (flags & F_HDR) - error |= print_header(hp, &cd); - if (flags & (F_LABEL)) - error |= print_labeltable(hp, &cd); - if (flags & (F_DATA | F_STATS)) - error |= read_data(hp, &cd); - if (flags & (F_FUNC | F_STATS)) - error |= read_funcs(hp, &cd); - if (flags & (F_TYPES | F_STATS)) - error |= read_types(hp, &cd); - if (flags & (F_STR | F_STATS)) - error |= read_strtab(hp, &cd); - if (flags & F_STATS) - error |= print_stats(); - - /* - * If the -u option is specified, write the uncompressed CTF data to a - * raw CTF file. CTF data can already be extracted compressed by - * applying elfdump -w -N .SUNW_ctf to an ELF file, so we don't bother. - */ - if (ufile != NULL) { - ctf_header_t h; - - bcopy(hp, &h, sizeof (h)); - h.cth_flags &= ~CTF_F_COMPRESS; - - if ((ufd = open(ufile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0 || - write(ufd, &h, sizeof (h)) != sizeof (h) || - write(ufd, cd.cd_ctfdata, cd.cd_ctflen) != cd.cd_ctflen) { - warn("failed to write CTF data to '%s'", ufile); - error |= E_ERROR; - } - - (void) close(ufd); - } - - if (elf != NULL) - (void) elf_end(elf); - - (void) close(fd); - return (error); -} diff --git a/usr/src/tools/ctf/dump/Makefile.com b/usr/src/tools/ctf/libctf/Makefile index 9877fa06a3..5e9236c43d 100644 --- a/usr/src/tools/ctf/dump/Makefile.com +++ b/usr/src/tools/ctf/libctf/Makefile @@ -19,49 +19,28 @@ # CDDL HEADER END # # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -.KEEP_STATE: -.SUFFIXES: - -PROG = ctfdump -SRCS = dump.c utils.c symbol.c - -include ../../Makefile.ctf - -LDFLAGS += -L$(NATIVE_ADJUNCT)/lib -LDLIBS += -lelf -lz - -OBJS = $(SRCS:%.c=%.o) -LINTFILES = $(SRCS:%.c=%.ln) +include ../../Makefile.tools -CERRWARN += -_gcc=-Wno-uninitialized +HDRS = libctf.h +HDRDIR = common -.NO_PARALLEL: -.PARALLEL: $(OBJS) $(LINTFILES) +SUBDIRS = $(MACH) -all: $(PROG) +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -%.o: ../%.c - $(COMPILE.c) $< - -$(ROOTONBLDMACHPROG): $(PROG) - -install: $(ROOTONBLDMACHPROG) - -clean: - $(RM) $(OBJS) $(LINTFILES) +.KEEP_STATE: -%.ln: ../%.c - $(LINT.c) -c $< +all clean clobber install lint: $(SUBDIRS) -lint: $(LINTFILES) - $(LINT) $(LINTFLAGS) $(LINTFILES) $(LDLIBS) +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) -include ../../Makefile.ctf.targ +FRC: diff --git a/usr/src/tools/ctf/libctf/Makefile.com b/usr/src/tools/ctf/libctf/Makefile.com new file mode 100644 index 0000000000..e47bde3e3b --- /dev/null +++ b/usr/src/tools/ctf/libctf/Makefile.com @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include $(SRC)/lib/libctf/Makefile.shared.com +include ../../Makefile.ctf + +CPPFLAGS += -include ../../common/ctf_headers.h \ + -DCTF_OLD_VERSIONS \ + -DCTF_TOOLS_BUILD +LDLIBS += -lc -lelf + +.KEEP_STATE: + +all: $(LIBS) + +install: all $(ROOTONBLDLIBMACH)/libctf.so.1 $(ROOTONBLDLIBMACH)/libctf.so + +$(ROOTONBLDLIBMACH)/%: % + $(INS.file) + +$(ROOTONBLDLIBMACH)/$(LIBLINKS): $(ROOTONBLDLIBMACH)/$(LIBLINKS)$(VERS) + $(INS.liblink) + +# +# Just like with libdwarf, we can't actually add ctf to ourselves, +# because we're part of the tools for creating CTF. +# +$(DYNLIB) := CTFMERGE_POST= : +CTFCONVERT_O= : + +include $(SRC)/lib/Makefile.targ +include $(SRC)/lib/libctf/Makefile.shared.targ diff --git a/usr/src/tools/ctf/libctf/i386/Makefile b/usr/src/tools/ctf/libctf/i386/Makefile new file mode 100644 index 0000000000..bb2f077f86 --- /dev/null +++ b/usr/src/tools/ctf/libctf/i386/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com + +all: $(LIBS) diff --git a/usr/src/tools/ctf/libctf/sparc/Makefile b/usr/src/tools/ctf/libctf/sparc/Makefile new file mode 100644 index 0000000000..bb2f077f86 --- /dev/null +++ b/usr/src/tools/ctf/libctf/sparc/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2015, Joyent, Inc. +# + +include ../Makefile.com + +all: $(LIBS) |