From d6568790224ddff1f39c3bda859e3782887f515a Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Wed, 10 Oct 2012 19:37:49 +0100 Subject: [PATCH] ctf: DTrace-independent CTF These largely cosmetic changes remove mention of DTrace from the CTF code, making it clear that it is freely usable by non-DTrace consumers. The changes are: - dtrace_ctf.ko is now named ctf.ko, and is stored in kernel/ctf rather than kernel/dtrace, controlled by a new CONFIG_CTF Kconfig option select'ed by CONFIG_DTRACE. (CONFIG_DT_DISABLE_CTF, being largely a DTrace debugging option, remains under DTrace configure control). The function used to trigger loading of ctf.ko has changed name similarly, from dtrace_ctf_forceload() to ctf_forceload(). - The CTF section names have changed, from .dtrace_ctf.* to .ctf.* (which as a bonus is more obviously related to the .ctf directory long used to store the CTF data during the build process). - The shared CTF repository is now stored in .ctf.shared_ctf instead of .dtrace_ctf.dtrace_ctf, making its intended use somewhat clearer. These changes depend on a suitably changed libdtrace-ctf: a suitably changed userspace is needed to take advantage of them. The dtrace-kernel-interface is bumped accordingly. Signed-off-by: Nick Alcock --- Documentation/dwarf2ctf | 35 ++++++++++------------ kernel/Makefile | 1 + kernel/ctf/Kconfig | 9 ++++++ kernel/ctf/Makefile | 7 +++++ kernel/{dtrace/dtrace_ctf.c => ctf/ctf.c} | 8 ++--- kernel/dtrace/Kconfig | 3 +- kernel/dtrace/Makefile | 1 - lib/Kconfig | 4 +++ scripts/Makefile.modpost | 20 ++++++------- scripts/dwarf2ctf/dwarf2ctf.c | 36 +++++++++++------------ 10 files changed, 71 insertions(+), 53 deletions(-) create mode 100644 kernel/ctf/Kconfig create mode 100644 kernel/ctf/Makefile rename kernel/{dtrace/dtrace_ctf.c => ctf/ctf.c} (71%) diff --git a/Documentation/dwarf2ctf b/Documentation/dwarf2ctf index 0d7d2b31bc3a..750b5b619cca 100644 --- a/Documentation/dwarf2ctf +++ b/Documentation/dwarf2ctf @@ -89,9 +89,8 @@ dwarf2ctf has written out content identical to what it wrote last time it ran. These fall into several classes, partitioned according to the contents of objects.builtin and modules.builtin: - - dtrace_ctf.builtin.ctf: The shared type repository. Types shared by more - than one of the files below go here. Despite its name it is not DTrace- - specific: it is named after the library that reads and writes it, + - shared_ctf.builtin.ctf: The shared type repository. Types shared by more + than one of the files below go here. libdtrace-ctf). See 'Using dwarf2ctf output' below regarding use of this data. - vmlinux.builtin.ctf: Types in the core kernel, that cannot be built in to @@ -100,8 +99,8 @@ objects.builtin and modules.builtin: is presently built in to the kernel. - *.mod.ctf: One of these is generated for each .ko. -All the files in the first three classes are linked into the dtrace_ctf.ko -module under various names, an empty module containing nothing but CTF data. +All the files in the first three classes are linked into the ctf.ko module under +various names, an empty module containing nothing but CTF data. A lengthy section of Makefile.modpost, and a short section of the toplevel @@ -110,16 +109,15 @@ kernel modules. The dependency graph related to dwarf2ctf output is quite complex: modules and objects (ld -r'ed *.o files) are processed by dwarf2ctf to produce a number of files in the .ctf directory, and the final modules depend on the relevant ctf files. .mod.ctf's go into the .ko's with the same stem name, -but dtrace_ctf.ko receives content from all the CTF files corresponding to -built-in modules, and until dwarf2ctf runs and creates those files we cannot -tell what those CTF files will be, though we do have a wildcard that matches -them all. +but ctf.ko receives content from all the CTF files corresponding to built-in +modules, and until dwarf2ctf runs and creates those files we cannot tell what +those CTF files will be, though we do have a wildcard that matches them all. GNU Make's 'secondary expansion' feature comes to the rescue here: we can compute a list of expected CTF filenames at runtime, given the names of the modules we are linking in. For the builtin modules, we cheat and touch a stamp file after moving any .ctf.new files back over a .ctf file, then depend on that -to see if dtrace_ctf.ko needs to be relinked. +to see if ctf.ko needs to be relinked. The actual incorporation of the CTF data into the kernel modules happens before module signing (if signing is active), by calling objcopy --add-section on the @@ -144,14 +142,13 @@ Using dwarf2ctf output Using this data is fairly simple. Once you've read the CTF sections from the kernel modules and inflated them (or ignored them if they are empty or, as just mentioned, one byte long), you simply need to look at the ctf_parent_name() for -each module, and if it is set to "dtrace_ctf", call ctf_import() to set the -parent of this module to the CTF data you have read from the -.dtrace_ctf.dtrace_ctf section in the dtrace_ctf.ko kernel module. The core -kernel's types are stored in the .dtrace_ctf.vmlinux section in the same kernel -module, and all built-in kernel modules have their types in -.dtrace_ctf.$module_name. Non-built-in kernel modules just have a .dtrace_ctf -section containing their types, which again might need their parent set to -"dtrace_ctf". (Out-of- tree kernel modules will have no such parent.) +each module, and if it is set to "ctf", call ctf_import() to set the parent of +this module to the CTF data you have read from the .ctf.shared_ctf section in +the ctf.ko kernel module. The core kernel's types are stored in the +.ctf.vmlinux section in the same kernel module, and all built-in kernel modules +have their types in .ctf.$module_name. Non-built-in kernel modules just have a +.ctf section containing their types, which again might need their parent set to +"shared_ctf". (Out-of-tree kernel modules will have no such parent.) Once you've set up the parenthood relationships you can call ctf_close() on the shared type repository and forget about it entirely: it will be refcounted and @@ -381,7 +378,7 @@ The job of the duplicate detection pass is to fill out the id_to_module hash, which maps type IDs to the module they appear in, with the two special cases that types that appear only in the core kernel are said to appear in the module 'vmlinux', and types that appear in more than one module (or in a module and in -the core kernel) are said to appear in the module 'dtrace_ctf', the shared type +the core kernel) are said to appear in the module 'shared_ctf', the shared type repository. This is quite a tricky multi-pass process, because we must ensure that the shared type repository is self-contained: all types in the repository must not reference any types outside the repository. diff --git a/kernel/Makefile b/kernel/Makefile index 6e6e12873c43..70a54501c7a3 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -99,6 +99,7 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o obj-$(CONFIG_TORTURE_TEST) += torture.o obj-$(CONFIG_DTRACE) += dtrace/ +obj-$(CONFIG_CTF) += ctf/ $(obj)/configs.o: $(obj)/config_data.h diff --git a/kernel/ctf/Kconfig b/kernel/ctf/Kconfig new file mode 100644 index 000000000000..8bbad30772af --- /dev/null +++ b/kernel/ctf/Kconfig @@ -0,0 +1,9 @@ +config CTF + bool "Compact Type Format generation" + default n + help + Emit a compact, compressed description of the kernel's datatypes and + global variables into .ctf sections in kernel modules. A module + 'ctf.ko' is also generated containing type information for built-in + modules, the core kernel, and types shared across multiple kernel + modules. diff --git a/kernel/ctf/Makefile b/kernel/ctf/Makefile new file mode 100644 index 000000000000..bd73c5230b9c --- /dev/null +++ b/kernel/ctf/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Compact Type Format storage +# + +ifdef CONFIG_CTF +obj-m += ctf.o +endif diff --git a/kernel/dtrace/dtrace_ctf.c b/kernel/ctf/ctf.c similarity index 71% rename from kernel/dtrace/dtrace_ctf.c rename to kernel/ctf/ctf.c index 77ab087ed83b..c04812ab6bbc 100644 --- a/kernel/dtrace/dtrace_ctf.c +++ b/kernel/ctf/ctf.c @@ -1,5 +1,5 @@ /* - * FILE: dtrace_ctf.c + * FILE: ctf.c * DESCRIPTION: Dynamic Tracing: CTF container module * * Copyright (C) 2012 Oracle Corporation @@ -9,11 +9,11 @@ MODULE_AUTHOR("Nick Alcock "); MODULE_DESCRIPTION("CTF container module, not for modprobing"); -MODULE_VERSION("v0.1"); +MODULE_VERSION("v0.2"); MODULE_LICENSE("GPL"); -void dtrace_ctf_forceload(void) { +void ctf_forceload(void) { /* nothing doing */ } -EXPORT_SYMBOL(dtrace_ctf_forceload); +EXPORT_SYMBOL(ctf_forceload); diff --git a/kernel/dtrace/Kconfig b/kernel/dtrace/Kconfig index eb27ec4f9c9e..363f8c8406c9 100644 --- a/kernel/dtrace/Kconfig +++ b/kernel/dtrace/Kconfig @@ -1,6 +1,6 @@ # # DTrace Configuration -# Copyright (C) 2010, 2011 Oracle Corporation +# Copyright (C) 2010, 2011, 2012 Oracle Corporation # menuconfig DTRACE @@ -8,6 +8,7 @@ menuconfig DTRACE default y depends on X86_64 && !DEBUG_LOCK_ALLOC select KALLSYMS + select CTF if (!DT_DISABLE_CTF) select STRIP_ASM_SYMS if (!DT_DISABLE_CTF) select DEBUG_INFO if (!DT_DISABLE_CTF) help diff --git a/kernel/dtrace/Makefile b/kernel/dtrace/Makefile index 0e431211d88e..3c57144958b5 100644 --- a/kernel/dtrace/Makefile +++ b/kernel/dtrace/Makefile @@ -7,5 +7,4 @@ GCOV_PROFILE := y ifdef CONFIG_DT_CORE obj-y += dtrace_os.o dtrace_cpu.o \ dtrace_stubs_x86_64.o dtrace_sdt.o -obj-m += dtrace_ctf.o endif diff --git a/lib/Kconfig b/lib/Kconfig index 601965a948e8..1788f103b474 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -504,6 +504,10 @@ config SIGNATURE # config LIBFDT bool +# +# CTF support is select'ed if needed +# +source "kernel/ctf/Kconfig" config OID_REGISTRY tristate diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 06e7ea8c5d5c..28a1971d67f2 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -122,7 +122,7 @@ targets += $(modules:.ko=.mod.o) # Step 6), generate CTF for the entire kernel, or for the module alone if this # is a build of an external module. -ifdef CONFIG_DTRACE +ifdef CONFIG_CTF ifndef CONFIG_DT_DISABLE_CTF # This is quite tricky. If called for non-external-modules, dwarf2ctf needs to @@ -144,12 +144,12 @@ ctf-dir := .ctf quiet_cmd_ctf = DWARF2CTF cmd_ctf = scripts/dwarf2ctf/dwarf2ctf $(ctf-dir) objects.builtin modules.builtin scripts/dwarf2ctf/dedup.blacklist $^ builtins := $(shell cat objects.builtin 2>/dev/null) -ctf-stamp := .ctf/dtrace-ctf.stamp +ctf-stamp := .ctf/ctf.stamp -# The dtrace CTF module depends on the CTF stamp file, in lieu of the builtin +# The CTF module depends on the CTF stamp file, in lieu of the builtin # CTF files whose names we cannot determine until it is too late. -kernel/dtrace/dtrace_ctf.ko: .ctf/dtrace-ctf.stamp +kernel/ctf/ctf.ko: .ctf/ctf.stamp else ctf-dir := $(KBUILD_EXTMOD)/.ctf @@ -197,13 +197,13 @@ endif # Expands to a series of objcopy --add-section arguments to add all # necessary CTF files to a module, with appropriate section names. # We also take advantage of the opportunity to strip the guaranteed- -# useless debugging information out of dtrace_ctf.ko at the same time. +# useless debugging information out of ctf.ko at the same time. -module-ctf-flags = $(if $(filter dtrace_ctf.ko dtrace_ctf.ko.unsigned,$(notdir $@)), \ +module-ctf-flags = $(if $(filter ctf.ko ctf.ko.unsigned,$(notdir $@)), \ --strip-debug \ $(foreach builtin,$(wildcard $(ctf-dir)/*.builtin.ctf), \ - --add-section $(patsubst %.builtin.ctf,.dtrace_ctf.%,$(notdir $(builtin)))=$(builtin)), \ - --add-section .dtrace_ctf=$(ctf-module-name)) + --add-section $(patsubst %.builtin.ctf,.ctf.%,$(notdir $(builtin)))=$(builtin)), \ + --add-section .ctf=$(ctf-module-name)) # We have to put content in our dummy no-CTF files because --add-section # in binutils 2.20 silently fails if asked to add an empty file as a section. @@ -212,7 +212,7 @@ cmd_touch_ctf = @for name in $(filter $(ctf-dir)/%,$(module-ctfs-modular)); do \ test -f $$name || dd if=/dev/zero of=$$name bs=1 count=1 2>/dev/null; \ done -else +else # CONFIG_DT_DISABLE_CTF module-ctfs-modular-prereq = module-ctfs-builtin = @@ -220,7 +220,7 @@ module-ctf-flags = cmd-touch-ctf = @: endif -else +else # !CONFIG_CTF module-ctfs-modular-prereq = module-ctfs-builtin = diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index 7867e5807bad..aebd1eba9497 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -97,7 +97,7 @@ static GHashTable *id_to_module; /* * A mapping from module name to ctf_file_t *. The CTF named 'vmlinux' is the * CTF corresponding to the types in always-built-in translation units; the CTF - * named 'dtrace_ctf' (not appearing in this mapping) is the CTF corresponding + * named 'shared_ctf' (not appearing in this mapping) is the CTF corresponding * to types shared between more than one module (even between two currently- * built-in modules: we do not distinguish at this level between built-in * modules and non-built-in modules.) @@ -165,7 +165,7 @@ static void init_tu_to_modules(void); /* * Initialize a CTF type table, and possibly fill it with those special types * that appear in CTF but not in DWARF (such as 'void'). (This filling happens - * only for the type table named "dtrace_ctf", unless deduplication is turned + * only for the type table named "shared_ctf", unless deduplication is turned * off, signified by the builtin_modules list being NULL.) * * If this is a local type table, and deduplication is active, make the global @@ -718,7 +718,7 @@ static void run(int starting_argv, char *argv[], char *output_dir) init_tu_to_modules(); if (builtin_modules != NULL) - init_ctf_table("dtrace_ctf"); + init_ctf_table("shared_ctf"); scan_duplicates(starting_argv, argv); @@ -929,7 +929,7 @@ static void init_blacklist(const char *dedup_blacklist_file) /* * Initialize a CTF type table, and possibly fill it with those special types * that appear in CTF but not in DWARF (such as 'void'). (This filling happens - * only for the type table named "dtrace_ctf", unless deduplication is turned + * only for the type table named "shared_ctf", unless deduplication is turned * off, signified by the builtin_modules list being NULL.) * * If this is a local type table, and deduplication is active, make the global @@ -949,7 +949,7 @@ static ctf_file_t *init_ctf_table(const char *module_name) ctf_file); dw_ctf_trace("Initializing module: %s\n", module_name); - if ((strcmp(module_name, "dtrace_ctf") == 0) || + if ((strcmp(module_name, "shared_ctf") == 0) || (builtin_modules == NULL)) { ctf_encoding_t void_encoding = { CTF_INT_SIGNED, 0, 0 }; ctf_encoding_t int_encoding = { CTF_INT_SIGNED, 0, @@ -984,13 +984,13 @@ static ctf_file_t *init_ctf_table(const char *module_name) */ if (ctf_import(ctf_file, g_hash_table_lookup(module_to_ctf_file, - "dtrace_ctf")) < 0) { + "shared_ctf")) < 0) { fprintf(stderr, "Cannot set parent of CTF file for " "module %s: %s\n", module_name, ctf_errmsg(ctf_errno(ctf_file))); exit(1); } - ctf_parent_name_set(ctf_file, "dtrace_ctf"); + ctf_parent_name_set(ctf_file, "shared_ctf"); } dw_ctf_trace("Created CTF file for module %s: %p\n", @@ -1614,7 +1614,7 @@ static void detect_duplicates(const char *module_name, !g_hash_table_lookup_extended(dedup_blacklist, module_name, NULL, NULL))) { mark_shared(die, NULL, data); - mark_seen_contained(die, "dtrace_ctf"); + mark_seen_contained(die, "shared_ctf"); } /* @@ -1723,11 +1723,11 @@ static void mark_shared(Dwarf_Die *die, const char *id, void *data) existing_module = g_hash_table_lookup(id_to_module, id); if ((existing_module == NULL) || - (strcmp(existing_module, "dtrace_ctf") != 0)) { + (strcmp(existing_module, "shared_ctf") != 0)) { dw_ctf_trace("Marking %s as duplicate\n", id); g_hash_table_replace(id_to_module, xstrdup(id), - xstrdup("dtrace_ctf")); + xstrdup("shared_ctf")); /* * Newly-marked structures or unions must trigger a new @@ -1914,10 +1914,10 @@ static void detect_duplicates_alias_fixup_internal(Dwarf_Die *die, opaque_id); transparent_shared = ((transparent_module != NULL) && - (strcmp(transparent_module, "dtrace_ctf") == 0)); + (strcmp(transparent_module, "shared_ctf") == 0)); opaque_shared = ((opaque_module != NULL) && - (strcmp(opaque_module, "dtrace_ctf") == 0)); + (strcmp(opaque_module, "shared_ctf") == 0)); /* * Transparent type needs sharing. @@ -1939,7 +1939,7 @@ static void detect_duplicates_alias_fixup_internal(Dwarf_Die *die, if (transparent_shared && !opaque_shared) { dw_ctf_trace("Marking %s as duplicate\n", opaque_id); g_hash_table_replace(id_to_module, xstrdup(opaque_id), - xstrdup("dtrace_ctf")); + xstrdup("shared_ctf")); } free(opaque_id); @@ -2001,7 +2001,7 @@ static ctf_full_id_t *construct_ctf_id(const char *module_name, } if ((strcmp(ctf_module, module_name) != 0) && - (strcmp(ctf_module, "dtrace_ctf") != 0)) { + (strcmp(ctf_module, "shared_ctf") != 0)) { fprintf(stderr, "Internal error: within file %s, module %s, " "type at DIE offset %lx with ID %s is in a different " "non-shared module, %s.\n", file_name, module_name, @@ -2098,7 +2098,7 @@ static ctf_full_id_t *construct_ctf_id(const char *module_name, * die: The DWARF DIE. * parent_die: Its parent, i.e. if a structure member, this is a structure: if * top-level, this is a CU DIE. - * ctf: The CTF file this object should go into (possibly dtrace_ctf). + * ctf: The CTF file this object should go into (possibly shared_ctf). * parent_ctf_id: The CTF ID of the parent DIE, or -1 if none. * parent_bias: any bias applied to structure members. Normally 0, may be * nonzero for unnamed structure members. @@ -2345,7 +2345,7 @@ static ctf_id_t lookup_ctf_type(const char *module_name, const char *file_name, if ((type_ref->ctf_file != ctf) && type_ref->ctf_file != g_hash_table_lookup(module_to_ctf_file, - "dtrace_ctf")) { + "shared_ctf")) { #ifdef DEBUG fprintf(stderr, "%s: Internal error: lookup of %s found in " "different file: %s/%s versus %s/%s.\n", locerrstr, @@ -3043,7 +3043,7 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name, if ((new_type->ctf_file != ctf) && (new_type->ctf_file != g_hash_table_lookup(module_to_ctf_file, - "dtrace_ctf"))) { + "shared_ctf"))) { fprintf(stderr, "%s:%s: internal error: referenced type lookup " "for member %s yields a different CTF file: %p versus " "%p\n", locerrstr, dwarf_diename(&cu_die), @@ -3170,7 +3170,7 @@ static void write_types(char *output_dir) dw_ctf_trace("Writing out %s\n", module); - if ((strcmp(module, "dtrace_ctf") == 0) || + if ((strcmp(module, "shared_ctf") == 0) || (strcmp(module, "vmlinux") == 0)) builtin_module = 1; else { -- 2.50.1