2 // Copyright (C) 2005-2014 Red Hat Inc.
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
14 #include "translate.h"
25 #include <sys/types.h>
30 #include <sys/resource.h>
36 /* Adjust and run make_cmd to build a kernel module. */
38 run_make_cmd(systemtap_session
& s
, vector
<string
>& make_cmd
,
39 bool null_out
=false, bool null_err
=false)
41 assert_no_interrupts();
43 // PR14168: we used to unsetenv values here; instead do it via
44 // env(1) in make_any_make_cmd().
46 // Disable ccache to avoid saving files that will never be reused.
47 // (ccache is useless to us, because our compiler commands always
48 // include the randomized tmpdir path.)
49 // It's not critical if this fails, so the return is ignored.
50 (void) setenv("CCACHE_DISABLE", "1", 0);
53 make_cmd
.push_back("V=1");
54 else if (s
.verbose
> 1)
55 make_cmd
.push_back("--no-print-directory");
58 make_cmd
.push_back("-s");
59 make_cmd
.push_back("--no-print-directory");
62 // Exploit SMP parallelism, if available.
63 long smp
= sysconf(_SC_NPROCESSORS_ONLN
);
64 if (smp
<= 0) smp
= 1;
65 // PR16276: but only if we're not running severely nproc-rlimited
67 int rlimit_rc
= getrlimit(RLIMIT_NPROC
, &rlim
);
68 const unsigned int severely_limited
= smp
*30; // WAG at number of gcc+make etc. nested processes
69 bool nproc_limited
= (rlimit_rc
== 0 && (rlim
.rlim_max
<= severely_limited
||
70 rlim
.rlim_cur
<= severely_limited
));
71 if (smp
>= 1 && !nproc_limited
)
72 make_cmd
.push_back("-j" + lex_cast(smp
+1));
74 if (strverscmp (s
.kernel_base_release
.c_str(), "2.6.29") < 0)
76 // Older kernels, before linux commit #fd54f502841c1, include
77 // gratuitous "echo"s in their Makefile. We need to suppress
78 // that with this bluntness.
82 int rc
= stap_system (s
.verbose
, "kbuild", make_cmd
, null_out
, null_err
);
89 make_any_make_cmd(systemtap_session
& s
, const string
& dir
, const string
& target
)
91 vector
<string
> make_cmd
;
93 // PR14168: sanitize environment variables for kbuild invocation
94 make_cmd
.push_back("env");
95 make_cmd
.push_back("-uARCH");
96 make_cmd
.push_back("-uKBUILD_EXTMOD");
97 make_cmd
.push_back("-uCROSS_COMPILE");
98 make_cmd
.push_back("-uKBUILD_IMAGE");
99 make_cmd
.push_back("-uKCONFIG_CONFIG");
100 make_cmd
.push_back("-uINSTALL_PATH");
101 string newpath
= string("PATH=/usr/bin:/bin:") + (getenv("PATH") ?: "");
102 make_cmd
.push_back(newpath
.c_str());
104 make_cmd
.push_back("make");
105 make_cmd
.push_back("-C");
106 make_cmd
.push_back(s
.kernel_build_tree
);
107 make_cmd
.push_back("M=" + dir
); // need make-quoting?
108 make_cmd
.push_back(target
);
110 // Add architecture, except for old powerpc (RHBZ669082)
111 if (s
.architecture
!= "powerpc" ||
112 (strverscmp (s
.kernel_base_release
.c_str(), "2.6.15") >= 0))
113 make_cmd
.push_back("ARCH=" + s
.architecture
); // need make-quoting?
115 // PR13847: suppress debuginfo creation by default
116 make_cmd
.insert(make_cmd
.end(), "CONFIG_DEBUG_INFO=");
118 // Add any custom kbuild flags
119 make_cmd
.insert(make_cmd
.end(), s
.kbuildflags
.begin(), s
.kbuildflags
.end());
124 static vector
<string
>
125 make_make_cmd(systemtap_session
& s
, const string
& dir
)
127 return make_any_make_cmd(s
, dir
, "modules");
130 static vector
<string
>
131 make_make_objs_cmd(systemtap_session
& s
, const string
& dir
)
133 // Kbuild uses these rules to build external modules:
135 // module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
136 // modules: $(module-dirs)
137 // @$(kecho) ' Building modules, stage 2.';
138 // $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
140 // So if we're only interested in the stage 1 objects, we can
141 // cheat and make only the $(module-dirs) part.
142 return make_any_make_cmd(s
, dir
, "_module_" + dir
);
146 output_autoconf(systemtap_session
& s
, ofstream
& o
, const char *autoconf_c
,
147 const char *deftrue
, const char *deffalse
)
152 o
<< "if $(CHECK_BUILD) $(SYSTEMTAP_RUNTIME)/linux/" << autoconf_c
;
154 o
<< " > /dev/null 2>&1";
157 o
<< "echo \"#define " << deftrue
<< " 1\"";
159 o
<< "; else echo \"#define " << deffalse
<< " 1\"";
160 o
<< "; fi >> $@" << endl
;
164 void output_exportconf(systemtap_session
& s
, ofstream
& o
, const char *symbol
,
170 if (s
.kernel_exports
.find(symbol
) != s
.kernel_exports
.end())
171 o
<< "echo \"#define " << deftrue
<< " 1\"";
172 o
<< ">> $@" << endl
;
176 void output_dual_exportconf(systemtap_session
& s
, ofstream
& o
,
177 const char *symbol1
, const char *symbol2
,
183 if (s
.kernel_exports
.find(symbol1
) != s
.kernel_exports
.end()
184 && s
.kernel_exports
.find(symbol2
) != s
.kernel_exports
.end())
185 o
<< "echo \"#define " << deftrue
<< " 1\"";
186 o
<< ">> $@" << endl
;
190 void output_either_exportconf(systemtap_session
& s
, ofstream
& o
,
191 const char *symbol1
, const char *symbol2
,
197 if (s
.kernel_exports
.find(symbol1
) != s
.kernel_exports
.end()
198 || s
.kernel_exports
.find(symbol2
) != s
.kernel_exports
.end())
199 o
<< "echo \"#define " << deftrue
<< " 1\"";
200 o
<< ">> $@" << endl
;
205 compile_dyninst (systemtap_session
& s
)
207 const string module
= s
.tmpdir
+ "/" + s
.module_filename();
210 cmd
.push_back("gcc");
211 cmd
.push_back("--std=gnu99");
212 cmd
.push_back("-Wall");
213 cmd
.push_back("-Werror");
214 cmd
.push_back("-Wno-unused");
215 cmd
.push_back("-Wno-strict-aliasing");
217 // BZ855981/948279. Since dyninst/runtime.h includes __sync_* calls,
218 // the compiler may generate different code for it depending on -march.
219 // For example, if the default is i386, we may get references to auxiliary
220 // functions like __sync_add_and_fetch_4, which appear to be defined
221 // nowhere. We hack around this problem thusly:
222 if (s
.architecture
== "i386")
223 cmd
.push_back("-march=i586");
225 cmd
.push_back("-fvisibility=hidden");
226 cmd
.push_back("-O2");
227 cmd
.push_back("-I" + s
.runtime_path
);
228 cmd
.push_back("-D__DYNINST__");
229 for (size_t i
= 0; i
< s
.c_macros
.size(); ++i
)
230 cmd
.push_back("-D" + s
.c_macros
[i
]);
231 cmd
.push_back(s
.translated_source
);
232 cmd
.push_back("-pthread");
233 cmd
.push_back("-lrt");
234 cmd
.push_back("-fPIC");
235 cmd
.push_back("-shared");
237 cmd
.push_back(module
);
240 cmd
.push_back("-ftime-report");
244 int rc
= stap_system (s
.verbose
, cmd
);
252 compile_pass (systemtap_session
& s
)
254 if (s
.runtime_usermode_p())
255 return compile_dyninst (s
);
257 int rc
= uprobes_pass (s
);
264 // fill in a quick Makefile
265 string makefile_nm
= s
.tmpdir
+ "/Makefile";
266 ofstream
o (makefile_nm
.c_str());
270 // Clever hacks copied from vmware modules
273 superverbose
= "set -x;";
275 string redirecterrors
= "> /dev/null 2>&1";
279 // Support O= (or KBUILD_OUTPUT) option
280 o
<< "_KBUILD_CFLAGS := $(call flags,KBUILD_CFLAGS)" << endl
;
282 o
<< "stap_check_gcc = $(shell " << superverbose
<< " if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo \"$(1)\"; else echo \"$(2)\"; fi)" << endl
;
283 o
<< "CHECK_BUILD := $(CC) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CPPFLAGS) $(LINUXINCLUDE) $(_KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) $(CFLAGS) -DKBUILD_BASENAME=\\\"" << s
.module_name
<< "\\\"" << (s
.omit_werror
? "" : " -Werror") << " -S -o /dev/null -xc " << endl
;
284 o
<< "stap_check_build = $(shell " << superverbose
<< " if $(CHECK_BUILD) $(1) " << redirecterrors
<< " ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl
;
286 o
<< "SYSTEMTAP_RUNTIME = \"" << s
.runtime_path
<< "\"" << endl
;
288 // "autoconf" options go here
290 // RHBZ 543529: early rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
291 o
<< "CONFIG_MODULE_SIG := n" << endl
;
293 string module_cflags
= "EXTRA_CFLAGS";
294 o
<< module_cflags
<< " :=" << endl
;
296 // XXX: This gruesome hack is needed on some kernels built with separate O=directory,
297 // where files like 2.6.27 x86's asm/mach-*/mach_mpspec.h are not found on the cpp path.
298 // This could be a bug in arch/x86/Makefile that names
299 // mflags-y += -Iinclude/asm-x86/mach-default
300 // but that path does not exist in an O= build tree.
301 o
<< module_cflags
<< " += -Iinclude2/asm/mach-default" << endl
;
302 if (s
.kernel_source_tree
!= "")
303 o
<< module_cflags
<< " += -I" + s
.kernel_source_tree
<< endl
;
306 // o << module_cflags << " += -Iusr/include" << endl;
307 // since such headers are cleansed of _KERNEL_ pieces that we need
309 o
<< "STAPCONF_HEADER := " << s
.tmpdir
<< "/" << s
.stapconf_name
<< endl
;
310 o
<< "$(STAPCONF_HEADER):" << endl
;
311 o
<< "\t@echo -n > $@" << endl
;
312 output_autoconf(s
, o
, "autoconf-hrtimer-rel.c", "STAPCONF_HRTIMER_REL", NULL
);
313 output_autoconf(s
, o
, "autoconf-generated-compile.c", "STAPCONF_GENERATED_COMPILE", NULL
);
314 output_autoconf(s
, o
, "autoconf-hrtimer-getset-expires.c", "STAPCONF_HRTIMER_GETSET_EXPIRES", NULL
);
315 output_autoconf(s
, o
, "autoconf-inode-private.c", "STAPCONF_INODE_PRIVATE", NULL
);
316 output_autoconf(s
, o
, "autoconf-constant-tsc.c", "STAPCONF_CONSTANT_TSC", NULL
);
317 output_autoconf(s
, o
, "autoconf-ktime-get-real.c", "STAPCONF_KTIME_GET_REAL", NULL
);
318 output_autoconf(s
, o
, "autoconf-x86-uniregs.c", "STAPCONF_X86_UNIREGS", NULL
);
319 output_autoconf(s
, o
, "autoconf-nameidata.c", "STAPCONF_NAMEIDATA_CLEANUP", NULL
);
320 output_dual_exportconf(s
, o
, "unregister_kprobes", "unregister_kretprobes", "STAPCONF_UNREGISTER_KPROBES");
321 output_autoconf(s
, o
, "autoconf-kprobe-symbol-name.c", "STAPCONF_KPROBE_SYMBOL_NAME", NULL
);
322 output_autoconf(s
, o
, "autoconf-real-parent.c", "STAPCONF_REAL_PARENT", NULL
);
323 output_autoconf(s
, o
, "autoconf-uaccess.c", "STAPCONF_LINUX_UACCESS_H", NULL
);
324 output_autoconf(s
, o
, "autoconf-oneachcpu-retry.c", "STAPCONF_ONEACHCPU_RETRY", NULL
);
325 output_autoconf(s
, o
, "autoconf-dpath-path.c", "STAPCONF_DPATH_PATH", NULL
);
326 output_exportconf(s
, o
, "synchronize_kernel", "STAPCONF_SYNCHRONIZE_KERNEL");
327 output_exportconf(s
, o
, "synchronize_rcu", "STAPCONF_SYNCHRONIZE_RCU");
328 output_exportconf(s
, o
, "synchronize_sched", "STAPCONF_SYNCHRONIZE_SCHED");
329 output_autoconf(s
, o
, "autoconf-task-uid.c", "STAPCONF_TASK_UID", NULL
);
330 output_autoconf(s
, o
, "autoconf-from_kuid_munged.c", "STAPCONF_FROM_KUID_MUNGED", NULL
);
331 output_dual_exportconf(s
, o
, "alloc_vm_area", "free_vm_area", "STAPCONF_VM_AREA");
332 output_autoconf(s
, o
, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL
);
333 output_autoconf(s
, o
, "autoconf-alloc-percpu-align.c", "STAPCONF_ALLOC_PERCPU_ALIGN", NULL
);
334 output_autoconf(s
, o
, "autoconf-x86-fs.c", "STAPCONF_X86_FS", NULL
);
335 output_autoconf(s
, o
, "autoconf-x86-xfs.c", "STAPCONF_X86_XFS", NULL
);
336 output_autoconf(s
, o
, "autoconf-x86-gs.c", "STAPCONF_X86_GS", NULL
);
337 output_autoconf(s
, o
, "autoconf-grsecurity.c", "STAPCONF_GRSECURITY", NULL
);
338 output_autoconf(s
, o
, "autoconf-trace-printk.c", "STAPCONF_TRACE_PRINTK", NULL
);
339 output_autoconf(s
, o
, "autoconf-regset.c", "STAPCONF_REGSET", NULL
);
340 output_autoconf(s
, o
, "autoconf-utrace-regset.c", "STAPCONF_UTRACE_REGSET", NULL
);
341 output_autoconf(s
, o
, "autoconf-uprobe-get-pc.c", "STAPCONF_UPROBE_GET_PC", NULL
);
342 output_autoconf(s
, o
, "autoconf-hlist-4args.c", "STAPCONF_HLIST_4ARGS", NULL
);
343 output_exportconf(s
, o
, "tsc_khz", "STAPCONF_TSC_KHZ");
344 output_exportconf(s
, o
, "cpu_khz", "STAPCONF_CPU_KHZ");
345 output_exportconf(s
, o
, "__module_text_address", "STAPCONF_MODULE_TEXT_ADDRESS");
346 output_exportconf(s
, o
, "add_timer_on", "STAPCONF_ADD_TIMER_ON");
348 output_dual_exportconf(s
, o
, "probe_kernel_read", "probe_kernel_write", "STAPCONF_PROBE_KERNEL");
349 output_autoconf(s
, o
, "autoconf-hw_breakpoint_context.c",
350 "STAPCONF_HW_BREAKPOINT_CONTEXT", NULL
);
351 output_autoconf(s
, o
, "autoconf-save-stack-trace.c",
352 "STAPCONF_KERNEL_STACKTRACE", NULL
);
353 output_autoconf(s
, o
, "autoconf-save-stack-trace-no-bp.c",
354 "STAPCONF_KERNEL_STACKTRACE_NO_BP", NULL
);
355 output_autoconf(s
, o
, "autoconf-asm-syscall.c",
356 "STAPCONF_ASM_SYSCALL_H", NULL
);
357 output_autoconf(s
, o
, "autoconf-ring_buffer-flags.c", "STAPCONF_RING_BUFFER_FLAGS", NULL
);
358 output_autoconf(s
, o
, "autoconf-ring_buffer_lost_events.c", "STAPCONF_RING_BUFFER_LOST_EVENTS", NULL
);
359 output_autoconf(s
, o
, "autoconf-ring_buffer_read_prepare.c", "STAPCONF_RING_BUFFER_READ_PREPARE", NULL
);
360 output_autoconf(s
, o
, "autoconf-kallsyms-on-each-symbol.c", "STAPCONF_KALLSYMS_ON_EACH_SYMBOL", NULL
);
361 output_autoconf(s
, o
, "autoconf-walk-stack.c", "STAPCONF_WALK_STACK", NULL
);
362 output_autoconf(s
, o
, "autoconf-stacktrace_ops-warning.c",
363 "STAPCONF_STACKTRACE_OPS_WARNING", NULL
);
364 output_autoconf(s
, o
, "autoconf-mm-context-vdso.c", "STAPCONF_MM_CONTEXT_VDSO", NULL
);
365 output_autoconf(s
, o
, "autoconf-mm-context-vdso-base.c", "STAPCONF_MM_CONTEXT_VDSO_BASE", NULL
);
366 output_autoconf(s
, o
, "autoconf-blk-types.c", "STAPCONF_BLK_TYPES", NULL
);
367 output_autoconf(s
, o
, "autoconf-perf-structpid.c", "STAPCONF_PERF_STRUCTPID", NULL
);
368 output_autoconf(s
, o
, "perf_event_counter_context.c",
369 "STAPCONF_PERF_COUNTER_CONTEXT", NULL
);
370 output_autoconf(s
, o
, "perf_probe_handler_nmi.c",
371 "STAPCONF_PERF_HANDLER_NMI", NULL
);
372 output_exportconf(s
, o
, "path_lookup", "STAPCONF_PATH_LOOKUP");
373 output_exportconf(s
, o
, "kern_path_parent", "STAPCONF_KERN_PATH_PARENT");
374 output_exportconf(s
, o
, "vfs_path_lookup", "STAPCONF_VFS_PATH_LOOKUP");
375 output_exportconf(s
, o
, "kern_path", "STAPCONF_KERN_PATH");
376 output_exportconf(s
, o
, "proc_create_data", "STAPCONF_PROC_CREATE_DATA");
377 output_exportconf(s
, o
, "PDE_DATA", "STAPCONF_PDE_DATA");
378 output_autoconf(s
, o
, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL
);
380 output_autoconf(s
, o
, "autoconf-utrace-via-tracepoints.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS", NULL
);
381 output_autoconf(s
, o
, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL
);
382 output_autoconf(s
, o
, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL
);
383 output_autoconf(s
, o
, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL
);
384 output_autoconf(s
, o
, "autoconf-fs_supers-hlist.c", "STAPCONF_FS_SUPERS_HLIST", NULL
);
385 output_autoconf(s
, o
, "autoconf-compat_sigaction.c", "STAPCONF_COMPAT_SIGACTION", NULL
);
386 output_autoconf(s
, o
, "autoconf-netfilter.c", "STAPCONF_NETFILTER_V313", NULL
);
387 output_autoconf(s
, o
, "autoconf-netfilter-4_1.c", "STAPCONF_NETFILTER_V41", NULL
);
388 output_autoconf(s
, o
, "autoconf-smpcall-5args.c", "STAPCONF_SMPCALL_5ARGS", NULL
);
389 output_autoconf(s
, o
, "autoconf-smpcall-4args.c", "STAPCONF_SMPCALL_4ARGS", NULL
);
391 // used by tapset/timestamp_monotonic.stp
392 output_exportconf(s
, o
, "cpu_clock", "STAPCONF_CPU_CLOCK");
393 output_exportconf(s
, o
, "local_clock", "STAPCONF_LOCAL_CLOCK");
395 // used by runtime/uprobe-inode.c
396 output_either_exportconf(s
, o
, "uprobe_register", "register_uprobe",
397 "STAPCONF_UPROBE_REGISTER_EXPORTED");
398 output_either_exportconf(s
, o
, "uprobe_unregister", "unregister_uprobe",
399 "STAPCONF_UPROBE_UNREGISTER_EXPORTED");
400 output_autoconf(s
, o
, "autoconf-old-inode-uprobes.c", "STAPCONF_OLD_INODE_UPROBES", NULL
);
401 output_autoconf(s
, o
, "autoconf-inode-uretprobes.c", "STAPCONF_INODE_URETPROBES", NULL
);
403 // used by tapsets.cxx inode uprobe generated code
404 output_exportconf(s
, o
, "uprobe_get_swbp_addr", "STAPCONF_UPROBE_GET_SWBP_ADDR_EXPORTED");
406 // used by runtime/loc2c-runtime.h
407 output_exportconf(s
, o
, "task_user_regset_view", "STAPCONF_TASK_USER_REGSET_VIEW_EXPORTED");
409 // used by runtime/stp_utrace.c
410 output_exportconf(s
, o
, "task_work_add", "STAPCONF_TASK_WORK_ADD_EXPORTED");
411 output_exportconf(s
, o
, "wake_up_state", "STAPCONF_WAKE_UP_STATE_EXPORTED");
412 output_exportconf(s
, o
, "try_to_wake_up", "STAPCONF_TRY_TO_WAKE_UP_EXPORTED");
413 output_exportconf(s
, o
, "signal_wake_up_state", "STAPCONF_SIGNAL_WAKE_UP_STATE_EXPORTED");
414 output_exportconf(s
, o
, "signal_wake_up", "STAPCONF_SIGNAL_WAKE_UP_EXPORTED");
415 output_exportconf(s
, o
, "__lock_task_sighand", "STAPCONF___LOCK_TASK_SIGHAND_EXPORTED");
417 output_autoconf(s
, o
, "autoconf-pagefault_disable.c", "STAPCONF_PAGEFAULT_DISABLE", NULL
);
418 output_exportconf(s
, o
, "kallsyms_lookup_name", "STAPCONF_KALLSYMS");
419 output_autoconf(s
, o
, "autoconf-uidgid.c", "STAPCONF_LINUX_UIDGID_H", NULL
);
420 output_exportconf(s
, o
, "sigset_from_compat", "STAPCONF_SIGSET_FROM_COMPAT_EXPORTED");
421 output_exportconf(s
, o
, "vzalloc", "STAPCONF_VZALLOC");
422 output_exportconf(s
, o
, "vzalloc_node", "STAPCONF_VZALLOC_NODE");
423 output_exportconf(s
, o
, "vmalloc_node", "STAPCONF_VMALLOC_NODE");
425 output_autoconf(s
, o
, "autoconf-tracepoint-strings.c", "STAPCONF_TRACEPOINT_STRINGS", NULL
);
426 output_autoconf(s
, o
, "autoconf-timerfd.c", "STAPCONF_TIMERFD_H", NULL
);
428 o
<< module_cflags
<< " += -include $(STAPCONF_HEADER)" << endl
;
430 for (unsigned i
=0; i
<s
.c_macros
.size(); i
++)
431 o
<< "EXTRA_CFLAGS += -D " << lex_cast_qstring(s
.c_macros
[i
]) << endl
; // XXX right quoting?
434 o
<< "EXTRA_CFLAGS += -ftime-report -Q" << endl
;
436 // XXX: unfortunately, -save-temps can't work since linux kbuild cwd
439 // if (s.keep_tmpdir)
440 // o << "CFLAGS += -fverbose-asm -save-temps" << endl;
442 // Kernels can be compiled with CONFIG_CC_OPTIMIZE_FOR_SIZE to select
443 // -Os, otherwise -O2 is the default.
444 o
<< "EXTRA_CFLAGS += -freorder-blocks" << endl
; // improve on -Os
446 // Generate eh_frame for self-backtracing
447 o
<< "EXTRA_CFLAGS += -fasynchronous-unwind-tables" << endl
;
449 // We used to allow the user to override default optimization when so
450 // requested by adding a -O[0123s] so they could determine the
451 // time/space/speed tradeoffs themselves, but we cannot guantantee that
452 // the (un)optimized code actually compiles and/or generates functional
453 // code, so we had to remove it.
454 // o << "EXTRA_CFLAGS += " << s.gcc_flags << endl; // Add -O[0123s]
456 // o << "CFLAGS += -fno-unit-at-a-time" << endl;
458 // 256^W512 bytes should be enough for anybody
459 // XXX this doesn't validate varargs, per gcc bug #41633
460 o
<< "EXTRA_CFLAGS += $(call cc-option,-Wframe-larger-than=512)" << endl
;
462 // gcc 5.0.0-0.13.fc23 ipa-icf seems to consume gigacpu on stap-generated code
463 o
<< "EXTRA_CFLAGS += $(call cc-option,-fno-ipa-icf)" << endl
;
465 // Assumes linux 2.6 kbuild
466 o
<< "EXTRA_CFLAGS += -Wno-unused" << (s
.omit_werror
? "" : " -Werror") << endl
;
467 #if CHECK_POINTER_ARITH_PR5947
468 o
<< "EXTRA_CFLAGS += -Wpointer-arith" << endl
;
470 o
<< "EXTRA_CFLAGS += -I\"" << s
.runtime_path
<< "\"" << endl
;
471 // XXX: this may help ppc toc overflow
472 // o << "CFLAGS := $(subst -Os,-O2,$(CFLAGS)) -fminimal-toc" << endl;
473 o
<< "obj-m := " << s
.module_name
<< ".o" << endl
;
475 // print out all the auxiliary source (->object) file names
476 o
<< s
.module_name
<< "-y := ";
477 for (unsigned i
=0; i
<s
.auxiliary_outputs
.size(); i
++)
479 if (s
.auxiliary_outputs
[i
]->trailer_p
) continue;
480 string srcname
= s
.auxiliary_outputs
[i
]->filename
;
481 assert (srcname
!= "" && srcname
.rfind('/') != string::npos
);
482 string objname
= srcname
.substr(srcname
.rfind('/')+1); // basename
483 assert (objname
!= "" && objname
[objname
.size()-1] == 'c');
484 objname
[objname
.size()-1] = 'o'; // now objname
487 // and once again, for the translated_source file. It can't simply
488 // be named MODULENAME.c, since kbuild doesn't allow a foo.ko file
489 // consisting of multiple .o's to have foo.o/foo.c as a source.
490 // (It uses ld -r -o foo.o EACH.o EACH.o).
492 string srcname
= s
.translated_source
;
493 assert (srcname
!= "" && srcname
.rfind('/') != string::npos
);
494 string objname
= srcname
.substr(srcname
.rfind('/')+1); // basename
495 assert (objname
!= "" && objname
[objname
.size()-1] == 'c');
496 objname
[objname
.size()-1] = 'o'; // now objname
499 // and once again, for the trailer type auxiliary outputs.
500 for (unsigned i
=0; i
<s
.auxiliary_outputs
.size(); i
++)
502 if (! s
.auxiliary_outputs
[i
]->trailer_p
) continue;
503 string srcname
= s
.auxiliary_outputs
[i
]->filename
;
504 assert (srcname
!= "" && srcname
.rfind('/') != string::npos
);
505 string objname
= srcname
.substr(srcname
.rfind('/')+1); // basename
506 assert (objname
!= "" && objname
[objname
.size()-1] == 'c');
507 objname
[objname
.size()-1] = 'o'; // now objname
512 // add all stapconf dependencies
513 o
<< s
.translated_source
<< ": $(STAPCONF_HEADER)" << endl
;
514 for (unsigned i
=0; i
<s
.auxiliary_outputs
.size(); i
++)
515 o
<< s
.auxiliary_outputs
[i
]->filename
<< ": $(STAPCONF_HEADER)" << endl
;
520 // Generate module directory pathname and make sure it exists.
521 string module_dir
= s
.kernel_build_tree
;
522 string module_dir_makefile
= module_dir
+ "/Makefile";
524 rc
= stat(module_dir_makefile
.c_str(), &st
);
527 clog
<< _F("Checking \" %s \" failed with error: %s\nEnsure kernel development headers & makefiles are installed.",
528 module_dir_makefile
.c_str(), strerror(errno
)) << endl
;
534 vector
<string
> make_cmd
= make_make_cmd(s
, s
.tmpdir
);
535 rc
= run_make_cmd(s
, make_cmd
);
542 * If uprobes was built as part of the kernel build (either built-in
543 * or as a module), the uprobes exports should show up. This is to be
544 * as distinct from the stap-built uprobes.ko from the runtime.
547 kernel_built_uprobes (systemtap_session
& s
)
549 if (s
.runtime_usermode_p())
550 return true; // sort of, via dyninst
552 // see also tapsets.cxx:kernel_supports_inode_uprobes()
553 return ((s
.kernel_config
["CONFIG_ARCH_SUPPORTS_UPROBES"] == "y" && s
.kernel_config
["CONFIG_UPROBES"] == "y") ||
554 (s
.kernel_exports
.find("unregister_uprobe") != s
.kernel_exports
.end()));
558 make_uprobes (systemtap_session
& s
)
561 clog
<< _("Pass 4, preamble: (re)building SystemTap's version of uprobes.")
564 // create a subdirectory for the uprobes module
565 string
dir(s
.tmpdir
+ "/uprobes");
566 if (create_dir(dir
.c_str()) != 0)
568 s
.print_warning("failed to create directory for build uprobes.");
573 // create a simple Makefile
574 string
makefile(dir
+ "/Makefile");
575 ofstream
omf(makefile
.c_str());
576 omf
<< "obj-m := uprobes.o" << endl
;
577 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
578 omf
<< "CONFIG_MODULE_SIG := n" << endl
;
581 // create a simple #include-chained source file
582 string
runtimesourcefile(s
.runtime_path
+ "/linux/uprobes/uprobes.c");
583 string
sourcefile(dir
+ "/uprobes.c");
584 ofstream
osrc(sourcefile
.c_str());
585 osrc
<< "#include \"" << runtimesourcefile
<< "\"" << endl
;
587 // pass --modinfo k=v to uprobes build too
588 for (unsigned i
= 0; i
< s
.modinfos
.size(); i
++)
590 const string
& mi
= s
.modinfos
[i
];
591 size_t loc
= mi
.find('=');
592 string tag
= mi
.substr (0, loc
);
593 string value
= mi
.substr (loc
+1);
594 osrc
<< "MODULE_INFO(" << tag
<< "," << lex_cast_qstring(value
) << ");" << endl
;
600 vector
<string
> make_cmd
= make_make_cmd(s
, dir
);
601 int rc
= run_make_cmd(s
, make_cmd
);
602 if (!rc
&& !copy_file(dir
+ "/Module.symvers",
603 s
.tmpdir
+ "/Module.symvers"))
607 clog
<< _("uprobes rebuild exit code: ") << rc
<< endl
;
611 s
.uprobes_path
= dir
+ "/uprobes.ko";
616 get_cached_uprobes(systemtap_session
& s
)
618 s
.uprobes_hash
= s
.use_cache
? find_uprobes_hash(s
) : "";
619 if (!s
.uprobes_hash
.empty())
621 // NB: We always put uprobes.ko in its own directory, especially so
622 // stap-serverd can more easily locate it.
623 string
dir(s
.tmpdir
+ "/uprobes");
624 if (create_dir(dir
.c_str()) != 0)
627 string cacheko
= s
.uprobes_hash
+ ".ko";
628 string tmpko
= dir
+ "/uprobes.ko";
630 // The symvers file still needs to go in the script module's directory.
631 string cachesyms
= s
.uprobes_hash
+ ".symvers";
632 string tmpsyms
= s
.tmpdir
+ "/Module.symvers";
634 if (get_file_size(cacheko
) > 0 && copy_file(cacheko
, tmpko
) &&
635 get_file_size(cachesyms
) > 0 && copy_file(cachesyms
, tmpsyms
))
637 s
.uprobes_path
= tmpko
;
645 set_cached_uprobes(systemtap_session
& s
)
647 if (s
.use_cache
&& !s
.uprobes_hash
.empty())
649 string cacheko
= s
.uprobes_hash
+ ".ko";
650 string tmpko
= s
.tmpdir
+ "/uprobes/uprobes.ko";
651 copy_file(tmpko
, cacheko
);
653 string cachesyms
= s
.uprobes_hash
+ ".symvers";
654 string tmpsyms
= s
.tmpdir
+ "/uprobes/Module.symvers";
655 copy_file(tmpsyms
, cachesyms
);
660 uprobes_pass (systemtap_session
& s
)
662 if (!s
.need_uprobes
|| kernel_built_uprobes(s
))
665 if (s
.kernel_config
["CONFIG_UTRACE"] != string("y"))
667 clog
<< _("user-space process-tracking facilities not available [man error::process-tracking]") << endl
;
673 * We need to use the version of uprobes that comes with SystemTap. Try to
674 * get it from the cache first. If not found, build it and try to save it to
675 * the cache for future reuse.
678 if (!get_cached_uprobes(s
))
680 rc
= make_uprobes(s
);
682 set_cached_uprobes(s
);
691 make_dyninst_run_command (systemtap_session
& s
, const string
& remotedir
,
692 const string
& version
)
695 cmd
.push_back(getenv("SYSTEMTAP_STAPDYN") ?: BINDIR
"/stapdyn");
697 // use slightly less verbosity
698 for (unsigned i
=1; i
<s
.verbose
; i
++)
700 if (s
.suppress_warnings
)
706 cmd
.push_back(s
.cmd
);
712 cmd
.push_back(lex_cast(s
.target_pid
));
715 if (!s
.output_file
.empty())
718 cmd
.push_back(s
.output_file
);
721 if (s
.color_mode
!= s
.color_auto
)
724 if (s
.color_mode
== s
.color_always
)
725 cmd
.push_back("always");
727 cmd
.push_back("never");
730 cmd
.push_back((remotedir
.empty() ? s
.tmpdir
: remotedir
)
731 + "/" + s
.module_filename());
733 // add module arguments
734 cmd
.insert(cmd
.end(), s
.globalopts
.begin(), s
.globalopts
.end());
740 make_run_command (systemtap_session
& s
, const string
& remotedir
,
741 const string
& version
)
743 if (s
.runtime_usermode_p())
744 return make_dyninst_run_command(s
, remotedir
, version
);
746 // for now, just spawn staprun
747 vector
<string
> staprun_cmd
;
748 staprun_cmd
.push_back(getenv("SYSTEMTAP_STAPRUN") ?: BINDIR
"/staprun");
750 // use slightly less verbosity
751 for (unsigned i
=1; i
<s
.verbose
; i
++)
752 staprun_cmd
.push_back("-v");
753 if (s
.suppress_warnings
)
754 staprun_cmd
.push_back("-w");
756 if (!s
.output_file
.empty())
758 staprun_cmd
.push_back("-o");
759 staprun_cmd
.push_back(s
.output_file
);
764 staprun_cmd
.push_back("-c");
765 staprun_cmd
.push_back(s
.cmd
);
770 staprun_cmd
.push_back("-t");
771 staprun_cmd
.push_back(lex_cast(s
.target_pid
));
776 staprun_cmd
.push_back("-b");
777 staprun_cmd
.push_back(lex_cast(s
.buffer_size
));
780 if (s
.need_uprobes
&& !kernel_built_uprobes(s
))
783 if (!s
.uprobes_path
.empty() &&
784 strverscmp("1.4", version
.c_str()) <= 0)
786 if (remotedir
.empty())
787 opt_u
.append(s
.uprobes_path
);
789 opt_u
.append(remotedir
+ "/" + basename(s
.uprobes_path
.c_str()));
791 staprun_cmd
.push_back(opt_u
);
795 staprun_cmd
.push_back(s
.output_file
.empty() ? "-L" : "-D");
797 // Note that if this system requires signed modules, we can't rename
798 // it after it has been signed.
799 if (!s
.modname_given
&& (strverscmp("1.6", version
.c_str()) <= 0)
800 && s
.mok_fingerprints
.empty())
801 staprun_cmd
.push_back("-R");
803 if (!s
.size_option
.empty())
805 staprun_cmd
.push_back("-S");
806 staprun_cmd
.push_back(s
.size_option
);
809 if (s
.color_mode
!= s
.color_auto
)
811 staprun_cmd
.push_back("-C");
812 if (s
.color_mode
== s
.color_always
)
813 staprun_cmd
.push_back("always");
815 staprun_cmd
.push_back("never");
818 staprun_cmd
.push_back((remotedir
.empty() ? s
.tmpdir
: remotedir
)
819 + "/" + s
.module_filename());
821 // add module arguments
822 staprun_cmd
.insert(staprun_cmd
.end(),
823 s
.globalopts
.begin(), s
.globalopts
.end());
829 // Build tiny kernel modules to query tracepoints.
830 // Given a (header-file -> test-contents) map, compile them ASAP, and return
831 // a (header-file -> obj-filename) map.
834 make_tracequeries(systemtap_session
& s
, const map
<string
,string
>& contents
)
836 static unsigned tick
= 0;
837 string
basename("tracequery_kmod_" + lex_cast(++tick
));
838 map
<string
,string
> objs
;
840 // create a subdirectory for the module
841 string
dir(s
.tmpdir
+ "/" + basename
);
842 if (create_dir(dir
.c_str()) != 0)
844 s
.print_warning("failed to create directory for querying tracepoints.");
849 // create a simple Makefile
850 string
makefile(dir
+ "/Makefile");
851 ofstream
omf(makefile
.c_str());
852 // force debuginfo generation, and relax implicit functions
853 omf
<< "EXTRA_CFLAGS := -g -Wno-implicit-function-declaration" << (s
.omit_werror
? "" : " -Werror") << endl
;
854 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
855 omf
<< "CONFIG_MODULE_SIG := n" << endl
;
857 // PR18389: disable GCC's Identical Code Folding, since the stubs may look identical
858 omf
<< "EXTRA_CFLAGS += $(call cc-option,-fno-ipa-icf)" << endl
;
860 if (s
.kernel_source_tree
!= "")
861 omf
<< "EXTRA_CFLAGS += -I" + s
.kernel_source_tree
<< endl
;
863 omf
<< "obj-m := " << endl
;
864 // write out each header-specific source file into a separate file
865 for (map
<string
,string
>::const_iterator it
= contents
.begin(); it
!= contents
.end(); it
++)
867 string sbasename
= basename
+ "_" + lex_cast(++tick
); // suffixed
869 // write out source code
870 string srcname
= dir
+ "/" + sbasename
+ ".c";
871 string src
= it
->second
;
872 ofstream
osrc(srcname
.c_str());
877 clog
<< _F("Processing tracepoint header %s with query %s",
878 it
->first
.c_str(), srcname
.c_str())
881 // arrange to build it
882 omf
<< "obj-m += " + sbasename
+ ".o" << endl
; // NB: without <dir> prefix
883 objs
[it
->first
] = dir
+ "/" + sbasename
+ ".o";
888 vector
<string
> make_cmd
= make_make_objs_cmd(s
, dir
);
889 make_cmd
.push_back ("-i"); // ignore errors, give rc 0 even in case of tracepoint header nits
890 bool quiet
= (s
.verbose
< 4);
891 int rc
= run_make_cmd(s
, make_cmd
, quiet
, quiet
);
895 // Sometimes we fail a tracequery due to PR9993 / PR11649 type
896 // kernel trace header problems. In this case, due to PR12729, we
897 // used to get a lovely "Warning: make exited with status: 2" but no
898 // other useful diagnostic. -vvvv would let a user see what's up,
899 // but the user can't fix the problem even with that.
905 // Build a tiny kernel module to query type information
907 make_typequery_kmod(systemtap_session
& s
, const vector
<string
>& headers
, string
& name
)
909 static unsigned tick
= 0;
910 string
basename("typequery_kmod_" + lex_cast(++tick
));
912 // create a subdirectory for the module
913 string
dir(s
.tmpdir
+ "/" + basename
);
914 if (create_dir(dir
.c_str()) != 0)
916 s
.print_warning("failed to create directory for querying types.");
921 name
= dir
+ "/" + basename
+ ".ko";
923 // create a simple Makefile
924 string
makefile(dir
+ "/Makefile");
925 ofstream
omf(makefile
.c_str());
926 omf
<< "EXTRA_CFLAGS := -g -fno-eliminate-unused-debug-types" << endl
;
928 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
929 omf
<< "CONFIG_MODULE_SIG := n" << endl
;
931 // NB: We use -include instead of #include because that gives us more power.
932 // Using #include searches relative to the source's path, which in this case
933 // is /tmp/..., so that's not helpful. Using -include will search relative
934 // to the cwd, which will be the kernel build root. This means if you have a
935 // full kernel build tree, it's possible to get at types that aren't in the
936 // normal include path, e.g.:
937 // @cast(foo, "bsd_acct_struct", "kernel<kernel/acct.c>")->...
938 omf
<< "CFLAGS_" << basename
<< ".o :=";
939 for (size_t i
= 0; i
< headers
.size(); ++i
)
940 omf
<< " -include " << lex_cast_qstring(headers
[i
]); // XXX right quoting?
943 omf
<< "obj-m := " + basename
+ ".o" << endl
;
946 // create our empty source file
947 string
source(dir
+ "/" + basename
+ ".c");
948 ofstream
osrc(source
.c_str());
952 vector
<string
> make_cmd
= make_make_cmd(s
, dir
);
953 bool quiet
= (s
.verbose
< 4);
954 int rc
= run_make_cmd(s
, make_cmd
, quiet
, quiet
);
961 // Build a tiny user module to query type information
963 make_typequery_umod(systemtap_session
& s
, const vector
<string
>& headers
, string
& name
)
965 static unsigned tick
= 0;
967 name
= s
.tmpdir
+ "/typequery_umod_" + lex_cast(++tick
) + ".so";
971 // NB: As with kmod, using -include makes relative paths more useful. The
972 // cwd in this case will be the cwd of stap itself though, which may be
973 // trickier to deal with. It might be better to "cd `dirname $script`"
976 cmd
.push_back("gcc");
977 cmd
.push_back("-shared");
979 cmd
.push_back("-fno-eliminate-unused-debug-types");
980 cmd
.push_back("-xc");
981 cmd
.push_back("/dev/null");
984 for (size_t i
= 0; i
< headers
.size(); ++i
)
986 cmd
.push_back("-include");
987 cmd
.push_back(headers
[i
]);
989 bool quiet
= (s
.verbose
< 4);
990 int rc
= stap_system (s
.verbose
, cmd
, quiet
, quiet
);
998 make_typequery(systemtap_session
& s
, string
& module
)
1002 vector
<string
> headers
;
1003 bool kernel
= startswith(module
, "kernel");
1005 for (size_t end
, i
= kernel
? 6 : 0; i
< module
.size(); i
= end
+ 1)
1007 if (module
[i
] != '<')
1009 end
= module
.find('>', ++i
);
1010 if (end
== string::npos
)
1012 string header
= module
.substr(i
, end
- i
);
1013 vector
<string
> matches
;
1014 if (regexp_match(header
, "^[a-zA-Z0-9/_.+-]+$", matches
))
1015 s
.print_warning("skipping malformed @cast header \""+ header
+ "\"");
1017 headers
.push_back(header
);
1019 if (headers
.empty())
1023 rc
= make_typequery_kmod(s
, headers
, new_module
);
1025 rc
= make_typequery_umod(s
, headers
, new_module
);
1028 module
= new_module
;
1033 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */