From b267fa2867fd98d2f8864fd82efc8ad4b2276f39 Mon Sep 17 00:00:00 2001 From: Jason King Date: Fri, 5 May 2017 22:58:26 +0000 Subject: OS-7200 would like thread name API OS-7205 bhyve makefile uses wrong linker flags Reviewed by: Robert Mustacchi Reviewed by: Jason King Reviewed by: Patrick Mooney Approved by: Patrick Mooney --- usr/src/uts/common/sys/dtrace.h | 7 ++++--- usr/src/uts/common/sys/elf.h | 19 ++++++++++--------- usr/src/uts/common/sys/procfs.h | 15 +++++++++++++-- usr/src/uts/common/sys/thread.h | 3 ++- 4 files changed, 29 insertions(+), 15 deletions(-) (limited to 'usr/src/uts/common/sys') diff --git a/usr/src/uts/common/sys/dtrace.h b/usr/src/uts/common/sys/dtrace.h index 44ca7d8ae7..ab6d4c4445 100644 --- a/usr/src/uts/common/sys/dtrace.h +++ b/usr/src/uts/common/sys/dtrace.h @@ -25,7 +25,7 @@ */ /* - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. * Copyright (c) 2013 by Delphix. All rights reserved. */ @@ -242,6 +242,7 @@ typedef enum dtrace_probespec { #define DIF_VAR_UID 0x011e /* process user ID */ #define DIF_VAR_GID 0x011f /* process group ID */ #define DIF_VAR_ERRNO 0x0120 /* thread errno */ +#define DIF_VAR_THREADNAME 0x0121 /* thread name */ #define DIF_SUBR_RAND 0 #define DIF_SUBR_MUTEX_OWNED 1 @@ -2212,8 +2213,8 @@ extern void dtrace_probe(dtrace_id_t, uintptr_t arg0, uintptr_t arg1, */ typedef struct dtrace_helper_probedesc { char *dthpb_mod; /* probe module */ - char *dthpb_func; /* probe function */ - char *dthpb_name; /* probe name */ + char *dthpb_func; /* probe function */ + char *dthpb_name; /* probe name */ uint64_t dthpb_base; /* base address */ uint32_t *dthpb_offs; /* offsets array */ uint32_t *dthpb_enoffs; /* is-enabled offsets array */ diff --git a/usr/src/uts/common/sys/elf.h b/usr/src/uts/common/sys/elf.h index 0dd4f2d17e..1a2ca397ef 100644 --- a/usr/src/uts/common/sys/elf.h +++ b/usr/src/uts/common/sys/elf.h @@ -429,10 +429,10 @@ typedef struct { #define ELFOSABI_OPENVMS 13 /* Open VMS */ #define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */ #define ELFOSABI_AROS 15 /* Amiga Research OS */ -#define ELFOSABI_FENIXOS 16 /* The FenixOS highly scalable */ +#define ELFOSABI_FENIXOS 16 /* The FenixOS highly scalable */ /* multi-core OS */ -#define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */ -#define ELFOSABI_OPENVOS 18 /* Stratus Technologies OpenVOS */ +#define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */ +#define ELFOSABI_OPENVOS 18 /* Stratus Technologies OpenVOS */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */ @@ -820,7 +820,7 @@ typedef struct { #define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type)) #define ELF64_R_SYM(info) ((info)>>32) -#define ELF64_R_TYPE(info) ((Elf64_Word)(info)) +#define ELF64_R_TYPE(info) ((Elf64_Word)(info)) #define ELF64_R_INFO(sym, type) (((Elf64_Xword)(sym)<<32)+(Elf64_Xword)(type)) @@ -867,7 +867,7 @@ typedef struct { #if defined(_LP64) || defined(_LONGLONG_TYPE) typedef struct { Elf32_Lword m_value; /* symbol value */ - Elf32_Word m_info; /* size + index */ + Elf32_Word m_info; /* size + index */ Elf32_Word m_poffset; /* symbol offset */ Elf32_Half m_repeat; /* repeat count */ Elf32_Half m_stride; /* stride info */ @@ -886,7 +886,7 @@ typedef struct { typedef struct { Elf64_Lword m_value; /* symbol value */ - Elf64_Xword m_info; /* size + index */ + Elf64_Xword m_info; /* size + index */ Elf64_Xword m_poffset; /* symbol offset */ Elf64_Half m_repeat; /* repeat count */ Elf64_Half m_stride; /* stride info */ @@ -945,7 +945,7 @@ typedef Elf64_Word Elf64_Capchain; * info = ELF64_C_INFO(sym, grp) */ #define ELF64_C_SYM(info) ((info)>>32) -#define ELF64_C_GROUP(info) ((Elf64_Word)(info)) +#define ELF64_C_GROUP(info) ((Elf64_Word)(info)) #define ELF64_C_INFO(sym, grp) (((Elf64_Xword)(sym)<<32)+(Elf64_Xword)(grp)) #endif /* defined(_LP64) || defined(_LONGLONG_TYPE) */ @@ -1014,10 +1014,11 @@ typedef Elf64_Word Elf64_Capchain; #define NT_PRPRIVINFO 19 /* priv_impl_info_t */ #define NT_CONTENT 20 /* core_content_t */ #define NT_ZONENAME 21 /* string from getzonenamebyid(3C) */ -#define NT_FDINFO 22 /* open fd info */ +#define NT_FDINFO 22 /* open fd info */ #define NT_SPYMASTER 23 /* psinfo_t for agent LWP spymaster */ #define NT_SECFLAGS 24 /* process security-flags */ -#define NT_NUM 24 +#define NT_LWPNAME 25 /* prlwpname_t */ +#define NT_NUM 25 #ifdef _KERNEL diff --git a/usr/src/uts/common/sys/procfs.h b/usr/src/uts/common/sys/procfs.h index 427d682d68..38c006f8f0 100644 --- a/usr/src/uts/common/sys/procfs.h +++ b/usr/src/uts/common/sys/procfs.h @@ -25,7 +25,7 @@ */ /* * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. - * Copyright 2015, Joyent, Inc. + * Copyright 2018, Joyent, Inc. */ #ifndef _SYS_PROCFS_H @@ -66,6 +66,7 @@ extern "C" { #include #include #include +#include /* * System call interfaces for /proc. @@ -346,7 +347,7 @@ typedef struct prxmap { int pr_shmid; /* SysV shmid, -1 if not SysV shared memory */ dev_t pr_dev; /* st_dev from stat64() of mapped object, or PRNODEV */ uint64_t pr_ino; /* st_ino from stat64() of mapped object, if any */ - size_t pr_rss; /* pages of resident memory */ + size_t pr_rss; /* pages of resident memory */ size_t pr_anon; /* pages of resident anonymous memory */ size_t pr_locked; /* pages of locked memory */ size_t pr_pad; /* currently unused */ @@ -536,6 +537,16 @@ typedef struct prfdinfo { char pr_path[MAXPATHLEN]; } prfdinfo_t; +/* + * Representation of LWP name in core files. In /proc, we use a simple char + * array, but in core files we need to make it easy to correlate the note back + * to the right LWP. For simplicity, we'll use 32/64 consistent types. + */ +typedef struct prlwpname { + uint64_t pr_lwpid; + char pr_lwpname[THREAD_NAME_MAX]; +} prlwpname_t; + /* * Header for /proc//lstatus /proc//lpsinfo /proc//lusage */ diff --git a/usr/src/uts/common/sys/thread.h b/usr/src/uts/common/sys/thread.h index 678d356564..6cc474f864 100644 --- a/usr/src/uts/common/sys/thread.h +++ b/usr/src/uts/common/sys/thread.h @@ -607,7 +607,8 @@ extern disp_lock_t stop_lock; /* lock protecting stopped threads */ caddr_t thread_stk_init(caddr_t); /* init thread stack */ -void thread_setname(kthread_t *, const char *); +int thread_setname(kthread_t *, const char *); +int thread_vsetname(kthread_t *, const char *, ...); extern int default_binding_mode; extern int default_stksize; -- cgit v1.2.3 From 8fe8a39ea9f7811d9c1e2e48a46932561906883f Mon Sep 17 00:00:00 2001 From: John Levon Date: Fri, 12 Oct 2018 17:05:41 +0000 Subject: Revert "OS-7270 ctfconvert doesn't handle DW_AT_specification": breaks build Reviewed by: Ryan Zezeski Approved by: Ryan Zezeski --- usr/src/Makefile.lint | 1 - usr/src/cmd/ctfdump/Makefile | 5 +- usr/src/cmd/ctfdump/ctfdump.c | 440 ++------------------------------- usr/src/cmd/mdb/Makefile.libstandctf | 5 - usr/src/common/ctf/ctf_types.c | 143 +---------- usr/src/lib/libctf/Makefile.shared.com | 10 +- usr/src/lib/libctf/common/ctf_dwarf.c | 80 ++---- usr/src/lib/libctf/common/mapfile-vers | 5 +- usr/src/man/man1/ctfdump.1 | 34 +-- usr/src/tools/ctf/common/ctf_headers.h | 9 +- usr/src/tools/ctf/ctfdump/Makefile.com | 3 - usr/src/tools/ctf/libctf/Makefile.com | 5 +- usr/src/uts/common/sys/ctf.h | 14 +- usr/src/uts/common/sys/ctf_api.h | 7 +- usr/src/uts/intel/ctf/Makefile | 4 - usr/src/uts/sparc/ctf/Makefile | 4 - 16 files changed, 71 insertions(+), 698 deletions(-) (limited to 'usr/src/uts/common/sys') diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index 626c51d406..da55853bba 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -96,7 +96,6 @@ COMMON_SUBDIRS = \ cmd/cpio \ cmd/crypt \ cmd/csplit \ - cmd/ctfdump \ cmd/ctrun \ cmd/ctstat \ cmd/ctwatch \ diff --git a/usr/src/cmd/ctfdump/Makefile b/usr/src/cmd/ctfdump/Makefile index 37a1ef4cc8..962ca43a8f 100644 --- a/usr/src/cmd/ctfdump/Makefile +++ b/usr/src/cmd/ctfdump/Makefile @@ -10,7 +10,7 @@ # # -# Copyright 2018 Joyent, Inc. +# Copyright (c) 2015, Joyent, Inc. # PROG= ctfdump @@ -20,9 +20,6 @@ include ../Makefile.cmd CFLAGS += $(CCVERBOSE) LDLIBS += -lctf -CSTD = $(CSTD_GNU99) -C99LMODE = -Xc99=%all - .KEEP_STATE: all: $(PROG) diff --git a/usr/src/cmd/ctfdump/ctfdump.c b/usr/src/cmd/ctfdump/ctfdump.c index 19245db8b4..d0ff63a02a 100644 --- a/usr/src/cmd/ctfdump/ctfdump.c +++ b/usr/src/cmd/ctfdump/ctfdump.c @@ -10,7 +10,7 @@ */ /* - * Copyright (c) 2018, Joyent, Inc. + * Copyright (c) 2015, Joyent, Inc. */ /* @@ -29,25 +29,21 @@ #include #include #include -#include #include #include #include -#include - -#define MAX_NAMELEN (512) typedef enum ctfdump_arg { - CTFDUMP_OBJECTS = 0x001, - CTFDUMP_FUNCTIONS = 0x002, - CTFDUMP_HEADER = 0x004, - CTFDUMP_LABELS = 0x008, - CTFDUMP_STRINGS = 0x010, - CTFDUMP_STATS = 0x020, - CTFDUMP_TYPES = 0x040, - CTFDUMP_DEFAULT = 0x07f, - CTFDUMP_OUTPUT = 0x080, - CTFDUMP_SOURCE = 0x100, + CTFDUMP_OBJECTS = 0x01, + CTFDUMP_FUNCTIONS = 0x02, + CTFDUMP_HEADER = 0x04, + CTFDUMP_LABELS = 0x08, + CTFDUMP_STRINGS = 0x10, + CTFDUMP_STATS = 0x20, + CTFDUMP_TYPES = 0x40, + CTFDUMP_DEFAULT = 0x7f, + CTFDUMP_OUTPUT = 0x80, + CTFDUMP_ALL = 0xff } ctfdump_arg_t; typedef struct ctfdump_stat { @@ -71,14 +67,6 @@ typedef struct ctfdump_stat { ulong_t cs_strmax; /* longest string */ } ctfdump_stat_t; -typedef struct { - char ci_name[MAX_NAMELEN]; - ctf_id_t ci_id; - ulong_t ci_symidx; - ctf_funcinfo_t ci_funcinfo; -} ctf_idname_t; - -static ctf_idname_t *idnames; static const char *g_progname; static ctfdump_arg_t g_dump; static ctf_file_t *g_fp; @@ -118,7 +106,7 @@ ctfdump_printf(ctfdump_arg_t arg, const char *fmt, ...) return; va_start(ap, fmt); - (void) vfprintf(stdout, fmt, ap); + vfprintf(stdout, fmt, ap); va_end(ap); } @@ -129,7 +117,7 @@ ctfdump_warn(const char *fmt, ...) (void) fprintf(stderr, "%s: ", g_progname); va_start(ap, fmt); - (void) vfprintf(stderr, fmt, ap); + vfprintf(stderr, fmt, ap); va_end(ap); } @@ -140,7 +128,7 @@ ctfdump_fatal(const char *fmt, ...) (void) fprintf(stderr, "%s: ", g_progname); va_start(ap, fmt); - (void) vfprintf(stderr, fmt, ap); + vfprintf(stderr, fmt, ap); va_end(ap); exit(1); @@ -157,10 +145,9 @@ ctfdump_usage(const char *fmt, ...) va_end(ap); } - (void) fprintf(stderr, "Usage: %s [-cdfhlsSt] [-p parent] [-u outfile] " + (void) fprintf(stderr, "Usage: %s [-dfhlsSt] [-p parent] [-u outfile] " "file\n" "\n" - "\t-c dump C-style output\n" "\t-d dump object data\n" "\t-f dump function data\n" "\t-h dump the CTF header\n" @@ -185,8 +172,6 @@ ctfdump_title(ctfdump_arg_t arg, const char *header) static int ctfdump_objects_cb(const char *name, ctf_id_t id, ulong_t symidx, void *arg) { - _NOTE(ARGUNUSED(arg)); - int len; len = snprintf(NULL, 0, " [%u] %u", g_stats.cs_ndata, id); @@ -223,7 +208,6 @@ static int ctfdump_functions_cb(const char *name, ulong_t symidx, ctf_funcinfo_t *ctc, void *arg) { - _NOTE(ARGUNUSED(arg)); int i; if (ctc->ctc_argc != 0) { @@ -300,7 +284,6 @@ ctfdump_header(void) static int ctfdump_labels_cb(const char *name, const ctf_lblinfo_t *li, void *arg) { - _NOTE(ARGUNUSED(arg)); ctfdump_printf(CTFDUMP_LABELS, " %5lu %s\n", li->ctb_typeidx, name); return (0); } @@ -513,10 +496,9 @@ ctfdump_enum_cb(const char *name, int value, void *arg) static int ctfdump_types_cb(ctf_id_t id, boolean_t root, void *arg) { - _NOTE(ARGUNUSED(arg)); int kind, i, count; ctf_id_t ref; - char name[MAX_NAMELEN], ienc[128]; + char name[512], ienc[128]; const char *encn; ctf_funcinfo_t ctc; ctf_arinfo_t ar; @@ -680,379 +662,10 @@ ctfdump_types(void) ctfdump_title(CTFDUMP_TYPES, "Types"); if (ctf_type_iter(g_fp, B_TRUE, ctfdump_types_cb, NULL) == CTF_ERR) { - ctfdump_warn("failed to dump types: %s\n", - ctf_errmsg(ctf_errno(g_fp))); - g_exit = 1; - } -} - -/* - * C-style output. This is designed mainly for comparison purposes, and doesn't - * produce directly valid C: - * - * - the declarations are sorted alphabetically not semantically - * - anonymous enums without other users are elided (e.g. IDCS_PROBE_SENT) - * - doubly-pointed-to functions are wrong (e.g. in kiconv_ops_t) - * - anon unions declared within SOUs aren't expanded - * - function arguments aren't expanded recursively - */ - -static void -ctfsrc_refname(ctf_id_t id, char *buf, size_t bufsize) -{ - ctf_id_t ref; - - if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR) { - ctfdump_fatal("failed to get reference type for %ld: " - "%s\n", id, ctf_errmsg(ctf_errno(g_fp))); - } - - (void) ctf_type_name(g_fp, ref, buf, bufsize); -} - -static int -ctfsrc_member_cb(const char *member, ctf_id_t type, ulong_t off, void *arg) -{ - _NOTE(ARGUNUSED(arg)); - char name[MAX_NAMELEN]; - - if (ctf_type_cname(g_fp, type, name, sizeof (name), member) == NULL) { - if (ctf_errno(g_fp) != ECTF_NOPARENT) { - ctfdump_fatal("type %lu missing name: %s\n", type, - ctf_errmsg(ctf_errno(g_fp))); - } - - (void) snprintf(name, sizeof (name), "unknown_t %s", member); - } - - /* - * A byte offset is friendlier, but we'll print bits too if it's not - * aligned (i.e. a bitfield). - */ - if (off % NBBY != 0) { - (void) printf("\t%s; /* offset: %lu bytes (%lu bits) */\n", - name, off / NBBY, off); - } else { - (void) printf("\t%s; /* offset: %lu bytes */\n", - name, off / NBBY); - } - return (0); -} - -static int -ctfsrc_enum_cb(const char *name, int value, void *arg) -{ - _NOTE(ARGUNUSED(arg)); - (void) printf("\t%s = %d,\n", name, value); - return (0); -} - -static int -is_anon_refname(const char *refname) -{ - return ((strcmp(refname, "struct ") == 0 || - strcmp(refname, "union ") == 0 || - strcmp(refname, "enum ") == 0)); -} - -static int -ctfsrc_collect_types_cb(ctf_id_t id, boolean_t root, void *arg) -{ - _NOTE(ARGUNUSED(root, arg)); - (void) ctf_type_name(g_fp, id, idnames[id].ci_name, - sizeof (idnames[id].ci_name)); - idnames[id].ci_id = id; - return (0); -} - -static void -ctfsrc_type(ctf_id_t id, const char *name) -{ - char refname[MAX_NAMELEN]; - ctf_id_t ref; - ssize_t size; - int kind; - - if ((kind = ctf_type_kind(g_fp, id)) == CTF_ERR) { - ctfdump_fatal("encountered malformed ctf, type %s does not " - "have a kind: %s\n", name, ctf_errmsg(ctf_errno(g_fp))); - } - - switch (kind) { - case CTF_K_STRUCT: - case CTF_K_UNION: - /* - * Delay printing anonymous SOUs; a later typedef will usually - * pick them up. - */ - if (is_anon_refname(name)) - break; - - if ((size = ctf_type_size(g_fp, id)) == CTF_ERR) { - ctfdump_fatal("failed to get size of %s: %s\n", name, - ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("%s { /* 0x%x bytes */\n", name, size); - - if (ctf_member_iter(g_fp, id, ctfsrc_member_cb, NULL) != 0) { - ctfdump_fatal("failed to iterate members of %s: %s\n", - name, ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("};\n\n"); - break; - case CTF_K_ENUM: - /* - * This will throw away any anon enum that isn't followed by a - * typedef... - */ - if (is_anon_refname(name)) - break; - - (void) printf("%s {\n", name); - - if (ctf_enum_iter(g_fp, id, ctfsrc_enum_cb, NULL) != 0) { - ctfdump_fatal("failed to iterate enumerators of %s: " - "%s\n", name, ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("};\n\n"); - break; - case CTF_K_TYPEDEF: - ctfsrc_refname(id, refname, sizeof (refname)); - - if (!is_anon_refname(refname)) { - (void) ctf_type_cname(g_fp, - ctf_type_reference(g_fp, id), refname, - sizeof (refname), name); - - (void) printf("typedef %s;\n\n", refname); - break; - } - - ref = ctf_type_reference(g_fp, id); - - if (ctf_type_kind(g_fp, ref) == CTF_K_ENUM) { - (void) printf("typedef enum {\n"); - - if (ctf_enum_iter(g_fp, ref, - ctfsrc_enum_cb, NULL) != 0) { - ctfdump_fatal("failed to iterate enumerators " - "of %s: %s\n", refname, - ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("} %s;\n\n", name); - } else { - if ((size = ctf_type_size(g_fp, ref)) == CTF_ERR) { - ctfdump_fatal("failed to get size of %s: %s\n", - refname, ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("typedef %s{ /* 0x%x bytes */\n", - refname, size); - - if (ctf_member_iter(g_fp, ref, - ctfsrc_member_cb, NULL) != 0) { - ctfdump_fatal("failed to iterate members " - "of %s: %s\n", refname, - ctf_errmsg(ctf_errno(g_fp))); - } - - (void) printf("} %s;\n\n", name); - } - - break; - case CTF_K_FORWARD: - (void) printf("%s;\n\n", name); - break; - case CTF_K_UNKNOWN: - case CTF_K_INTEGER: - case CTF_K_FLOAT: - case CTF_K_POINTER: - case CTF_K_ARRAY: - case CTF_K_FUNCTION: - case CTF_K_VOLATILE: - case CTF_K_CONST: - case CTF_K_RESTRICT: - break; - default: - ctfdump_fatal("encountered unknown kind for type %s: %d\n", - name, kind); - break; - } -} - -static int -ctfsrc_collect_objects_cb(const char *name, ctf_id_t id, - ulong_t symidx, void *arg) -{ - size_t *count = arg; - - /* local static vars can have an unknown ID */ - if (id == 0) - return (0); - - (void) strlcpy(idnames[*count].ci_name, name, - sizeof (idnames[*count].ci_name)); - idnames[*count].ci_id = id; - idnames[*count].ci_symidx = symidx; - *count = *count + 1; - return (0); -} - -static void -ctfsrc_object(ctf_id_t id, const char *name) -{ - char tname[MAX_NAMELEN]; - - if (ctf_type_cname(g_fp, id, tname, sizeof (tname), name) == NULL) { - if (ctf_errno(g_fp) != ECTF_NOPARENT) { - ctfdump_fatal("type %ld missing name: %s\n", id, - ctf_errmsg(ctf_errno(g_fp))); - } - (void) snprintf(tname, sizeof (tname), "unknown_t %s", name); - } - - (void) printf("extern %s;\n", tname); -} - -static int -ctfsrc_collect_functions_cb(const char *name, ulong_t symidx, - ctf_funcinfo_t *ctc, void *arg) -{ - size_t *count = arg; - - (void) strlcpy(idnames[*count].ci_name, name, - sizeof (idnames[*count].ci_name)); - bcopy(ctc, &idnames[*count].ci_funcinfo, sizeof (*ctc)); - idnames[*count].ci_id = 0; - idnames[*count].ci_symidx = symidx; - *count = *count + 1; - return (0); -} - -static void -ctfsrc_function(ctf_idname_t *idn) -{ - ctf_funcinfo_t *cfi = &idn->ci_funcinfo; - char name[MAX_NAMELEN] = "unknown_t"; - - (void) ctf_type_name(g_fp, cfi->ctc_return, name, sizeof (name)); - - (void) printf("extern %s %s(", name, idn->ci_name); - - if (cfi->ctc_argc != 0) { - ctfdump_fargs_grow(cfi->ctc_argc); - if (ctf_func_args(g_fp, idn->ci_symidx, - g_nfargc, g_fargc) == CTF_ERR) { - ctfdump_fatal("failed to get arguments for function " - "%s: %s\n", idn->ci_name, - ctf_errmsg(ctf_errno(g_fp))); - } - - for (size_t i = 0; i < cfi->ctc_argc; i++) { - ctf_id_t aid = g_fargc[i]; - - name[0] = '\0'; - - (void) ctf_type_name(g_fp, aid, name, sizeof (name)); - - (void) printf("%s%s", name, - i + 1 == cfi->ctc_argc ? "" : ", "); - } - } else { - if (!(cfi->ctc_flags & CTF_FUNC_VARARG)) - (void) printf("void"); - } - - if (cfi->ctc_flags & CTF_FUNC_VARARG) - (void) printf("%s...", cfi->ctc_argc == 0 ? "" : ", "); - - (void) printf(");\n"); -} - -static int -idname_compare(const void *lhs, const void *rhs) -{ - return (strcmp(((ctf_idname_t *)lhs)->ci_name, - ((ctf_idname_t *)rhs)->ci_name)); -} - -static void -ctfdump_source(void) -{ - ulong_t nr_syms = ctf_nr_syms(g_fp); - ctf_id_t max_id = ctf_max_id(g_fp); - size_t count = 0; - - (void) printf("/* Types */\n\n"); - - if ((idnames = calloc(max_id + 1, sizeof (idnames[0]))) == NULL) { - ctfdump_fatal("failed to alloc idnames: %s\n", - strerror(errno)); - } - - if (ctf_type_iter(g_fp, B_FALSE, ctfsrc_collect_types_cb, - idnames) == CTF_ERR) { - ctfdump_warn("failed to collect types: %s\n", - ctf_errmsg(ctf_errno(g_fp))); - g_exit = 1; - } - - qsort(idnames, max_id, sizeof (ctf_idname_t), idname_compare); - - for (size_t i = 0; i < max_id; i++) { - if (idnames[i].ci_id != 0) - ctfsrc_type(idnames[i].ci_id, idnames[i].ci_name); - } - - free(idnames); - - (void) printf("\n\n/* Data Objects */\n\n"); - - if ((idnames = calloc(nr_syms, sizeof (idnames[0]))) == NULL) { - ctfdump_fatal("failed to alloc idnames: %s\n", - strerror(errno)); - } - - if (ctf_object_iter(g_fp, ctfsrc_collect_objects_cb, - &count) == CTF_ERR) { - ctfdump_warn("failed to collect objects: %s\n", - ctf_errmsg(ctf_errno(g_fp))); - g_exit = 1; - } - - qsort(idnames, count, sizeof (ctf_idname_t), idname_compare); - - for (size_t i = 0; i < count; i++) - ctfsrc_object(idnames[i].ci_id, idnames[i].ci_name); - - free(idnames); - - (void) printf("\n\n/* Functions */\n\n"); - - if ((idnames = calloc(nr_syms, sizeof (idnames[0]))) == NULL) { - ctfdump_fatal("failed to alloc idnames: %s\n", - strerror(errno)); - } - - count = 0; - - if (ctf_function_iter(g_fp, ctfsrc_collect_functions_cb, - &count) == CTF_ERR) { - ctfdump_warn("failed to collect functions: %s\n", + ctfdump_warn("failed to dump labels: %s\n", ctf_errmsg(ctf_errno(g_fp))); g_exit = 1; } - - qsort(idnames, count, sizeof (ctf_idname_t), idname_compare); - - for (size_t i = 0; i < count; i++) - ctfsrc_function(&idnames[i]); - - free(idnames); } static void @@ -1076,7 +689,7 @@ ctfdump_output(const char *out) else if (ret == -1) ctfdump_fatal("failed to write to %s: %s\n", out, strerror(errno)); - data = ((char *)data) + ret; + data += ret; len -= ret; } @@ -1096,11 +709,8 @@ main(int argc, char *argv[]) const char *ufile = NULL, *parent = NULL; g_progname = basename(argv[0]); - while ((c = getopt(argc, argv, ":cdfhlp:sStu:")) != -1) { + while ((c = getopt(argc, argv, ":dfhlp:sStu:")) != -1) { switch (c) { - case 'c': - g_dump |= CTFDUMP_SOURCE; - break; case 'd': g_dump |= CTFDUMP_OBJECTS; break; @@ -1142,13 +752,8 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if ((g_dump & CTFDUMP_SOURCE) && !!(g_dump & ~CTFDUMP_SOURCE)) { - ctfdump_usage("-c must be specified on its own\n"); - return (2); - } - /* - * Dump all information except C source by default. + * Dump all information by default. */ if (g_dump == 0) g_dump = CTFDUMP_DEFAULT; @@ -1178,11 +783,6 @@ main(int argc, char *argv[]) parent, ctf_errmsg(ctf_errno(g_fp))); } - if (g_dump & CTFDUMP_SOURCE) { - ctfdump_source(); - return (0); - } - /* * If stats is set, we must run through everything exect CTFDUMP_OUTPUT. * We also do CTFDUMP_STATS last as a result. diff --git a/usr/src/cmd/mdb/Makefile.libstandctf b/usr/src/cmd/mdb/Makefile.libstandctf index 176291399c..caa621be0e 100644 --- a/usr/src/cmd/mdb/Makefile.libstandctf +++ b/usr/src/cmd/mdb/Makefile.libstandctf @@ -22,8 +22,6 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2018 Joyent, Inc. -# .KEEP_STATE: @@ -47,9 +45,6 @@ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS += -I$(SRC)/common/ctf -I../../../common -DCTF_OLD_VERSIONS -D_MDB \ -Dvsnprintf=ctf_vsnprintf -Dassfail=kmdb_prom_assfail -CSTD = $(CSTD_GNU99) -C99LMODE = -Xc99=%all - # # kmdb is a kernel module, so we'll use the kernel's build flags. CFLAGS64 += $(STAND_FLAGS_64) diff --git a/usr/src/common/ctf/ctf_types.c b/usr/src/common/ctf/ctf_types.c index 71c32f953e..2ef4f42d6b 100644 --- a/usr/src/common/ctf/ctf_types.c +++ b/usr/src/common/ctf/ctf_types.c @@ -25,7 +25,7 @@ * Use is subject to license terms. */ /* - * Copyright 2018 Joyent, Inc. + * Copyright (c) 2015, Joyent, Inc. */ #include @@ -200,91 +200,13 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type) } /* - * Format an integer type; if a vname is specified, we need to insert it prior - * to any bitfield ":24" suffix. This works out far simpler than figuring it - * out from scratch. - */ -static const char * -ctf_format_int(ctf_decl_t *cd, const char *vname, const char *qname, - const char *name) -{ - const char *c; - - if (vname == NULL) { - if (qname != NULL) - ctf_decl_sprintf(cd, "%s`%s", qname, name); - else - ctf_decl_sprintf(cd, "%s", name); - return (NULL); - } - - if ((c = strchr(name, ':')) == NULL) { - ctf_decl_sprintf(cd, "%s", name); - return (vname); - } - - /* "unsigned int mybits:23" */ - ctf_decl_sprintf(cd, "%.*s %s%s", c - name, name, vname, c); - return (NULL); -} - -static void -ctf_format_func(ctf_file_t *fp, ctf_decl_t *cd, - const char *vname, ctf_id_t id, int want_func_args) -{ - ctf_funcinfo_t fi; - /* We'll presume zone_create() is a bad example. */ - ctf_id_t args[20]; - - ctf_decl_sprintf(cd, "%s(", vname == NULL ? "" : vname); - - if (!want_func_args) - goto out; - - if (ctf_func_info_by_id(fp, id, &fi) != 0) - goto out; - - if (fi.ctc_argc > ARRAY_SIZE(args)) - fi.ctc_argc = ARRAY_SIZE(args); - - if (fi.ctc_argc == 0) { - ctf_decl_sprintf(cd, "void"); - goto out; - } - - if (ctf_func_args_by_id(fp, id, fi.ctc_argc, args) != 0) - goto out; - - for (size_t i = 0; i < fi.ctc_argc; i++) { - char aname[512]; - - if (ctf_type_name(fp, args[i], aname, sizeof (aname)) != 0) - (void) strlcpy(aname, "unknown_t", sizeof (aname)); - - ctf_decl_sprintf(cd, "%s%s", aname, - i + 1 == fi.ctc_argc ? "" : ", "); - } - - if (fi.ctc_flags & CTF_FUNC_VARARG) - ctf_decl_sprintf(cd, "%s...", fi.ctc_argc == 0 ? "" : ", "); - -out: - ctf_decl_sprintf(cd, ")"); -} - -/* - * Lookup the given type ID and print a string name for it into buf. Return the - * actual number of bytes (not including \0) needed to format the name. - * - * "vname" is an optional variable name or similar, so array suffix formatting, - * bitfields, and functions are C-correct. (This is not perfect, as can be seen - * in kiconv_ops_t.) + * Lookup the given type ID and print a string name for it into buf. Return + * the actual number of bytes (not including \0) needed to format the name. */ static ssize_t ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, - const char *vname, const char *qname) + const char *qname) { - int want_func_args = (vname != NULL); ctf_decl_t cd; ctf_decl_node_t *cdp; ctf_decl_prec_t prec, lp, rp; @@ -336,8 +258,6 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, switch (cdp->cd_kind) { case CTF_K_INTEGER: - vname = ctf_format_int(&cd, vname, qname, name); - break; case CTF_K_FLOAT: case CTF_K_TYPEDEF: if (qname != NULL) @@ -348,14 +268,10 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, ctf_decl_sprintf(&cd, "*"); break; case CTF_K_ARRAY: - ctf_decl_sprintf(&cd, "%s[%u]", - vname != NULL ? vname : "", cdp->cd_n); - vname = NULL; + ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n); break; case CTF_K_FUNCTION: - ctf_format_func(fp, &cd, vname, - cdp->cd_type, want_func_args); - vname = NULL; + ctf_decl_sprintf(&cd, "()"); break; case CTF_K_STRUCT: case CTF_K_FORWARD: @@ -390,29 +306,10 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, k = cdp->cd_kind; } - if (rp == prec) { - /* - * Peek ahead: if we're going to hit a function, - * we want to insert its name now before this closing - * bracket. - */ - if (vname != NULL && prec < CTF_PREC_FUNCTION) { - cdp = ctf_list_next( - &cd.cd_nodes[CTF_PREC_FUNCTION]); - - if (cdp != NULL) { - ctf_decl_sprintf(&cd, "%s", vname); - vname = NULL; - } - } - + if (rp == prec) ctf_decl_sprintf(&cd, ")"); - } } - if (vname != NULL) - ctf_decl_sprintf(&cd, " %s", vname); - if (cd.cd_len >= len) (void) ctf_set_errno(fp, ECTF_NAMELEN); @@ -423,7 +320,7 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, ssize_t ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - return (ctf_type_qlname(fp, type, buf, len, NULL, NULL)); + return (ctf_type_qlname(fp, type, buf, len, NULL)); } /* @@ -433,7 +330,7 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) char * ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, NULL); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL); return (rv >= 0 && rv < len ? buf : NULL); } @@ -441,17 +338,10 @@ char * ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, const char *qname) { - ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, qname); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname); return (rv >= 0 && rv < len ? buf : NULL); } -char * -ctf_type_cname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, - const char *cname) -{ - ssize_t rv = ctf_type_qlname(fp, type, buf, len, cname, NULL); - return (rv >= 0 && rv < len ? buf : NULL); -} /* * Resolve the type down to a base type node, and then return the size @@ -1295,16 +1185,3 @@ ctf_kind_name(ctf_file_t *fp, int kind) return ("unknown"); } } - -ctf_id_t -ctf_max_id(ctf_file_t *fp) -{ - int child = (fp->ctf_flags & LCTF_CHILD); - return (fp->ctf_typemax + (child ? CTF_CHILD_START : 0)); -} - -ulong_t -ctf_nr_syms(ctf_file_t *fp) -{ - return (fp->ctf_nsyms); -} diff --git a/usr/src/lib/libctf/Makefile.shared.com b/usr/src/lib/libctf/Makefile.shared.com index 3f2603a29a..55f090e7f8 100644 --- a/usr/src/lib/libctf/Makefile.shared.com +++ b/usr/src/lib/libctf/Makefile.shared.com @@ -22,7 +22,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2018 Joyent, Inc. +# Copyright (c) 2015, Joyent, Inc. All rights reserved. # # @@ -69,16 +69,16 @@ SRCS = \ $(LIB_OBJS:%.o=$(SRC)/lib/libctf/common/%.c) \ $(LIST_OBJS:%.o=$(SRC)/common/list/%.c) \ $(MERGEQ_OBJS:%.o=$(SRC)/lib/mergeq/%.c) - + LIBS = $(DYNLIB) $(LINTLIB) LDLIBS += -lc -lelf -ldwarf -lavl -CSTD = $(CSTD_GNU99) -C99LMODE = -Xc99=%all +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all SRCDIR = $(SRC)/lib/libctf/common -CPPFLAGS += -I$(SRC)/lib/libctf/common \ +CPPFLAGS += -I$(SRC)/lib/libctf/common \ -I$(SRC)/common/ctf \ -I$(SRC)/lib/libdwarf/common \ -I$(SRC)/lib/mergeq \ diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index f490c8f351..13a049d243 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -469,7 +469,7 @@ ctf_dwarf_refdie(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half name, Dwarf_Off off; Dwarf_Error derr; - if ((ret = ctf_dwarf_ref(cdp, die, name, &off)) != 0) + if ((ret = ctf_dwarf_ref(cdp, die, DW_AT_type, &off)) != 0) return (ret); off += cdp->cd_cuoff; @@ -630,17 +630,6 @@ ctf_dwarf_offset(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Off *offsetp) return (ECTF_CONVBKERR); } -/* simpler variant for debugging output */ -static Dwarf_Off -ctf_die_offset(Dwarf_Die die) -{ - Dwarf_Off off = -1; - Dwarf_Error derr; - - (void) dwarf_dieoffset(die, &off, &derr); - return (off); -} - static int ctf_dwarf_tag(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half *tagp) { @@ -1558,6 +1547,7 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) if ((ret = ctf_dwmap_add(cdp, id, die, B_FALSE)) != 0) return (ret); + if ((ret = ctf_dwarf_child(cdp, die, &child)) != 0) { if (ret == ENOENT) ret = 0; @@ -1584,35 +1574,27 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) continue; } - /* - * DWARF v4 section 5.7 tells us we'll always have names. - */ - if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, &name)) != 0) - return (ret); - - /* - * We have to be careful here: newer GCCs generate DWARF where - * an unsigned value will happily pass ctf_dwarf_signed(). - * Since negative values will fail ctf_dwarf_unsigned(), we try - * that first to make sure we get the right value. - */ - if ((ret = ctf_dwarf_unsigned(cdp, arg, DW_AT_const_value, - &uval)) == 0) { - eval = (int)uval; - } else if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, + if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, &sval)) == 0) { eval = sval; - } - - if (ret != 0) { - if (ret != ENOENT) - return (ret); - + } else if (ret != ENOENT) { + return (ret); + } else if ((ret = ctf_dwarf_unsigned(cdp, arg, + DW_AT_const_value, &uval)) == 0) { + eval = (int)uval; + } else { (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, - "encountered enumeration without constant value\n"); + "encountered enumration without constant value\n"); return (ECTF_CONVBKERR); } + /* + * DWARF v4 section 5.7 tells us we'll always have names. + */ + if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, + &name)) != 0) + return (ret); + ret = ctf_add_enumerator(cdp->cd_ctfp, id, name, eval); if (ret == CTF_ERR) { (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, @@ -2013,31 +1995,11 @@ ctf_dwarf_convert_variable(ctf_die_t *cdp, Dwarf_Die die) ctf_id_t id; ctf_dwvar_t *cdv; - /* Skip "Non-Defining Declarations" */ - if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) == 0) { - if (b != 0) - return (0); - } else if (ret != ENOENT) { - return (ret); - } - - /* - * If we find a DIE of "Declarations Completing Non-Defining - * Declarations", we will use the referenced type's DIE. This isn't - * quite correct, e.g. DW_AT_decl_line will be the forward declaration - * not this site. It's sufficient for what we need, however: in - * particular, we should find DW_AT_external as needed there. - */ - if ((ret = ctf_dwarf_refdie(cdp, die, DW_AT_specification, - &tdie)) == 0) { - Dwarf_Off offset; - if ((ret = ctf_dwarf_offset(cdp, tdie, &offset)) != 0) + if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) != 0) { + if (ret != ENOENT) return (ret); - ctf_dprintf("die 0x%llx DW_AT_specification -> die 0x%llx\n", - ctf_die_offset(die), ctf_die_offset(tdie)); - die = tdie; - } else if (ret != ENOENT) { - return (ret); + } else if (b != 0) { + return (0); } if ((ret = ctf_dwarf_string(cdp, die, DW_AT_name, &name)) != 0 && diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index f64eb407df..cfd2952bbe 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -23,7 +23,7 @@ # # -# Copyright 2018 Joyent, Inc. +# Copyright (c) 2015, Joyent, Inc. All rights reserved. # # @@ -91,7 +91,6 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_label_info; ctf_label_iter; ctf_label_topmost; - ctf_max_id; ctf_member_info; ctf_merge_add; ctf_merge_dedup; @@ -101,7 +100,6 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_merge_merge; ctf_merge_set_nthreads; ctf_merge_uniquify; - ctf_nr_syms; ctf_object_iter; ctf_parent_file; ctf_parent_label; @@ -113,7 +111,6 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_symbol_name; ctf_type_align; ctf_type_cmp; - ctf_type_cname; ctf_type_compat; ctf_type_pointer; ctf_update; diff --git a/usr/src/man/man1/ctfdump.1 b/usr/src/man/man1/ctfdump.1 index b80c856eaf..eb0fd10165 100644 --- a/usr/src/man/man1/ctfdump.1 +++ b/usr/src/man/man1/ctfdump.1 @@ -9,9 +9,9 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright 2018, Joyent, Inc. +.\" Copyright (c) 2015, Joyent, Inc. .\" -.Dd Oct 2, 2018 +.Dd Oct 4, 2014 .Dt CTFDUMP 1 .Os .Sh NAME @@ -19,7 +19,7 @@ .Nd dump parts of ctf data from files .Sh SYNOPSIS .Nm ctfdump -.Op Fl cdfhlsSt +.Op Fl dfhlsSt .Op Fl p Ar parent .Op Fl u Ar outfile .Ar file @@ -69,15 +69,9 @@ data can be inspected using and other tools such as .Xr mdb 1 . .Lp -.Nm -in -.Fl c -mode will generate C-style output, which can be used for comparison. -Note that this output is not directly compilable. -.Lp When no options are specified, .Nm -displays all information, except the C-style output. +displays all information. However, when the .Fl u option is used, then no information is displayed by default, unless @@ -85,10 +79,6 @@ requested through the appropriate option. .Sh OPTIONS The following options are supported: .Bl -hang -width Ds -.It Fl c -.Bd -filled -compact -Generate C-style output. -.Ed .It Fl d .Bd -filled -compact Dump the types of symbols that correspond to objects. @@ -417,22 +407,6 @@ $ mdb ./ctf.out cth_strlen = 0x7c9c } .Ed -.Lp -.Sy Example 3 -Dumping C-style output -.Bd -literal -offset 6n -$ ctfdump -c ./genunix | more -/* Types */ - -typedef Elf64_Addr Addr; - -typedef unsigned char Bool; - -typedef struct CK_AES_CCM_PARAMS CK_AES_CCM_PARAMS; - -typedef struct CK_AES_GCM_PARAMS CK_AES_GCM_PARAMS; -\&... -.Ed .Sh INTERFACE STABILITY The command syntax is .Sy Committed . diff --git a/usr/src/tools/ctf/common/ctf_headers.h b/usr/src/tools/ctf/common/ctf_headers.h index 7cad0d2a27..a63690be77 100644 --- a/usr/src/tools/ctf/common/ctf_headers.h +++ b/usr/src/tools/ctf/common/ctf_headers.h @@ -22,7 +22,6 @@ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2018 Joyent, Inc. */ #ifndef _CTF_HEADERS_H @@ -33,7 +32,7 @@ * the tools need to include the headers installed on the build system, * rather than those in the ON source tree. However, some of the headers * required by the tools are part of the ON source tree, but not delivered - * as part of illumos. These include the following: + * as part of Solaris. These include the following: * * $(SRC)/lib/libctf/common/libctf.h * $(SRC)/lib/libctf/common/libctf_impl.h @@ -63,14 +62,8 @@ * This last -I include is needed in order to prevent a build failure * when is included via a nested #include rather than * an explicit path #include. - * - * Finally, to make life easier, we also include the current definitions of the - * ccompile.h and sysmacros.h headers to make it so we have to rely less on the - * build system contents. */ -#include -#include #include #include #include diff --git a/usr/src/tools/ctf/ctfdump/Makefile.com b/usr/src/tools/ctf/ctfdump/Makefile.com index 66e7a170c4..3e1414ea59 100644 --- a/usr/src/tools/ctf/ctfdump/Makefile.com +++ b/usr/src/tools/ctf/ctfdump/Makefile.com @@ -8,15 +8,12 @@ # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # -# Copyright 2018 Joyent, Inc. PROG = ctfdump SRCS = ctfdump.c include ../../Makefile.ctf -CSTD = $(CSTD_GNU99) -C99LMODE = -Xc99=%all CFLAGS += $(CCVERBOSE) LDLIBS += -lctf diff --git a/usr/src/tools/ctf/libctf/Makefile.com b/usr/src/tools/ctf/libctf/Makefile.com index d932042f54..0444b975d5 100644 --- a/usr/src/tools/ctf/libctf/Makefile.com +++ b/usr/src/tools/ctf/libctf/Makefile.com @@ -10,7 +10,7 @@ # # -# Copyright 2018 Joyent, Inc. +# Copyright (c) 2015, Joyent, Inc. # include $(SRC)/lib/libctf/Makefile.shared.com @@ -24,9 +24,6 @@ LDLIBS += \ -L$(ROOTONBLDLIBMACH) \ '-R$$ORIGIN/../../lib/$(MACH)' \ -CSTD = $(CSTD_GNU99) -C99LMODE = -Xc99=%all - CPPFLAGS += -I$(SRC)/lib/libctf/common/ \ -I$(SRC)/lib/libdwarf/common/ \ -I$(SRC)/lib/mergeq \ diff --git a/usr/src/uts/common/sys/ctf.h b/usr/src/uts/common/sys/ctf.h index 2e41cf9a0e..065e985b82 100644 --- a/usr/src/uts/common/sys/ctf.h +++ b/usr/src/uts/common/sys/ctf.h @@ -22,13 +22,13 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * - * Copyright 2018 Joyent, Inc. */ #ifndef _CTF_H #define _CTF_H +#pragma ident "%Z%%M% %I% %E% SMI" + #include #ifdef __cplusplus @@ -220,13 +220,11 @@ typedef struct ctf_type { #define CTF_TYPE_NAME(stid, offset) \ (((stid) << 31) | ((offset) & 0x7fffffff)) -#define CTF_CHILD_START (0x8000) -#define CTF_TYPE_ISPARENT(id) ((id) < CTF_CHILD_START) -#define CTF_TYPE_ISCHILD(id) ((id) >= CTF_CHILD_START) +#define CTF_TYPE_ISPARENT(id) ((id) < 0x8000) +#define CTF_TYPE_ISCHILD(id) ((id) > 0x7fff) -#define CTF_TYPE_TO_INDEX(id) ((id) & (CTF_CHILD_START - 1)) -#define CTF_INDEX_TO_TYPE(id, child) \ - ((child) ? ((id) | CTF_CHILD_START) : (id)) +#define CTF_TYPE_TO_INDEX(id) ((id) & 0x7fff) +#define CTF_INDEX_TO_TYPE(id, child) ((child) ? ((id) | 0x8000) : (id)) #define CTF_PARENT_SHIFT 15 #define CTF_STRTAB_0 0 /* symbolic define for string table id 0 */ diff --git a/usr/src/uts/common/sys/ctf_api.h b/usr/src/uts/common/sys/ctf_api.h index 073cc4f0d6..bc99f67d3f 100644 --- a/usr/src/uts/common/sys/ctf_api.h +++ b/usr/src/uts/common/sys/ctf_api.h @@ -24,7 +24,7 @@ * Use is subject to license terms. */ /* - * Copyright 2018 Joyent, Inc. + * Copyright (c) 2015, Joyent, Inc. */ /* @@ -233,9 +233,6 @@ extern uint_t ctf_flags(ctf_file_t *); extern const char *ctf_errmsg(int); extern int ctf_version(int); -extern ctf_id_t ctf_max_id(ctf_file_t *); -extern ulong_t ctf_nr_syms(ctf_file_t *); - extern int ctf_func_info(ctf_file_t *, ulong_t, ctf_funcinfo_t *); extern int ctf_func_info_by_id(ctf_file_t *, ctf_id_t, ctf_funcinfo_t *); extern int ctf_func_args(ctf_file_t *, ulong_t, uint_t, ctf_id_t *); @@ -251,8 +248,6 @@ extern ssize_t ctf_type_lname(ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_name(ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_qname(ctf_file_t *, ctf_id_t, char *, size_t, const char *); -extern char *ctf_type_cname(ctf_file_t *, ctf_id_t, char *, size_t, - const char *); extern ssize_t ctf_type_size(ctf_file_t *, ctf_id_t); extern ssize_t ctf_type_align(ctf_file_t *, ctf_id_t); extern int ctf_type_kind(ctf_file_t *, ctf_id_t); diff --git a/usr/src/uts/intel/ctf/Makefile b/usr/src/uts/intel/ctf/Makefile index 97457d0c0c..207a5ff8ea 100644 --- a/usr/src/uts/intel/ctf/Makefile +++ b/usr/src/uts/intel/ctf/Makefile @@ -22,8 +22,6 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2018 Joyent, Inc. -# UTSBASE = ../.. @@ -38,8 +36,6 @@ ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) -C99LMODE= -Xc99=%all - CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS LDFLAGS += $(BREDUCE) -M$(UTSBASE)/common/ctf/mapfile -dy diff --git a/usr/src/uts/sparc/ctf/Makefile b/usr/src/uts/sparc/ctf/Makefile index 0f463684dd..bb40cd9d28 100644 --- a/usr/src/uts/sparc/ctf/Makefile +++ b/usr/src/uts/sparc/ctf/Makefile @@ -22,8 +22,6 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2018 Joyent, Inc. -# UTSBASE = ../.. @@ -38,8 +36,6 @@ ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) -C99LMODE= -Xc99=%all - CFLAGS += $(CCVERBOSE) CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS LDFLAGS += $(BREDUCE) -M$(UTSBASE)/common/ctf/mapfile -dy -- cgit v1.2.3 From f35f236324c07bf560ad6481307ea93b1261d636 Mon Sep 17 00:00:00 2001 From: John Levon Date: Fri, 28 Sep 2018 17:18:54 +0000 Subject: OS-7270 ctfconvert doesn't handle DW_AT_specification OS-7275 ctfdump could generate C-style output OS-7279 DWARF->CTF enum conversion needs to be careful of sign --- usr/src/Makefile.lint | 1 + usr/src/cmd/ctfdump/Makefile | 5 +- usr/src/cmd/ctfdump/ctfdump.c | 440 +++++++++++++++++++++++++++++++-- usr/src/cmd/mdb/Makefile.libstandctf | 5 + usr/src/common/ctf/ctf_types.c | 143 ++++++++++- usr/src/lib/libctf/Makefile.shared.com | 10 +- usr/src/lib/libctf/common/ctf_dwarf.c | 80 ++++-- usr/src/lib/libctf/common/mapfile-vers | 5 +- usr/src/man/man1/ctfdump.1 | 34 ++- usr/src/tools/ctf/common/ctf_headers.h | 13 +- usr/src/tools/ctf/ctfdump/Makefile.com | 3 + usr/src/tools/ctf/libctf/Makefile.com | 5 +- usr/src/uts/common/sys/ctf.h | 14 +- usr/src/uts/common/sys/ctf_api.h | 7 +- usr/src/uts/intel/ctf/Makefile | 4 + usr/src/uts/sparc/ctf/Makefile | 4 + 16 files changed, 702 insertions(+), 71 deletions(-) (limited to 'usr/src/uts/common/sys') diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index da55853bba..626c51d406 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -96,6 +96,7 @@ COMMON_SUBDIRS = \ cmd/cpio \ cmd/crypt \ cmd/csplit \ + cmd/ctfdump \ cmd/ctrun \ cmd/ctstat \ cmd/ctwatch \ diff --git a/usr/src/cmd/ctfdump/Makefile b/usr/src/cmd/ctfdump/Makefile index 962ca43a8f..37a1ef4cc8 100644 --- a/usr/src/cmd/ctfdump/Makefile +++ b/usr/src/cmd/ctfdump/Makefile @@ -10,7 +10,7 @@ # # -# Copyright (c) 2015, Joyent, Inc. +# Copyright 2018 Joyent, Inc. # PROG= ctfdump @@ -20,6 +20,9 @@ include ../Makefile.cmd CFLAGS += $(CCVERBOSE) LDLIBS += -lctf +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all + .KEEP_STATE: all: $(PROG) diff --git a/usr/src/cmd/ctfdump/ctfdump.c b/usr/src/cmd/ctfdump/ctfdump.c index d0ff63a02a..19245db8b4 100644 --- a/usr/src/cmd/ctfdump/ctfdump.c +++ b/usr/src/cmd/ctfdump/ctfdump.c @@ -10,7 +10,7 @@ */ /* - * Copyright (c) 2015, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. */ /* @@ -29,21 +29,25 @@ #include #include #include +#include #include #include #include +#include + +#define MAX_NAMELEN (512) typedef enum ctfdump_arg { - CTFDUMP_OBJECTS = 0x01, - CTFDUMP_FUNCTIONS = 0x02, - CTFDUMP_HEADER = 0x04, - CTFDUMP_LABELS = 0x08, - CTFDUMP_STRINGS = 0x10, - CTFDUMP_STATS = 0x20, - CTFDUMP_TYPES = 0x40, - CTFDUMP_DEFAULT = 0x7f, - CTFDUMP_OUTPUT = 0x80, - CTFDUMP_ALL = 0xff + CTFDUMP_OBJECTS = 0x001, + CTFDUMP_FUNCTIONS = 0x002, + CTFDUMP_HEADER = 0x004, + CTFDUMP_LABELS = 0x008, + CTFDUMP_STRINGS = 0x010, + CTFDUMP_STATS = 0x020, + CTFDUMP_TYPES = 0x040, + CTFDUMP_DEFAULT = 0x07f, + CTFDUMP_OUTPUT = 0x080, + CTFDUMP_SOURCE = 0x100, } ctfdump_arg_t; typedef struct ctfdump_stat { @@ -67,6 +71,14 @@ typedef struct ctfdump_stat { ulong_t cs_strmax; /* longest string */ } ctfdump_stat_t; +typedef struct { + char ci_name[MAX_NAMELEN]; + ctf_id_t ci_id; + ulong_t ci_symidx; + ctf_funcinfo_t ci_funcinfo; +} ctf_idname_t; + +static ctf_idname_t *idnames; static const char *g_progname; static ctfdump_arg_t g_dump; static ctf_file_t *g_fp; @@ -106,7 +118,7 @@ ctfdump_printf(ctfdump_arg_t arg, const char *fmt, ...) return; va_start(ap, fmt); - vfprintf(stdout, fmt, ap); + (void) vfprintf(stdout, fmt, ap); va_end(ap); } @@ -117,7 +129,7 @@ ctfdump_warn(const char *fmt, ...) (void) fprintf(stderr, "%s: ", g_progname); va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + (void) vfprintf(stderr, fmt, ap); va_end(ap); } @@ -128,7 +140,7 @@ ctfdump_fatal(const char *fmt, ...) (void) fprintf(stderr, "%s: ", g_progname); va_start(ap, fmt); - vfprintf(stderr, fmt, ap); + (void) vfprintf(stderr, fmt, ap); va_end(ap); exit(1); @@ -145,9 +157,10 @@ ctfdump_usage(const char *fmt, ...) va_end(ap); } - (void) fprintf(stderr, "Usage: %s [-dfhlsSt] [-p parent] [-u outfile] " + (void) fprintf(stderr, "Usage: %s [-cdfhlsSt] [-p parent] [-u outfile] " "file\n" "\n" + "\t-c dump C-style output\n" "\t-d dump object data\n" "\t-f dump function data\n" "\t-h dump the CTF header\n" @@ -172,6 +185,8 @@ ctfdump_title(ctfdump_arg_t arg, const char *header) static int ctfdump_objects_cb(const char *name, ctf_id_t id, ulong_t symidx, void *arg) { + _NOTE(ARGUNUSED(arg)); + int len; len = snprintf(NULL, 0, " [%u] %u", g_stats.cs_ndata, id); @@ -208,6 +223,7 @@ static int ctfdump_functions_cb(const char *name, ulong_t symidx, ctf_funcinfo_t *ctc, void *arg) { + _NOTE(ARGUNUSED(arg)); int i; if (ctc->ctc_argc != 0) { @@ -284,6 +300,7 @@ ctfdump_header(void) static int ctfdump_labels_cb(const char *name, const ctf_lblinfo_t *li, void *arg) { + _NOTE(ARGUNUSED(arg)); ctfdump_printf(CTFDUMP_LABELS, " %5lu %s\n", li->ctb_typeidx, name); return (0); } @@ -496,9 +513,10 @@ ctfdump_enum_cb(const char *name, int value, void *arg) static int ctfdump_types_cb(ctf_id_t id, boolean_t root, void *arg) { + _NOTE(ARGUNUSED(arg)); int kind, i, count; ctf_id_t ref; - char name[512], ienc[128]; + char name[MAX_NAMELEN], ienc[128]; const char *encn; ctf_funcinfo_t ctc; ctf_arinfo_t ar; @@ -662,12 +680,381 @@ ctfdump_types(void) ctfdump_title(CTFDUMP_TYPES, "Types"); if (ctf_type_iter(g_fp, B_TRUE, ctfdump_types_cb, NULL) == CTF_ERR) { - ctfdump_warn("failed to dump labels: %s\n", + ctfdump_warn("failed to dump types: %s\n", ctf_errmsg(ctf_errno(g_fp))); g_exit = 1; } } +/* + * C-style output. This is designed mainly for comparison purposes, and doesn't + * produce directly valid C: + * + * - the declarations are sorted alphabetically not semantically + * - anonymous enums without other users are elided (e.g. IDCS_PROBE_SENT) + * - doubly-pointed-to functions are wrong (e.g. in kiconv_ops_t) + * - anon unions declared within SOUs aren't expanded + * - function arguments aren't expanded recursively + */ + +static void +ctfsrc_refname(ctf_id_t id, char *buf, size_t bufsize) +{ + ctf_id_t ref; + + if ((ref = ctf_type_reference(g_fp, id)) == CTF_ERR) { + ctfdump_fatal("failed to get reference type for %ld: " + "%s\n", id, ctf_errmsg(ctf_errno(g_fp))); + } + + (void) ctf_type_name(g_fp, ref, buf, bufsize); +} + +static int +ctfsrc_member_cb(const char *member, ctf_id_t type, ulong_t off, void *arg) +{ + _NOTE(ARGUNUSED(arg)); + char name[MAX_NAMELEN]; + + if (ctf_type_cname(g_fp, type, name, sizeof (name), member) == NULL) { + if (ctf_errno(g_fp) != ECTF_NOPARENT) { + ctfdump_fatal("type %lu missing name: %s\n", type, + ctf_errmsg(ctf_errno(g_fp))); + } + + (void) snprintf(name, sizeof (name), "unknown_t %s", member); + } + + /* + * A byte offset is friendlier, but we'll print bits too if it's not + * aligned (i.e. a bitfield). + */ + if (off % NBBY != 0) { + (void) printf("\t%s; /* offset: %lu bytes (%lu bits) */\n", + name, off / NBBY, off); + } else { + (void) printf("\t%s; /* offset: %lu bytes */\n", + name, off / NBBY); + } + return (0); +} + +static int +ctfsrc_enum_cb(const char *name, int value, void *arg) +{ + _NOTE(ARGUNUSED(arg)); + (void) printf("\t%s = %d,\n", name, value); + return (0); +} + +static int +is_anon_refname(const char *refname) +{ + return ((strcmp(refname, "struct ") == 0 || + strcmp(refname, "union ") == 0 || + strcmp(refname, "enum ") == 0)); +} + +static int +ctfsrc_collect_types_cb(ctf_id_t id, boolean_t root, void *arg) +{ + _NOTE(ARGUNUSED(root, arg)); + (void) ctf_type_name(g_fp, id, idnames[id].ci_name, + sizeof (idnames[id].ci_name)); + idnames[id].ci_id = id; + return (0); +} + +static void +ctfsrc_type(ctf_id_t id, const char *name) +{ + char refname[MAX_NAMELEN]; + ctf_id_t ref; + ssize_t size; + int kind; + + if ((kind = ctf_type_kind(g_fp, id)) == CTF_ERR) { + ctfdump_fatal("encountered malformed ctf, type %s does not " + "have a kind: %s\n", name, ctf_errmsg(ctf_errno(g_fp))); + } + + switch (kind) { + case CTF_K_STRUCT: + case CTF_K_UNION: + /* + * Delay printing anonymous SOUs; a later typedef will usually + * pick them up. + */ + if (is_anon_refname(name)) + break; + + if ((size = ctf_type_size(g_fp, id)) == CTF_ERR) { + ctfdump_fatal("failed to get size of %s: %s\n", name, + ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("%s { /* 0x%x bytes */\n", name, size); + + if (ctf_member_iter(g_fp, id, ctfsrc_member_cb, NULL) != 0) { + ctfdump_fatal("failed to iterate members of %s: %s\n", + name, ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("};\n\n"); + break; + case CTF_K_ENUM: + /* + * This will throw away any anon enum that isn't followed by a + * typedef... + */ + if (is_anon_refname(name)) + break; + + (void) printf("%s {\n", name); + + if (ctf_enum_iter(g_fp, id, ctfsrc_enum_cb, NULL) != 0) { + ctfdump_fatal("failed to iterate enumerators of %s: " + "%s\n", name, ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("};\n\n"); + break; + case CTF_K_TYPEDEF: + ctfsrc_refname(id, refname, sizeof (refname)); + + if (!is_anon_refname(refname)) { + (void) ctf_type_cname(g_fp, + ctf_type_reference(g_fp, id), refname, + sizeof (refname), name); + + (void) printf("typedef %s;\n\n", refname); + break; + } + + ref = ctf_type_reference(g_fp, id); + + if (ctf_type_kind(g_fp, ref) == CTF_K_ENUM) { + (void) printf("typedef enum {\n"); + + if (ctf_enum_iter(g_fp, ref, + ctfsrc_enum_cb, NULL) != 0) { + ctfdump_fatal("failed to iterate enumerators " + "of %s: %s\n", refname, + ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("} %s;\n\n", name); + } else { + if ((size = ctf_type_size(g_fp, ref)) == CTF_ERR) { + ctfdump_fatal("failed to get size of %s: %s\n", + refname, ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("typedef %s{ /* 0x%x bytes */\n", + refname, size); + + if (ctf_member_iter(g_fp, ref, + ctfsrc_member_cb, NULL) != 0) { + ctfdump_fatal("failed to iterate members " + "of %s: %s\n", refname, + ctf_errmsg(ctf_errno(g_fp))); + } + + (void) printf("} %s;\n\n", name); + } + + break; + case CTF_K_FORWARD: + (void) printf("%s;\n\n", name); + break; + case CTF_K_UNKNOWN: + case CTF_K_INTEGER: + case CTF_K_FLOAT: + case CTF_K_POINTER: + case CTF_K_ARRAY: + case CTF_K_FUNCTION: + case CTF_K_VOLATILE: + case CTF_K_CONST: + case CTF_K_RESTRICT: + break; + default: + ctfdump_fatal("encountered unknown kind for type %s: %d\n", + name, kind); + break; + } +} + +static int +ctfsrc_collect_objects_cb(const char *name, ctf_id_t id, + ulong_t symidx, void *arg) +{ + size_t *count = arg; + + /* local static vars can have an unknown ID */ + if (id == 0) + return (0); + + (void) strlcpy(idnames[*count].ci_name, name, + sizeof (idnames[*count].ci_name)); + idnames[*count].ci_id = id; + idnames[*count].ci_symidx = symidx; + *count = *count + 1; + return (0); +} + +static void +ctfsrc_object(ctf_id_t id, const char *name) +{ + char tname[MAX_NAMELEN]; + + if (ctf_type_cname(g_fp, id, tname, sizeof (tname), name) == NULL) { + if (ctf_errno(g_fp) != ECTF_NOPARENT) { + ctfdump_fatal("type %ld missing name: %s\n", id, + ctf_errmsg(ctf_errno(g_fp))); + } + (void) snprintf(tname, sizeof (tname), "unknown_t %s", name); + } + + (void) printf("extern %s;\n", tname); +} + +static int +ctfsrc_collect_functions_cb(const char *name, ulong_t symidx, + ctf_funcinfo_t *ctc, void *arg) +{ + size_t *count = arg; + + (void) strlcpy(idnames[*count].ci_name, name, + sizeof (idnames[*count].ci_name)); + bcopy(ctc, &idnames[*count].ci_funcinfo, sizeof (*ctc)); + idnames[*count].ci_id = 0; + idnames[*count].ci_symidx = symidx; + *count = *count + 1; + return (0); +} + +static void +ctfsrc_function(ctf_idname_t *idn) +{ + ctf_funcinfo_t *cfi = &idn->ci_funcinfo; + char name[MAX_NAMELEN] = "unknown_t"; + + (void) ctf_type_name(g_fp, cfi->ctc_return, name, sizeof (name)); + + (void) printf("extern %s %s(", name, idn->ci_name); + + if (cfi->ctc_argc != 0) { + ctfdump_fargs_grow(cfi->ctc_argc); + if (ctf_func_args(g_fp, idn->ci_symidx, + g_nfargc, g_fargc) == CTF_ERR) { + ctfdump_fatal("failed to get arguments for function " + "%s: %s\n", idn->ci_name, + ctf_errmsg(ctf_errno(g_fp))); + } + + for (size_t i = 0; i < cfi->ctc_argc; i++) { + ctf_id_t aid = g_fargc[i]; + + name[0] = '\0'; + + (void) ctf_type_name(g_fp, aid, name, sizeof (name)); + + (void) printf("%s%s", name, + i + 1 == cfi->ctc_argc ? "" : ", "); + } + } else { + if (!(cfi->ctc_flags & CTF_FUNC_VARARG)) + (void) printf("void"); + } + + if (cfi->ctc_flags & CTF_FUNC_VARARG) + (void) printf("%s...", cfi->ctc_argc == 0 ? "" : ", "); + + (void) printf(");\n"); +} + +static int +idname_compare(const void *lhs, const void *rhs) +{ + return (strcmp(((ctf_idname_t *)lhs)->ci_name, + ((ctf_idname_t *)rhs)->ci_name)); +} + +static void +ctfdump_source(void) +{ + ulong_t nr_syms = ctf_nr_syms(g_fp); + ctf_id_t max_id = ctf_max_id(g_fp); + size_t count = 0; + + (void) printf("/* Types */\n\n"); + + if ((idnames = calloc(max_id + 1, sizeof (idnames[0]))) == NULL) { + ctfdump_fatal("failed to alloc idnames: %s\n", + strerror(errno)); + } + + if (ctf_type_iter(g_fp, B_FALSE, ctfsrc_collect_types_cb, + idnames) == CTF_ERR) { + ctfdump_warn("failed to collect types: %s\n", + ctf_errmsg(ctf_errno(g_fp))); + g_exit = 1; + } + + qsort(idnames, max_id, sizeof (ctf_idname_t), idname_compare); + + for (size_t i = 0; i < max_id; i++) { + if (idnames[i].ci_id != 0) + ctfsrc_type(idnames[i].ci_id, idnames[i].ci_name); + } + + free(idnames); + + (void) printf("\n\n/* Data Objects */\n\n"); + + if ((idnames = calloc(nr_syms, sizeof (idnames[0]))) == NULL) { + ctfdump_fatal("failed to alloc idnames: %s\n", + strerror(errno)); + } + + if (ctf_object_iter(g_fp, ctfsrc_collect_objects_cb, + &count) == CTF_ERR) { + ctfdump_warn("failed to collect objects: %s\n", + ctf_errmsg(ctf_errno(g_fp))); + g_exit = 1; + } + + qsort(idnames, count, sizeof (ctf_idname_t), idname_compare); + + for (size_t i = 0; i < count; i++) + ctfsrc_object(idnames[i].ci_id, idnames[i].ci_name); + + free(idnames); + + (void) printf("\n\n/* Functions */\n\n"); + + if ((idnames = calloc(nr_syms, sizeof (idnames[0]))) == NULL) { + ctfdump_fatal("failed to alloc idnames: %s\n", + strerror(errno)); + } + + count = 0; + + if (ctf_function_iter(g_fp, ctfsrc_collect_functions_cb, + &count) == CTF_ERR) { + ctfdump_warn("failed to collect functions: %s\n", + ctf_errmsg(ctf_errno(g_fp))); + g_exit = 1; + } + + qsort(idnames, count, sizeof (ctf_idname_t), idname_compare); + + for (size_t i = 0; i < count; i++) + ctfsrc_function(&idnames[i]); + + free(idnames); +} + static void ctfdump_output(const char *out) { @@ -689,7 +1076,7 @@ ctfdump_output(const char *out) else if (ret == -1) ctfdump_fatal("failed to write to %s: %s\n", out, strerror(errno)); - data += ret; + data = ((char *)data) + ret; len -= ret; } @@ -709,8 +1096,11 @@ main(int argc, char *argv[]) const char *ufile = NULL, *parent = NULL; g_progname = basename(argv[0]); - while ((c = getopt(argc, argv, ":dfhlp:sStu:")) != -1) { + while ((c = getopt(argc, argv, ":cdfhlp:sStu:")) != -1) { switch (c) { + case 'c': + g_dump |= CTFDUMP_SOURCE; + break; case 'd': g_dump |= CTFDUMP_OBJECTS; break; @@ -752,8 +1142,13 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; + if ((g_dump & CTFDUMP_SOURCE) && !!(g_dump & ~CTFDUMP_SOURCE)) { + ctfdump_usage("-c must be specified on its own\n"); + return (2); + } + /* - * Dump all information by default. + * Dump all information except C source by default. */ if (g_dump == 0) g_dump = CTFDUMP_DEFAULT; @@ -783,6 +1178,11 @@ main(int argc, char *argv[]) parent, ctf_errmsg(ctf_errno(g_fp))); } + if (g_dump & CTFDUMP_SOURCE) { + ctfdump_source(); + return (0); + } + /* * If stats is set, we must run through everything exect CTFDUMP_OUTPUT. * We also do CTFDUMP_STATS last as a result. diff --git a/usr/src/cmd/mdb/Makefile.libstandctf b/usr/src/cmd/mdb/Makefile.libstandctf index caa621be0e..176291399c 100644 --- a/usr/src/cmd/mdb/Makefile.libstandctf +++ b/usr/src/cmd/mdb/Makefile.libstandctf @@ -22,6 +22,8 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2018 Joyent, Inc. +# .KEEP_STATE: @@ -45,6 +47,9 @@ $(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG CPPFLAGS += -I$(SRC)/common/ctf -I../../../common -DCTF_OLD_VERSIONS -D_MDB \ -Dvsnprintf=ctf_vsnprintf -Dassfail=kmdb_prom_assfail +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all + # # kmdb is a kernel module, so we'll use the kernel's build flags. CFLAGS64 += $(STAND_FLAGS_64) diff --git a/usr/src/common/ctf/ctf_types.c b/usr/src/common/ctf/ctf_types.c index 2ef4f42d6b..71c32f953e 100644 --- a/usr/src/common/ctf/ctf_types.c +++ b/usr/src/common/ctf/ctf_types.c @@ -25,7 +25,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2015, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #include @@ -200,13 +200,91 @@ ctf_type_resolve(ctf_file_t *fp, ctf_id_t type) } /* - * Lookup the given type ID and print a string name for it into buf. Return - * the actual number of bytes (not including \0) needed to format the name. + * Format an integer type; if a vname is specified, we need to insert it prior + * to any bitfield ":24" suffix. This works out far simpler than figuring it + * out from scratch. + */ +static const char * +ctf_format_int(ctf_decl_t *cd, const char *vname, const char *qname, + const char *name) +{ + const char *c; + + if (vname == NULL) { + if (qname != NULL) + ctf_decl_sprintf(cd, "%s`%s", qname, name); + else + ctf_decl_sprintf(cd, "%s", name); + return (NULL); + } + + if ((c = strchr(name, ':')) == NULL) { + ctf_decl_sprintf(cd, "%s", name); + return (vname); + } + + /* "unsigned int mybits:23" */ + ctf_decl_sprintf(cd, "%.*s %s%s", c - name, name, vname, c); + return (NULL); +} + +static void +ctf_format_func(ctf_file_t *fp, ctf_decl_t *cd, + const char *vname, ctf_id_t id, int want_func_args) +{ + ctf_funcinfo_t fi; + /* We'll presume zone_create() is a bad example. */ + ctf_id_t args[20]; + + ctf_decl_sprintf(cd, "%s(", vname == NULL ? "" : vname); + + if (!want_func_args) + goto out; + + if (ctf_func_info_by_id(fp, id, &fi) != 0) + goto out; + + if (fi.ctc_argc > ARRAY_SIZE(args)) + fi.ctc_argc = ARRAY_SIZE(args); + + if (fi.ctc_argc == 0) { + ctf_decl_sprintf(cd, "void"); + goto out; + } + + if (ctf_func_args_by_id(fp, id, fi.ctc_argc, args) != 0) + goto out; + + for (size_t i = 0; i < fi.ctc_argc; i++) { + char aname[512]; + + if (ctf_type_name(fp, args[i], aname, sizeof (aname)) != 0) + (void) strlcpy(aname, "unknown_t", sizeof (aname)); + + ctf_decl_sprintf(cd, "%s%s", aname, + i + 1 == fi.ctc_argc ? "" : ", "); + } + + if (fi.ctc_flags & CTF_FUNC_VARARG) + ctf_decl_sprintf(cd, "%s...", fi.ctc_argc == 0 ? "" : ", "); + +out: + ctf_decl_sprintf(cd, ")"); +} + +/* + * Lookup the given type ID and print a string name for it into buf. Return the + * actual number of bytes (not including \0) needed to format the name. + * + * "vname" is an optional variable name or similar, so array suffix formatting, + * bitfields, and functions are C-correct. (This is not perfect, as can be seen + * in kiconv_ops_t.) */ static ssize_t ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, - const char *qname) + const char *vname, const char *qname) { + int want_func_args = (vname != NULL); ctf_decl_t cd; ctf_decl_node_t *cdp; ctf_decl_prec_t prec, lp, rp; @@ -258,6 +336,8 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, switch (cdp->cd_kind) { case CTF_K_INTEGER: + vname = ctf_format_int(&cd, vname, qname, name); + break; case CTF_K_FLOAT: case CTF_K_TYPEDEF: if (qname != NULL) @@ -268,10 +348,14 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, ctf_decl_sprintf(&cd, "*"); break; case CTF_K_ARRAY: - ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n); + ctf_decl_sprintf(&cd, "%s[%u]", + vname != NULL ? vname : "", cdp->cd_n); + vname = NULL; break; case CTF_K_FUNCTION: - ctf_decl_sprintf(&cd, "()"); + ctf_format_func(fp, &cd, vname, + cdp->cd_type, want_func_args); + vname = NULL; break; case CTF_K_STRUCT: case CTF_K_FORWARD: @@ -306,10 +390,29 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, k = cdp->cd_kind; } - if (rp == prec) + if (rp == prec) { + /* + * Peek ahead: if we're going to hit a function, + * we want to insert its name now before this closing + * bracket. + */ + if (vname != NULL && prec < CTF_PREC_FUNCTION) { + cdp = ctf_list_next( + &cd.cd_nodes[CTF_PREC_FUNCTION]); + + if (cdp != NULL) { + ctf_decl_sprintf(&cd, "%s", vname); + vname = NULL; + } + } + ctf_decl_sprintf(&cd, ")"); + } } + if (vname != NULL) + ctf_decl_sprintf(&cd, " %s", vname); + if (cd.cd_len >= len) (void) ctf_set_errno(fp, ECTF_NAMELEN); @@ -320,7 +423,7 @@ ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, ssize_t ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - return (ctf_type_qlname(fp, type, buf, len, NULL)); + return (ctf_type_qlname(fp, type, buf, len, NULL, NULL)); } /* @@ -330,7 +433,7 @@ ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) char * ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len) { - ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, NULL); return (rv >= 0 && rv < len ? buf : NULL); } @@ -338,10 +441,17 @@ char * ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, const char *qname) { - ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname); + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, qname); return (rv >= 0 && rv < len ? buf : NULL); } +char * +ctf_type_cname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len, + const char *cname) +{ + ssize_t rv = ctf_type_qlname(fp, type, buf, len, cname, NULL); + return (rv >= 0 && rv < len ? buf : NULL); +} /* * Resolve the type down to a base type node, and then return the size @@ -1185,3 +1295,16 @@ ctf_kind_name(ctf_file_t *fp, int kind) return ("unknown"); } } + +ctf_id_t +ctf_max_id(ctf_file_t *fp) +{ + int child = (fp->ctf_flags & LCTF_CHILD); + return (fp->ctf_typemax + (child ? CTF_CHILD_START : 0)); +} + +ulong_t +ctf_nr_syms(ctf_file_t *fp) +{ + return (fp->ctf_nsyms); +} diff --git a/usr/src/lib/libctf/Makefile.shared.com b/usr/src/lib/libctf/Makefile.shared.com index 55f090e7f8..3f2603a29a 100644 --- a/usr/src/lib/libctf/Makefile.shared.com +++ b/usr/src/lib/libctf/Makefile.shared.com @@ -22,7 +22,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright (c) 2015, Joyent, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # # @@ -69,16 +69,16 @@ SRCS = \ $(LIB_OBJS:%.o=$(SRC)/lib/libctf/common/%.c) \ $(LIST_OBJS:%.o=$(SRC)/common/list/%.c) \ $(MERGEQ_OBJS:%.o=$(SRC)/lib/mergeq/%.c) - + LIBS = $(DYNLIB) $(LINTLIB) LDLIBS += -lc -lelf -ldwarf -lavl -C99MODE= -xc99=%all -C99LMODE= -Xc99=%all +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all SRCDIR = $(SRC)/lib/libctf/common -CPPFLAGS += -I$(SRC)/lib/libctf/common \ +CPPFLAGS += -I$(SRC)/lib/libctf/common \ -I$(SRC)/common/ctf \ -I$(SRC)/lib/libdwarf/common \ -I$(SRC)/lib/mergeq \ diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 13a049d243..f490c8f351 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -469,7 +469,7 @@ ctf_dwarf_refdie(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half name, Dwarf_Off off; Dwarf_Error derr; - if ((ret = ctf_dwarf_ref(cdp, die, DW_AT_type, &off)) != 0) + if ((ret = ctf_dwarf_ref(cdp, die, name, &off)) != 0) return (ret); off += cdp->cd_cuoff; @@ -630,6 +630,17 @@ ctf_dwarf_offset(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Off *offsetp) return (ECTF_CONVBKERR); } +/* simpler variant for debugging output */ +static Dwarf_Off +ctf_die_offset(Dwarf_Die die) +{ + Dwarf_Off off = -1; + Dwarf_Error derr; + + (void) dwarf_dieoffset(die, &off, &derr); + return (off); +} + static int ctf_dwarf_tag(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half *tagp) { @@ -1547,7 +1558,6 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) if ((ret = ctf_dwmap_add(cdp, id, die, B_FALSE)) != 0) return (ret); - if ((ret = ctf_dwarf_child(cdp, die, &child)) != 0) { if (ret == ENOENT) ret = 0; @@ -1574,27 +1584,35 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) continue; } - if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, - &sval)) == 0) { - eval = sval; - } else if (ret != ENOENT) { + /* + * DWARF v4 section 5.7 tells us we'll always have names. + */ + if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, &name)) != 0) return (ret); - } else if ((ret = ctf_dwarf_unsigned(cdp, arg, - DW_AT_const_value, &uval)) == 0) { + + /* + * We have to be careful here: newer GCCs generate DWARF where + * an unsigned value will happily pass ctf_dwarf_signed(). + * Since negative values will fail ctf_dwarf_unsigned(), we try + * that first to make sure we get the right value. + */ + if ((ret = ctf_dwarf_unsigned(cdp, arg, DW_AT_const_value, + &uval)) == 0) { eval = (int)uval; - } else { + } else if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, + &sval)) == 0) { + eval = sval; + } + + if (ret != 0) { + if (ret != ENOENT) + return (ret); + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, - "encountered enumration without constant value\n"); + "encountered enumeration without constant value\n"); return (ECTF_CONVBKERR); } - /* - * DWARF v4 section 5.7 tells us we'll always have names. - */ - if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, - &name)) != 0) - return (ret); - ret = ctf_add_enumerator(cdp->cd_ctfp, id, name, eval); if (ret == CTF_ERR) { (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, @@ -1995,11 +2013,31 @@ ctf_dwarf_convert_variable(ctf_die_t *cdp, Dwarf_Die die) ctf_id_t id; ctf_dwvar_t *cdv; - if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) != 0) { - if (ret != ENOENT) + /* Skip "Non-Defining Declarations" */ + if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) == 0) { + if (b != 0) + return (0); + } else if (ret != ENOENT) { + return (ret); + } + + /* + * If we find a DIE of "Declarations Completing Non-Defining + * Declarations", we will use the referenced type's DIE. This isn't + * quite correct, e.g. DW_AT_decl_line will be the forward declaration + * not this site. It's sufficient for what we need, however: in + * particular, we should find DW_AT_external as needed there. + */ + if ((ret = ctf_dwarf_refdie(cdp, die, DW_AT_specification, + &tdie)) == 0) { + Dwarf_Off offset; + if ((ret = ctf_dwarf_offset(cdp, tdie, &offset)) != 0) return (ret); - } else if (b != 0) { - return (0); + ctf_dprintf("die 0x%llx DW_AT_specification -> die 0x%llx\n", + ctf_die_offset(die), ctf_die_offset(tdie)); + die = tdie; + } else if (ret != ENOENT) { + return (ret); } if ((ret = ctf_dwarf_string(cdp, die, DW_AT_name, &name)) != 0 && diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index cfd2952bbe..f64eb407df 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -23,7 +23,7 @@ # # -# Copyright (c) 2015, Joyent, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # # @@ -91,6 +91,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_label_info; ctf_label_iter; ctf_label_topmost; + ctf_max_id; ctf_member_info; ctf_merge_add; ctf_merge_dedup; @@ -100,6 +101,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_merge_merge; ctf_merge_set_nthreads; ctf_merge_uniquify; + ctf_nr_syms; ctf_object_iter; ctf_parent_file; ctf_parent_label; @@ -111,6 +113,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_symbol_name; ctf_type_align; ctf_type_cmp; + ctf_type_cname; ctf_type_compat; ctf_type_pointer; ctf_update; diff --git a/usr/src/man/man1/ctfdump.1 b/usr/src/man/man1/ctfdump.1 index eb0fd10165..b80c856eaf 100644 --- a/usr/src/man/man1/ctfdump.1 +++ b/usr/src/man/man1/ctfdump.1 @@ -9,9 +9,9 @@ .\" http://www.illumos.org/license/CDDL. .\" .\" -.\" Copyright (c) 2015, Joyent, Inc. +.\" Copyright 2018, Joyent, Inc. .\" -.Dd Oct 4, 2014 +.Dd Oct 2, 2018 .Dt CTFDUMP 1 .Os .Sh NAME @@ -19,7 +19,7 @@ .Nd dump parts of ctf data from files .Sh SYNOPSIS .Nm ctfdump -.Op Fl dfhlsSt +.Op Fl cdfhlsSt .Op Fl p Ar parent .Op Fl u Ar outfile .Ar file @@ -69,9 +69,15 @@ data can be inspected using and other tools such as .Xr mdb 1 . .Lp +.Nm +in +.Fl c +mode will generate C-style output, which can be used for comparison. +Note that this output is not directly compilable. +.Lp When no options are specified, .Nm -displays all information. +displays all information, except the C-style output. However, when the .Fl u option is used, then no information is displayed by default, unless @@ -79,6 +85,10 @@ requested through the appropriate option. .Sh OPTIONS The following options are supported: .Bl -hang -width Ds +.It Fl c +.Bd -filled -compact +Generate C-style output. +.Ed .It Fl d .Bd -filled -compact Dump the types of symbols that correspond to objects. @@ -407,6 +417,22 @@ $ mdb ./ctf.out cth_strlen = 0x7c9c } .Ed +.Lp +.Sy Example 3 +Dumping C-style output +.Bd -literal -offset 6n +$ ctfdump -c ./genunix | more +/* Types */ + +typedef Elf64_Addr Addr; + +typedef unsigned char Bool; + +typedef struct CK_AES_CCM_PARAMS CK_AES_CCM_PARAMS; + +typedef struct CK_AES_GCM_PARAMS CK_AES_GCM_PARAMS; +\&... +.Ed .Sh INTERFACE STABILITY The command syntax is .Sy Committed . diff --git a/usr/src/tools/ctf/common/ctf_headers.h b/usr/src/tools/ctf/common/ctf_headers.h index a63690be77..572fb03d4d 100644 --- a/usr/src/tools/ctf/common/ctf_headers.h +++ b/usr/src/tools/ctf/common/ctf_headers.h @@ -22,6 +22,7 @@ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2018 Joyent, Inc. */ #ifndef _CTF_HEADERS_H @@ -32,7 +33,7 @@ * the tools need to include the headers installed on the build system, * rather than those in the ON source tree. However, some of the headers * required by the tools are part of the ON source tree, but not delivered - * as part of Solaris. These include the following: + * as part of illumos. These include the following: * * $(SRC)/lib/libctf/common/libctf.h * $(SRC)/lib/libctf/common/libctf_impl.h @@ -62,12 +63,22 @@ * This last -I include is needed in order to prevent a build failure * when is included via a nested #include rather than * an explicit path #include. + * + * We'll also include the local ccompile.h - older build systems often lack + * useful definitions like __unused. Finally, we'll also define ARRAY_SIZE: + * unfortunately, older systems sysmacros.h only have this defined for the + * kernel, and we can't easily pick it up otherwise. */ +#include #include #include #include #include #include +#if !defined(ARRAY_SIZE) +#define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0])) +#endif + #endif /* _CTF_HEADERS_H */ diff --git a/usr/src/tools/ctf/ctfdump/Makefile.com b/usr/src/tools/ctf/ctfdump/Makefile.com index 3e1414ea59..66e7a170c4 100644 --- a/usr/src/tools/ctf/ctfdump/Makefile.com +++ b/usr/src/tools/ctf/ctfdump/Makefile.com @@ -8,12 +8,15 @@ # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # +# Copyright 2018 Joyent, Inc. PROG = ctfdump SRCS = ctfdump.c include ../../Makefile.ctf +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all CFLAGS += $(CCVERBOSE) LDLIBS += -lctf diff --git a/usr/src/tools/ctf/libctf/Makefile.com b/usr/src/tools/ctf/libctf/Makefile.com index 0444b975d5..d932042f54 100644 --- a/usr/src/tools/ctf/libctf/Makefile.com +++ b/usr/src/tools/ctf/libctf/Makefile.com @@ -10,7 +10,7 @@ # # -# Copyright (c) 2015, Joyent, Inc. +# Copyright 2018 Joyent, Inc. # include $(SRC)/lib/libctf/Makefile.shared.com @@ -24,6 +24,9 @@ LDLIBS += \ -L$(ROOTONBLDLIBMACH) \ '-R$$ORIGIN/../../lib/$(MACH)' \ +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all + CPPFLAGS += -I$(SRC)/lib/libctf/common/ \ -I$(SRC)/lib/libdwarf/common/ \ -I$(SRC)/lib/mergeq \ diff --git a/usr/src/uts/common/sys/ctf.h b/usr/src/uts/common/sys/ctf.h index 065e985b82..2e41cf9a0e 100644 --- a/usr/src/uts/common/sys/ctf.h +++ b/usr/src/uts/common/sys/ctf.h @@ -22,13 +22,13 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Joyent, Inc. */ #ifndef _CTF_H #define _CTF_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include #ifdef __cplusplus @@ -220,11 +220,13 @@ typedef struct ctf_type { #define CTF_TYPE_NAME(stid, offset) \ (((stid) << 31) | ((offset) & 0x7fffffff)) -#define CTF_TYPE_ISPARENT(id) ((id) < 0x8000) -#define CTF_TYPE_ISCHILD(id) ((id) > 0x7fff) +#define CTF_CHILD_START (0x8000) +#define CTF_TYPE_ISPARENT(id) ((id) < CTF_CHILD_START) +#define CTF_TYPE_ISCHILD(id) ((id) >= CTF_CHILD_START) -#define CTF_TYPE_TO_INDEX(id) ((id) & 0x7fff) -#define CTF_INDEX_TO_TYPE(id, child) ((child) ? ((id) | 0x8000) : (id)) +#define CTF_TYPE_TO_INDEX(id) ((id) & (CTF_CHILD_START - 1)) +#define CTF_INDEX_TO_TYPE(id, child) \ + ((child) ? ((id) | CTF_CHILD_START) : (id)) #define CTF_PARENT_SHIFT 15 #define CTF_STRTAB_0 0 /* symbolic define for string table id 0 */ diff --git a/usr/src/uts/common/sys/ctf_api.h b/usr/src/uts/common/sys/ctf_api.h index bc99f67d3f..073cc4f0d6 100644 --- a/usr/src/uts/common/sys/ctf_api.h +++ b/usr/src/uts/common/sys/ctf_api.h @@ -24,7 +24,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2015, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ /* @@ -233,6 +233,9 @@ extern uint_t ctf_flags(ctf_file_t *); extern const char *ctf_errmsg(int); extern int ctf_version(int); +extern ctf_id_t ctf_max_id(ctf_file_t *); +extern ulong_t ctf_nr_syms(ctf_file_t *); + extern int ctf_func_info(ctf_file_t *, ulong_t, ctf_funcinfo_t *); extern int ctf_func_info_by_id(ctf_file_t *, ctf_id_t, ctf_funcinfo_t *); extern int ctf_func_args(ctf_file_t *, ulong_t, uint_t, ctf_id_t *); @@ -248,6 +251,8 @@ extern ssize_t ctf_type_lname(ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_name(ctf_file_t *, ctf_id_t, char *, size_t); extern char *ctf_type_qname(ctf_file_t *, ctf_id_t, char *, size_t, const char *); +extern char *ctf_type_cname(ctf_file_t *, ctf_id_t, char *, size_t, + const char *); extern ssize_t ctf_type_size(ctf_file_t *, ctf_id_t); extern ssize_t ctf_type_align(ctf_file_t *, ctf_id_t); extern int ctf_type_kind(ctf_file_t *, ctf_id_t); diff --git a/usr/src/uts/intel/ctf/Makefile b/usr/src/uts/intel/ctf/Makefile index 207a5ff8ea..97457d0c0c 100644 --- a/usr/src/uts/intel/ctf/Makefile +++ b/usr/src/uts/intel/ctf/Makefile @@ -22,6 +22,8 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2018 Joyent, Inc. +# UTSBASE = ../.. @@ -36,6 +38,8 @@ ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) +C99LMODE= -Xc99=%all + CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS LDFLAGS += $(BREDUCE) -M$(UTSBASE)/common/ctf/mapfile -dy diff --git a/usr/src/uts/sparc/ctf/Makefile b/usr/src/uts/sparc/ctf/Makefile index bb40cd9d28..0f463684dd 100644 --- a/usr/src/uts/sparc/ctf/Makefile +++ b/usr/src/uts/sparc/ctf/Makefile @@ -22,6 +22,8 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2018 Joyent, Inc. +# UTSBASE = ../.. @@ -36,6 +38,8 @@ ALL_TARGET = $(BINARY) LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) +C99LMODE= -Xc99=%all + CFLAGS += $(CCVERBOSE) CPPFLAGS += -I$(SRC)/common/ctf -DCTF_OLD_VERSIONS LDFLAGS += $(BREDUCE) -M$(UTSBASE)/common/ctf/mapfile -dy -- cgit v1.2.3