]> sourceware.org Git - systemtap.git/blob - buildrun.cxx
b541b45ef4af69d333625b08a843ebdc4b098618
[systemtap.git] / buildrun.cxx
1 // build/run probes
2 // Copyright (C) 2005-2016 Red Hat Inc.
3 //
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
7 // later version.
8
9 #include "config.h"
10 #include "buildrun.h"
11 #include "session.h"
12 #include "util.h"
13 #include "hash.h"
14 #include "translate.h"
15
16 #include <cstdlib>
17 #include <fstream>
18 #include <sstream>
19
20 extern "C" {
21 #include <signal.h>
22 #include <sys/wait.h>
23 #include <pwd.h>
24 #include <grp.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <sys/resource.h>
31 }
32
33 // A bit of obfuscation for Gentoo's sake.
34 // We *need* -Werror for stapconf to work correctly.
35 // https://bugs.gentoo.org/show_bug.cgi?id=522908
36 #define WERROR ("-W" "error")
37
38 using namespace std;
39
40 /* Adjust and run make_cmd to build a kernel module. */
41 static int
42 run_make_cmd(systemtap_session& s, vector<string>& make_cmd,
43 bool null_out=false, bool null_err=false)
44 {
45 assert_no_interrupts();
46
47 // PR14168: we used to unsetenv values here; instead do it via
48 // env(1) in make_any_make_cmd().
49
50 // Disable ccache to avoid saving files that will never be reused.
51 // (ccache is useless to us, because our compiler commands always
52 // include the randomized tmpdir path.)
53 // It's not critical if this fails, so the return is ignored.
54 (void) setenv("CCACHE_DISABLE", "1", 0);
55
56 if (s.verbose > 2)
57 make_cmd.push_back("V=1");
58 else if (s.verbose > 1)
59 make_cmd.push_back("--no-print-directory");
60 else
61 {
62 make_cmd.push_back("-s");
63 make_cmd.push_back("--no-print-directory");
64 }
65
66 // Exploit SMP parallelism, if available.
67 long smp = sysconf(_SC_NPROCESSORS_ONLN);
68 if (smp <= 0) smp = 1;
69 // PR16276: but only if we're not running severely nproc-rlimited
70 struct rlimit rlim;
71 int rlimit_rc = getrlimit(RLIMIT_NPROC, &rlim);
72 const unsigned int severely_limited = smp*30; // WAG at number of gcc+make etc. nested processes
73 bool nproc_limited = (rlimit_rc == 0 && (rlim.rlim_max <= severely_limited ||
74 rlim.rlim_cur <= severely_limited));
75 if (smp >= 1 && !nproc_limited)
76 make_cmd.push_back("-j" + lex_cast(smp+1));
77
78 if (strverscmp (s.kernel_base_release.c_str(), "2.6.29") < 0)
79 {
80 // Older kernels, before linux commit #fd54f502841c1, include
81 // gratuitous "echo"s in their Makefile. We need to suppress
82 // that with this bluntness.
83 null_out = true;
84 }
85
86 int rc = stap_system (s.verbose, "kbuild", make_cmd, null_out, null_err);
87 if (rc != 0)
88 s.set_try_server ();
89 return rc;
90 }
91
92 static vector<string>
93 make_any_make_cmd(systemtap_session& s, const string& dir, const string& target)
94 {
95 string newpath("PATH=/usr/bin:/bin");
96 const char *oldpath = getenv("PATH");
97 if (oldpath != NULL)
98 {
99 newpath += ':';
100 newpath += oldpath;
101 }
102
103 vector<string> make_cmd
104 {
105 // PR14168: sanitize environment variables for kbuild invocation
106 "env", "-uARCH", "-uKBUILD_EXTMOD", "-uCROSS_COMPILE", "-uKBUILD_IMAGE",
107 "-uKCONFIG_CONFIG", "-uINSTALL_PATH", newpath,
108
109 "make", "-C", s.kernel_build_tree,
110 "M=" + dir, // need make-quoting?
111 target,
112
113 // PR13847: suppress debuginfo creation by default
114 "CONFIG_DEBUG_INFO=",
115
116 // RHBZ1321628: suppress stack validation; expected to be temporary
117 "CONFIG_STACK_VALIDATION=",
118 };
119
120 // Add architecture, except for old powerpc (RHBZ669082)
121 if (s.architecture != "powerpc" ||
122 (strverscmp (s.kernel_base_release.c_str(), "2.6.15") >= 0))
123 make_cmd.push_back("ARCH=" + s.architecture); // need make-quoting?
124
125 // Add any custom kbuild flags
126 make_cmd.insert(make_cmd.end(), s.kbuildflags.begin(), s.kbuildflags.end());
127
128 return make_cmd;
129 }
130
131 static vector<string>
132 make_make_cmd(systemtap_session& s, const string& dir)
133 {
134 return make_any_make_cmd(s, dir, "modules");
135 }
136
137 static vector<string>
138 make_make_objs_cmd(systemtap_session& s, const string& dir)
139 {
140 // Kbuild uses these rules to build external modules:
141 //
142 // module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
143 // modules: $(module-dirs)
144 // @$(kecho) ' Building modules, stage 2.';
145 // $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
146 //
147 // So if we're only interested in the stage 1 objects, we can
148 // cheat and make only the $(module-dirs) part.
149 return make_any_make_cmd(s, dir, "_module_" + dir);
150 }
151
152 static void
153 output_autoconf(systemtap_session& s, ofstream& o, const char *autoconf_c,
154 const char *deftrue, const char *deffalse)
155 {
156 o << "\t";
157 if (s.verbose < 4)
158 o << "@";
159 o << "if $(CHECK_BUILD) $(SYSTEMTAP_RUNTIME)/linux/" << autoconf_c;
160 if (s.verbose < 5)
161 o << " > /dev/null 2>&1";
162 o << "; then ";
163 if (deftrue)
164 o << "echo \"#define " << deftrue << " 1\"";
165 if (deffalse)
166 o << "; else echo \"#define " << deffalse << " 1\"";
167 o << "; fi >> $@" << endl;
168 }
169
170
171 void output_exportconf(systemtap_session& s, ofstream& o, const char *symbol,
172 const char *deftrue)
173 {
174 o << "\t";
175 if (s.verbose < 4)
176 o << "@";
177 if (s.kernel_exports.find(symbol) != s.kernel_exports.end())
178 o << "echo \"#define " << deftrue << " 1\"";
179 o << ">> $@" << endl;
180 }
181
182
183 void output_dual_exportconf(systemtap_session& s, ofstream& o,
184 const char *symbol1, const char *symbol2,
185 const char *deftrue)
186 {
187 o << "\t";
188 if (s.verbose < 4)
189 o << "@";
190 if (s.kernel_exports.find(symbol1) != s.kernel_exports.end()
191 && s.kernel_exports.find(symbol2) != s.kernel_exports.end())
192 o << "echo \"#define " << deftrue << " 1\"";
193 o << ">> $@" << endl;
194 }
195
196
197 void output_either_exportconf(systemtap_session& s, ofstream& o,
198 const char *symbol1, const char *symbol2,
199 const char *deftrue)
200 {
201 o << "\t";
202 if (s.verbose < 4)
203 o << "@";
204 if (s.kernel_exports.find(symbol1) != s.kernel_exports.end()
205 || s.kernel_exports.find(symbol2) != s.kernel_exports.end())
206 o << "echo \"#define " << deftrue << " 1\"";
207 o << ">> $@" << endl;
208 }
209
210
211 static int
212 compile_dyninst (systemtap_session& s)
213 {
214 const string module = s.tmpdir + "/" + s.module_filename();
215
216 vector<string> cmd
217 {
218 "gcc", "--std=gnu99", s.translated_source, "-o", module,
219 "-fvisibility=hidden", "-O2", "-I" + s.runtime_path, "-D__DYNINST__",
220 "-Wall", WERROR, "-Wno-unused", "-Wno-strict-aliasing",
221 "-pthread", "-lrt", "-fPIC", "-shared",
222 };
223
224 // BZ855981/948279. Since dyninst/runtime.h includes __sync_* calls,
225 // the compiler may generate different code for it depending on -march.
226 // For example, if the default is i386, we may get references to auxiliary
227 // functions like __sync_add_and_fetch_4, which appear to be defined
228 // nowhere. We hack around this problem thusly:
229 if (s.architecture == "i386")
230 cmd.push_back("-march=i586");
231
232 for (size_t i = 0; i < s.c_macros.size(); ++i)
233 cmd.push_back("-D" + s.c_macros[i]);
234
235 if (s.verbose > 3)
236 cmd.insert(cmd.end(), { "-ftime-report", "-Q" });
237
238 // Add any custom kbuild flags
239 cmd.insert(cmd.end(), s.kbuildflags.begin(), s.kbuildflags.end());
240
241 int rc = stap_system (s.verbose, cmd);
242 if (rc)
243 s.set_try_server ();
244 return rc;
245 }
246
247
248 int
249 compile_pass (systemtap_session& s)
250 {
251 if (s.runtime_usermode_p())
252 return compile_dyninst (s);
253
254 int rc = uprobes_pass (s);
255 if (rc)
256 {
257 s.set_try_server ();
258 return rc;
259 }
260
261 // fill in a quick Makefile
262 string makefile_nm = s.tmpdir + "/Makefile";
263 ofstream o (makefile_nm.c_str());
264
265 // Create makefile
266
267 // Clever hacks copied from vmware modules
268 string superverbose;
269 if (s.verbose > 3)
270 superverbose = "set -x;";
271
272 string redirecterrors = "> /dev/null 2>&1";
273 if (s.verbose > 6)
274 redirecterrors = "";
275
276 // Support O= (or KBUILD_OUTPUT) option
277 o << "_KBUILD_CFLAGS := $(call flags,KBUILD_CFLAGS)" << endl;
278
279 o << "stap_check_gcc = $(shell " << superverbose
280 << " if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then "
281 << "echo \"$(1)\"; else echo \"$(2)\"; fi)" << endl;
282 o << "CHECK_BUILD := $(CC) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CPPFLAGS) "
283 << "$(LINUXINCLUDE) $(_KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) "
284 << "$(CFLAGS) -DKBUILD_BASENAME=\\\"" << s.module_name << "\\\" "
285 << WERROR << " -S -o /dev/null -xc " << endl;
286 o << "stap_check_build = $(shell " << superverbose << " if $(CHECK_BUILD) $(1) "
287 << redirecterrors << " ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl;
288
289 o << "SYSTEMTAP_RUNTIME = \"" << s.runtime_path << "\"" << endl;
290
291 // "autoconf" options go here
292
293 // RHBZ 543529: early rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
294 o << "CONFIG_MODULE_SIG := n" << endl;
295
296 string module_cflags = "EXTRA_CFLAGS";
297 o << module_cflags << " :=" << endl;
298
299 // XXX: This gruesome hack is needed on some kernels built with separate O=directory,
300 // where files like 2.6.27 x86's asm/mach-*/mach_mpspec.h are not found on the cpp path.
301 // This could be a bug in arch/x86/Makefile that names
302 // mflags-y += -Iinclude/asm-x86/mach-default
303 // but that path does not exist in an O= build tree.
304 o << module_cflags << " += -Iinclude2/asm/mach-default" << endl;
305 o << module_cflags << " += -I" + s.kernel_build_tree << endl;
306 if (s.kernel_source_tree != "")
307 o << module_cflags << " += -I" + s.kernel_source_tree << endl;
308 for (unsigned i = 0; i < s.kernel_extra_cflags.size(); i++)
309 o << module_cflags << " += " + s.kernel_extra_cflags[i] << endl;
310
311 // NB: don't try
312 // o << module_cflags << " += -Iusr/include" << endl;
313 // since such headers are cleansed of _KERNEL_ pieces that we need
314
315 o << "STAPCONF_HEADER := " << s.tmpdir << "/" << s.stapconf_name << endl;
316 o << "$(STAPCONF_HEADER):" << endl;
317 o << "\t@> $@" << endl;
318 output_autoconf(s, o, "autoconf-hrtimer-rel.c", "STAPCONF_HRTIMER_REL", NULL);
319 output_exportconf(s, o, "hrtimer_get_res", "STAPCONF_HRTIMER_GET_RES");
320 output_autoconf(s, o, "autoconf-generated-compile.c", "STAPCONF_GENERATED_COMPILE", NULL);
321 output_autoconf(s, o, "autoconf-hrtimer-getset-expires.c", "STAPCONF_HRTIMER_GETSET_EXPIRES", NULL);
322 output_autoconf(s, o, "autoconf-inode-private.c", "STAPCONF_INODE_PRIVATE", NULL);
323 output_autoconf(s, o, "autoconf-constant-tsc.c", "STAPCONF_CONSTANT_TSC", NULL);
324 output_autoconf(s, o, "autoconf-ktime-get-real.c", "STAPCONF_KTIME_GET_REAL", NULL);
325 output_autoconf(s, o, "autoconf-x86-uniregs.c", "STAPCONF_X86_UNIREGS", NULL);
326 output_autoconf(s, o, "autoconf-nameidata.c", "STAPCONF_NAMEIDATA_CLEANUP", NULL);
327 output_dual_exportconf(s, o, "unregister_kprobes", "unregister_kretprobes", "STAPCONF_UNREGISTER_KPROBES");
328 output_autoconf(s, o, "autoconf-kprobe-symbol-name.c", "STAPCONF_KPROBE_SYMBOL_NAME", NULL);
329 output_autoconf(s, o, "autoconf-real-parent.c", "STAPCONF_REAL_PARENT", NULL);
330 output_autoconf(s, o, "autoconf-uaccess.c", "STAPCONF_LINUX_UACCESS_H", NULL);
331 output_autoconf(s, o, "autoconf-oneachcpu-retry.c", "STAPCONF_ONEACHCPU_RETRY", NULL);
332 output_autoconf(s, o, "autoconf-dpath-path.c", "STAPCONF_DPATH_PATH", NULL);
333 output_exportconf(s, o, "synchronize_kernel", "STAPCONF_SYNCHRONIZE_KERNEL");
334 output_exportconf(s, o, "synchronize_rcu", "STAPCONF_SYNCHRONIZE_RCU");
335 output_exportconf(s, o, "synchronize_sched", "STAPCONF_SYNCHRONIZE_SCHED");
336 output_autoconf(s, o, "autoconf-task-uid.c", "STAPCONF_TASK_UID", NULL);
337 output_autoconf(s, o, "autoconf-from_kuid_munged.c", "STAPCONF_FROM_KUID_MUNGED", NULL);
338 output_exportconf(s, o, "get_mm_exe_file", "STAPCONF_GET_MM_EXE_FILE");
339 output_dual_exportconf(s, o, "alloc_vm_area", "free_vm_area", "STAPCONF_VM_AREA");
340 output_autoconf(s, o, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL);
341 output_autoconf(s, o, "autoconf-alloc-percpu-align.c", "STAPCONF_ALLOC_PERCPU_ALIGN", NULL);
342 output_autoconf(s, o, "autoconf-x86-fs.c", "STAPCONF_X86_FS", NULL);
343 output_autoconf(s, o, "autoconf-x86-xfs.c", "STAPCONF_X86_XFS", NULL);
344 output_autoconf(s, o, "autoconf-x86-gs.c", "STAPCONF_X86_GS", NULL);
345 output_autoconf(s, o, "autoconf-grsecurity.c", "STAPCONF_GRSECURITY", NULL);
346 output_autoconf(s, o, "autoconf-trace-printk.c", "STAPCONF_TRACE_PRINTK", NULL);
347 output_autoconf(s, o, "autoconf-regset.c", "STAPCONF_REGSET", NULL);
348 output_autoconf(s, o, "autoconf-utrace-regset.c", "STAPCONF_UTRACE_REGSET", NULL);
349 output_autoconf(s, o, "autoconf-uprobe-get-pc.c", "STAPCONF_UPROBE_GET_PC", NULL);
350 output_autoconf(s, o, "autoconf-hlist-4args.c", "STAPCONF_HLIST_4ARGS", NULL);
351 output_exportconf(s, o, "tsc_khz", "STAPCONF_TSC_KHZ");
352 output_exportconf(s, o, "cpu_khz", "STAPCONF_CPU_KHZ");
353 output_exportconf(s, o, "__module_text_address", "STAPCONF_MODULE_TEXT_ADDRESS");
354 output_exportconf(s, o, "add_timer_on", "STAPCONF_ADD_TIMER_ON");
355
356 output_dual_exportconf(s, o, "probe_kernel_read", "probe_kernel_write", "STAPCONF_PROBE_KERNEL");
357 output_autoconf(s, o, "autoconf-hw_breakpoint_context.c",
358 "STAPCONF_HW_BREAKPOINT_CONTEXT", NULL);
359 output_autoconf(s, o, "autoconf-save-stack-trace.c",
360 "STAPCONF_KERNEL_STACKTRACE", NULL);
361 output_autoconf(s, o, "autoconf-save-stack-trace-no-bp.c",
362 "STAPCONF_KERNEL_STACKTRACE_NO_BP", NULL);
363 output_autoconf(s, o, "autoconf-asm-syscall.c",
364 "STAPCONF_ASM_SYSCALL_H", NULL);
365 output_autoconf(s, o, "autoconf-ring_buffer-flags.c", "STAPCONF_RING_BUFFER_FLAGS", NULL);
366 output_autoconf(s, o, "autoconf-ring_buffer_lost_events.c", "STAPCONF_RING_BUFFER_LOST_EVENTS", NULL);
367 output_autoconf(s, o, "autoconf-ring_buffer_read_prepare.c", "STAPCONF_RING_BUFFER_READ_PREPARE", NULL);
368 output_autoconf(s, o, "autoconf-kallsyms-on-each-symbol.c", "STAPCONF_KALLSYMS_ON_EACH_SYMBOL", NULL);
369 output_autoconf(s, o, "autoconf-walk-stack.c", "STAPCONF_WALK_STACK", NULL);
370 output_autoconf(s, o, "autoconf-stacktrace_ops-warning.c",
371 "STAPCONF_STACKTRACE_OPS_WARNING", NULL);
372 output_autoconf(s, o, "autoconf-mm-context-vdso.c", "STAPCONF_MM_CONTEXT_VDSO", NULL);
373 output_autoconf(s, o, "autoconf-mm-context-vdso-base.c", "STAPCONF_MM_CONTEXT_VDSO_BASE", NULL);
374 output_autoconf(s, o, "autoconf-blk-types.c", "STAPCONF_BLK_TYPES", NULL);
375 output_autoconf(s, o, "autoconf-perf-structpid.c", "STAPCONF_PERF_STRUCTPID", NULL);
376 output_autoconf(s, o, "perf_event_counter_context.c",
377 "STAPCONF_PERF_COUNTER_CONTEXT", NULL);
378 output_autoconf(s, o, "perf_probe_handler_nmi.c",
379 "STAPCONF_PERF_HANDLER_NMI", NULL);
380 output_exportconf(s, o, "path_lookup", "STAPCONF_PATH_LOOKUP");
381 output_exportconf(s, o, "kern_path_parent", "STAPCONF_KERN_PATH_PARENT");
382 output_exportconf(s, o, "vfs_path_lookup", "STAPCONF_VFS_PATH_LOOKUP");
383 output_exportconf(s, o, "kern_path", "STAPCONF_KERN_PATH");
384 output_exportconf(s, o, "proc_create_data", "STAPCONF_PROC_CREATE_DATA");
385 output_exportconf(s, o, "PDE_DATA", "STAPCONF_PDE_DATA");
386 output_autoconf(s, o, "autoconf-module-sect-attrs.c", "STAPCONF_MODULE_SECT_ATTRS", NULL);
387
388 output_autoconf(s, o, "autoconf-utrace-via-tracepoints.c", "STAPCONF_UTRACE_VIA_TRACEPOINTS", NULL);
389 output_autoconf(s, o, "autoconf-task_work-struct.c", "STAPCONF_TASK_WORK_STRUCT", NULL);
390 output_autoconf(s, o, "autoconf-vm-area-pte.c", "STAPCONF_VM_AREA_PTE", NULL);
391 output_autoconf(s, o, "autoconf-relay-umode_t.c", "STAPCONF_RELAY_UMODE_T", NULL);
392 output_autoconf(s, o, "autoconf-fs_supers-hlist.c", "STAPCONF_FS_SUPERS_HLIST", NULL);
393 output_autoconf(s, o, "autoconf-compat_sigaction.c", "STAPCONF_COMPAT_SIGACTION", NULL);
394 output_autoconf(s, o, "autoconf-netfilter.c", "STAPCONF_NETFILTER_V313", NULL);
395 output_autoconf(s, o, "autoconf-netfilter-313b.c", "STAPCONF_NETFILTER_V313B", NULL);
396 output_autoconf(s, o, "autoconf-netfilter-4_1.c", "STAPCONF_NETFILTER_V41", NULL);
397 output_autoconf(s, o, "autoconf-netfilter-4_4.c", "STAPCONF_NETFILTER_V44", NULL);
398 output_autoconf(s, o, "autoconf-smpcall-5args.c", "STAPCONF_SMPCALL_5ARGS", NULL);
399 output_autoconf(s, o, "autoconf-smpcall-4args.c", "STAPCONF_SMPCALL_4ARGS", NULL);
400
401 // used by tapset/timestamp_monotonic.stp
402 output_exportconf(s, o, "cpu_clock", "STAPCONF_CPU_CLOCK");
403 output_exportconf(s, o, "local_clock", "STAPCONF_LOCAL_CLOCK");
404
405 // used by runtime/uprobe-inode.c
406 output_either_exportconf(s, o, "uprobe_register", "register_uprobe",
407 "STAPCONF_UPROBE_REGISTER_EXPORTED");
408 output_either_exportconf(s, o, "uprobe_unregister", "unregister_uprobe",
409 "STAPCONF_UPROBE_UNREGISTER_EXPORTED");
410 output_autoconf(s, o, "autoconf-old-inode-uprobes.c", "STAPCONF_OLD_INODE_UPROBES", NULL);
411 output_autoconf(s, o, "autoconf-inode-uretprobes.c", "STAPCONF_INODE_URETPROBES", NULL);
412
413 // used by tapsets.cxx inode uprobe generated code
414 output_exportconf(s, o, "uprobe_get_swbp_addr", "STAPCONF_UPROBE_GET_SWBP_ADDR_EXPORTED");
415
416 // used by runtime/loc2c-runtime.h
417 output_exportconf(s, o, "task_user_regset_view", "STAPCONF_TASK_USER_REGSET_VIEW_EXPORTED");
418
419 // used by runtime/stp_utrace.c
420 output_exportconf(s, o, "task_work_add", "STAPCONF_TASK_WORK_ADD_EXPORTED");
421 output_exportconf(s, o, "wake_up_state", "STAPCONF_WAKE_UP_STATE_EXPORTED");
422 output_exportconf(s, o, "try_to_wake_up", "STAPCONF_TRY_TO_WAKE_UP_EXPORTED");
423 output_exportconf(s, o, "signal_wake_up_state", "STAPCONF_SIGNAL_WAKE_UP_STATE_EXPORTED");
424 output_exportconf(s, o, "signal_wake_up", "STAPCONF_SIGNAL_WAKE_UP_EXPORTED");
425 output_exportconf(s, o, "__lock_task_sighand", "STAPCONF___LOCK_TASK_SIGHAND_EXPORTED");
426
427 output_autoconf(s, o, "autoconf-pagefault_disable.c", "STAPCONF_PAGEFAULT_DISABLE", NULL);
428 output_exportconf(s, o, "kallsyms_lookup_name", "STAPCONF_KALLSYMS");
429 output_autoconf(s, o, "autoconf-uidgid.c", "STAPCONF_LINUX_UIDGID_H", NULL);
430 output_exportconf(s, o, "sigset_from_compat", "STAPCONF_SIGSET_FROM_COMPAT_EXPORTED");
431 output_exportconf(s, o, "vzalloc", "STAPCONF_VZALLOC");
432 output_exportconf(s, o, "vzalloc_node", "STAPCONF_VZALLOC_NODE");
433 output_exportconf(s, o, "vmalloc_node", "STAPCONF_VMALLOC_NODE");
434
435 // RHBZ1233912 - s390 temporary workaround for non-atomic udelay()
436 output_exportconf(s, o, "udelay_simple", "STAPCONF_UDELAY_SIMPLE");
437
438 output_autoconf(s, o, "autoconf-tracepoint-strings.c", "STAPCONF_TRACEPOINT_STRINGS", NULL);
439 output_autoconf(s, o, "autoconf-timerfd.c", "STAPCONF_TIMERFD_H", NULL);
440
441 output_autoconf(s, o, "autoconf-module_layout.c",
442 "STAPCONF_MODULE_LAYOUT", NULL);
443 output_autoconf(s, o, "autoconf-mod_kallsyms.c",
444 "STAPCONF_MOD_KALLSYMS", NULL);
445 output_exportconf(s, o, "get_user_pages_remote", "STAPCONF_GET_USER_PAGES_REMOTE");
446
447 o << module_cflags << " += -include $(STAPCONF_HEADER)" << endl;
448
449 for (unsigned i=0; i<s.c_macros.size(); i++)
450 o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.c_macros[i]) << endl; // XXX right quoting?
451
452 if (s.verbose > 3)
453 o << "EXTRA_CFLAGS += -ftime-report -Q" << endl;
454
455 // XXX: unfortunately, -save-temps can't work since linux kbuild cwd
456 // is not writable.
457 //
458 // if (s.keep_tmpdir)
459 // o << "CFLAGS += -fverbose-asm -save-temps" << endl;
460
461 // Kernels can be compiled with CONFIG_CC_OPTIMIZE_FOR_SIZE to select
462 // -Os, otherwise -O2 is the default.
463 o << "EXTRA_CFLAGS += -freorder-blocks" << endl; // improve on -Os
464
465 // Generate eh_frame for self-backtracing
466 o << "EXTRA_CFLAGS += -fasynchronous-unwind-tables" << endl;
467
468 // We used to allow the user to override default optimization when so
469 // requested by adding a -O[0123s] so they could determine the
470 // time/space/speed tradeoffs themselves, but we cannot guantantee that
471 // the (un)optimized code actually compiles and/or generates functional
472 // code, so we had to remove it.
473 // o << "EXTRA_CFLAGS += " << s.gcc_flags << endl; // Add -O[0123s]
474
475 // o << "CFLAGS += -fno-unit-at-a-time" << endl;
476
477 // 256^W512 bytes should be enough for anybody
478 // XXX this doesn't validate varargs, per gcc bug #41633
479 o << "EXTRA_CFLAGS += $(call cc-option,-Wframe-larger-than=512)" << endl;
480
481 // gcc 5.0.0-0.13.fc23 ipa-icf seems to consume gigacpu on stap-generated code
482 o << "EXTRA_CFLAGS += $(call cc-option,-fno-ipa-icf)" << endl;
483
484 // Assumes linux 2.6 kbuild
485 o << "EXTRA_CFLAGS += -Wno-unused " << WERROR << endl;
486 #if CHECK_POINTER_ARITH_PR5947
487 o << "EXTRA_CFLAGS += -Wpointer-arith" << endl;
488 #endif
489 o << "EXTRA_CFLAGS += -I\"" << s.runtime_path << "\"" << endl;
490 // XXX: this may help ppc toc overflow
491 // o << "CFLAGS := $(subst -Os,-O2,$(CFLAGS)) -fminimal-toc" << endl;
492 o << "obj-m := " << s.module_name << ".o" << endl;
493
494 // print out all the auxiliary source (->object) file names
495 o << s.module_name << "-y := ";
496 for (unsigned i=0; i<s.auxiliary_outputs.size(); i++)
497 {
498 if (s.auxiliary_outputs[i]->trailer_p) continue;
499 string srcname = s.auxiliary_outputs[i]->filename;
500 assert (srcname != "" && srcname.rfind('/') != string::npos);
501 string objname = srcname.substr(srcname.rfind('/')+1); // basename
502 assert (objname != "" && objname[objname.size()-1] == 'c');
503 objname[objname.size()-1] = 'o'; // now objname
504 o << " " + objname;
505 }
506 // and once again, for the translated_source file. It can't simply
507 // be named MODULENAME.c, since kbuild doesn't allow a foo.ko file
508 // consisting of multiple .o's to have foo.o/foo.c as a source.
509 // (It uses ld -r -o foo.o EACH.o EACH.o).
510 {
511 string srcname = s.translated_source;
512 assert (srcname != "" && srcname.rfind('/') != string::npos);
513 string objname = srcname.substr(srcname.rfind('/')+1); // basename
514 assert (objname != "" && objname[objname.size()-1] == 'c');
515 objname[objname.size()-1] = 'o'; // now objname
516 o << " " + objname;
517 }
518 // and once again, for the trailer type auxiliary outputs.
519 for (unsigned i=0; i<s.auxiliary_outputs.size(); i++)
520 {
521 if (! s.auxiliary_outputs[i]->trailer_p) continue;
522 string srcname = s.auxiliary_outputs[i]->filename;
523 assert (srcname != "" && srcname.rfind('/') != string::npos);
524 string objname = srcname.substr(srcname.rfind('/')+1); // basename
525 assert (objname != "" && objname[objname.size()-1] == 'c');
526 objname[objname.size()-1] = 'o'; // now objname
527 o << " " + objname;
528 }
529 o << endl;
530
531 // add all stapconf dependencies
532 o << s.translated_source << ": $(STAPCONF_HEADER)" << endl;
533 for (unsigned i=0; i<s.auxiliary_outputs.size(); i++)
534 o << s.auxiliary_outputs[i]->filename << ": $(STAPCONF_HEADER)" << endl;
535
536
537 o.close ();
538
539 // Generate module directory pathname and make sure it exists.
540 string module_dir = s.kernel_build_tree;
541 string module_dir_makefile = module_dir + "/Makefile";
542 struct stat st;
543 rc = stat(module_dir_makefile.c_str(), &st);
544 if (rc != 0)
545 {
546 clog << _F("Checking \" %s \" failed with error: %s\nEnsure kernel development headers & makefiles are installed.",
547 module_dir_makefile.c_str(), strerror(errno)) << endl;
548 s.set_try_server ();
549 return rc;
550 }
551
552 // Run make
553 vector<string> make_cmd = make_make_cmd(s, s.tmpdir);
554 rc = run_make_cmd(s, make_cmd);
555 if (rc)
556 s.set_try_server ();
557 return rc;
558 }
559
560 /*
561 * If uprobes was built as part of the kernel build (either built-in
562 * or as a module), the uprobes exports should show up. This is to be
563 * as distinct from the stap-built uprobes.ko from the runtime.
564 */
565 static bool
566 kernel_built_uprobes (systemtap_session& s)
567 {
568 if (s.runtime_usermode_p())
569 return true; // sort of, via dyninst
570
571 // see also tapsets.cxx:kernel_supports_inode_uprobes()
572 return ((s.kernel_config["CONFIG_ARCH_SUPPORTS_UPROBES"] == "y" && s.kernel_config["CONFIG_UPROBES"] == "y") ||
573 (s.kernel_exports.find("unregister_uprobe") != s.kernel_exports.end()));
574 }
575
576 static int
577 make_uprobes (systemtap_session& s)
578 {
579 if (s.verbose > 1)
580 clog << _("Pass 4, preamble: (re)building SystemTap's version of uprobes.")
581 << endl;
582
583 // create a subdirectory for the uprobes module
584 string dir(s.tmpdir + "/uprobes");
585 if (create_dir(dir.c_str()) != 0)
586 {
587 s.print_warning("failed to create directory for build uprobes.");
588 s.set_try_server ();
589 return 1;
590 }
591
592 // create a simple Makefile
593 string makefile(dir + "/Makefile");
594 ofstream omf(makefile.c_str());
595 omf << "obj-m := uprobes.o" << endl;
596 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
597 omf << "CONFIG_MODULE_SIG := n" << endl;
598 omf.close();
599
600 // create a simple #include-chained source file
601 string runtimesourcefile(s.runtime_path + "/linux/uprobes/uprobes.c");
602 string sourcefile(dir + "/uprobes.c");
603 ofstream osrc(sourcefile.c_str());
604 osrc << "#include \"" << runtimesourcefile << "\"" << endl;
605
606 // pass --modinfo k=v to uprobes build too
607 for (unsigned i = 0; i < s.modinfos.size(); i++)
608 {
609 const string& mi = s.modinfos[i];
610 size_t loc = mi.find('=');
611 string tag = mi.substr (0, loc);
612 string value = mi.substr (loc+1);
613 osrc << "MODULE_INFO(" << tag << "," << lex_cast_qstring(value) << ");" << endl;
614 }
615
616 osrc.close();
617
618 // make the module
619 vector<string> make_cmd = make_make_cmd(s, dir);
620 int rc = run_make_cmd(s, make_cmd);
621 if (!rc && !copy_file(dir + "/Module.symvers",
622 s.tmpdir + "/Module.symvers"))
623 rc = -1;
624
625 if (s.verbose > 1)
626 clog << _("uprobes rebuild exit code: ") << rc << endl;
627 if (rc)
628 s.set_try_server ();
629 else
630 s.uprobes_path = dir + "/uprobes.ko";
631 return rc;
632 }
633
634 static bool
635 get_cached_uprobes(systemtap_session& s)
636 {
637 s.uprobes_hash = s.use_cache ? find_uprobes_hash(s) : "";
638 if (!s.uprobes_hash.empty())
639 {
640 // NB: We always put uprobes.ko in its own directory, especially so
641 // stap-serverd can more easily locate it.
642 string dir(s.tmpdir + "/uprobes");
643 if (create_dir(dir.c_str()) != 0)
644 return false;
645
646 string cacheko = s.uprobes_hash + ".ko";
647 string tmpko = dir + "/uprobes.ko";
648
649 // The symvers file still needs to go in the script module's directory.
650 string cachesyms = s.uprobes_hash + ".symvers";
651 string tmpsyms = s.tmpdir + "/Module.symvers";
652
653 if (get_file_size(cacheko) > 0 && copy_file(cacheko, tmpko) &&
654 get_file_size(cachesyms) > 0 && copy_file(cachesyms, tmpsyms))
655 {
656 s.uprobes_path = tmpko;
657 return true;
658 }
659 }
660 return false;
661 }
662
663 static void
664 set_cached_uprobes(systemtap_session& s)
665 {
666 if (s.use_cache && !s.uprobes_hash.empty())
667 {
668 string cacheko = s.uprobes_hash + ".ko";
669 string tmpko = s.tmpdir + "/uprobes/uprobes.ko";
670 copy_file(tmpko, cacheko);
671
672 string cachesyms = s.uprobes_hash + ".symvers";
673 string tmpsyms = s.tmpdir + "/uprobes/Module.symvers";
674 copy_file(tmpsyms, cachesyms);
675 }
676 }
677
678 int
679 uprobes_pass (systemtap_session& s)
680 {
681 if (!s.need_uprobes || kernel_built_uprobes(s))
682 return 0;
683
684 if (s.kernel_config["CONFIG_UTRACE"] != string("y"))
685 {
686 clog << _("user-space process-tracking facilities not available [man error::process-tracking]") << endl;
687 s.set_try_server ();
688 return 1;
689 }
690
691 /*
692 * We need to use the version of uprobes that comes with SystemTap. Try to
693 * get it from the cache first. If not found, build it and try to save it to
694 * the cache for future reuse.
695 */
696 int rc = 0;
697 if (!get_cached_uprobes(s))
698 {
699 rc = make_uprobes(s);
700 if (!rc)
701 set_cached_uprobes(s);
702 }
703 if (rc)
704 s.set_try_server ();
705 return rc;
706 }
707
708 static
709 vector<string>
710 make_dyninst_run_command (systemtap_session& s, const string& remotedir,
711 const string&)
712 {
713 vector<string> cmd { getenv("SYSTEMTAP_STAPDYN") ?: BINDIR "/stapdyn" };
714
715 // use slightly less verbosity
716 if (s.verbose > 0)
717 cmd.insert(cmd.end(), s.verbose - 1, "-v");
718
719 if (s.suppress_warnings)
720 cmd.push_back("-w");
721
722 if (!s.cmd.empty())
723 cmd.insert(cmd.end(), { "-c", s.cmd });
724
725 if (s.target_pid)
726 cmd.insert(cmd.end(), { "-x", lex_cast(s.target_pid) });
727
728 if (!s.output_file.empty())
729 cmd.insert(cmd.end(), { "-o", s.output_file });
730
731 if (s.color_mode != s.color_auto)
732 {
733 auto mode = s.color_mode == s.color_always ? "always" : "never";
734 cmd.insert(cmd.end(), { "-C", mode });
735 }
736
737 cmd.push_back((remotedir.empty() ? s.tmpdir : remotedir)
738 + "/" + s.module_filename());
739
740 // add module arguments
741 cmd.insert(cmd.end(), s.globalopts.begin(), s.globalopts.end());
742
743 return cmd;
744 }
745
746 vector<string>
747 make_run_command (systemtap_session& s, const string& remotedir,
748 const string& version)
749 {
750 if (s.runtime_usermode_p())
751 return make_dyninst_run_command(s, remotedir, version);
752
753 // for now, just spawn staprun
754 vector<string> cmd { getenv("SYSTEMTAP_STAPRUN") ?: BINDIR "/staprun" };
755
756 // use slightly less verbosity
757 if (s.verbose > 0)
758 cmd.insert(cmd.end(), s.verbose - 1, "-v");
759
760 if (s.suppress_warnings)
761 cmd.push_back("-w");
762
763 if (!s.output_file.empty())
764 cmd.insert(cmd.end(), { "-o", s.output_file });
765
766 if (!s.cmd.empty())
767 cmd.insert(cmd.end(), { "-c", s.cmd });
768
769 if (s.target_pid)
770 cmd.insert(cmd.end(), { "-t", lex_cast(s.target_pid) });
771
772 if (s.target_namespaces_pid)
773 cmd.insert(cmd.end(), { "-N", lex_cast(s.target_namespaces_pid) });
774
775 if (s.buffer_size)
776 cmd.insert(cmd.end(), { "-b", lex_cast(s.buffer_size) });
777
778 if (s.need_uprobes && !kernel_built_uprobes(s))
779 {
780 string opt_u = "-u";
781 if (!s.uprobes_path.empty() &&
782 strverscmp("1.4", version.c_str()) <= 0)
783 {
784 if (remotedir.empty())
785 opt_u.append(s.uprobes_path);
786 else
787 opt_u.append(remotedir + "/" + basename(s.uprobes_path.c_str()));
788 }
789 cmd.push_back(opt_u);
790 }
791
792 if (s.load_only)
793 cmd.push_back(s.output_file.empty() ? "-L" : "-D");
794
795 // Note that if this system requires signed modules, we can't rename
796 // it after it has been signed.
797 if (!s.modname_given && (strverscmp("1.6", version.c_str()) <= 0)
798 && s.mok_fingerprints.empty())
799 cmd.push_back("-R");
800
801 if (!s.size_option.empty())
802 cmd.insert(cmd.end(), { "-S", s.size_option });
803
804 if (s.color_mode != s.color_auto)
805 {
806 auto mode = s.color_mode == s.color_always ? "always" : "never";
807 cmd.insert(cmd.end(), { "-C", mode });
808 }
809
810 if (s.monitor)
811 cmd.insert(cmd.end(), { "-M", lex_cast(s.monitor_interval) });
812
813 cmd.push_back((remotedir.empty() ? s.tmpdir : remotedir)
814 + "/" + s.module_filename());
815
816 // add module arguments
817 cmd.insert(cmd.end(), s.globalopts.begin(), s.globalopts.end());
818
819 return cmd;
820 }
821
822
823 // Build tiny kernel modules to query tracepoints.
824 // Given a (header-file -> test-contents) map, compile them ASAP, and return
825 // a (header-file -> obj-filename) map.
826
827 map<string,string>
828 make_tracequeries(systemtap_session& s, const map<string,string>& contents)
829 {
830 static unsigned tick = 0;
831 string basename("tracequery_kmod_" + lex_cast(++tick));
832 map<string,string> objs;
833
834 // create a subdirectory for the module
835 string dir(s.tmpdir + "/" + basename);
836 if (create_dir(dir.c_str()) != 0)
837 {
838 s.print_warning("failed to create directory for querying tracepoints.");
839 s.set_try_server ();
840 return objs;
841 }
842
843 // create a simple Makefile
844 string makefile(dir + "/Makefile");
845 ofstream omf(makefile.c_str());
846 // force debuginfo generation, and relax implicit functions
847 omf << "EXTRA_CFLAGS := -g -Wno-implicit-function-declaration " << WERROR << endl;
848 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
849 omf << "CONFIG_MODULE_SIG := n" << endl;
850
851 // PR18389: disable GCC's Identical Code Folding, since the stubs may look identical
852 omf << "EXTRA_CFLAGS += $(call cc-option,-fno-ipa-icf)" << endl;
853
854 omf << "EXTRA_CFLAGS += -I" + s.kernel_build_tree << endl;
855 if (s.kernel_source_tree != "")
856 omf << "EXTRA_CFLAGS += -I" + s.kernel_source_tree << endl;
857 for (unsigned i = 0; i < s.kernel_extra_cflags.size(); i++)
858 omf << "EXTRA_CFLAGS += " + s.kernel_extra_cflags[i] << endl;
859
860 omf << "obj-m := " << endl;
861 // write out each header-specific source file into a separate file
862 for (map<string,string>::const_iterator it = contents.begin(); it != contents.end(); it++)
863 {
864 string sbasename = basename + "_" + lex_cast(++tick); // suffixed
865
866 // write out source code
867 string srcname = dir + "/" + sbasename + ".c";
868 string src = it->second;
869 ofstream osrc(srcname.c_str());
870 osrc << src;
871 osrc.close();
872
873 if (s.verbose > 2)
874 clog << _F("Processing tracepoint header %s with query %s",
875 it->first.c_str(), srcname.c_str())
876 << endl;
877
878 // arrange to build it
879 omf << "obj-m += " + sbasename + ".o" << endl; // NB: without <dir> prefix
880 objs[it->first] = dir + "/" + sbasename + ".o";
881 }
882 omf.close();
883
884 // make the module
885 vector<string> make_cmd = make_make_objs_cmd(s, dir);
886 make_cmd.push_back ("-i"); // ignore errors, give rc 0 even in case of tracepoint header nits
887 bool quiet = (s.verbose < 4);
888 int rc = run_make_cmd(s, make_cmd, quiet, quiet);
889 if (rc)
890 s.set_try_server ();
891
892 // Sometimes we fail a tracequery due to PR9993 / PR11649 type
893 // kernel trace header problems. In this case, due to PR12729, we
894 // used to get a lovely "Warning: make exited with status: 2" but no
895 // other useful diagnostic. -vvvv would let a user see what's up,
896 // but the user can't fix the problem even with that.
897
898 return objs;
899 }
900
901
902 // Build a tiny kernel module to query type information
903 static int
904 make_typequery_kmod(systemtap_session& s, const vector<string>& headers, string& name)
905 {
906 static unsigned tick = 0;
907 string basename("typequery_kmod_" + lex_cast(++tick));
908
909 // create a subdirectory for the module
910 string dir(s.tmpdir + "/" + basename);
911 if (create_dir(dir.c_str()) != 0)
912 {
913 s.print_warning("failed to create directory for querying types.");
914 s.set_try_server ();
915 return 1;
916 }
917
918 name = dir + "/" + basename + ".ko";
919
920 // create a simple Makefile
921 string makefile(dir + "/Makefile");
922 ofstream omf(makefile.c_str());
923 omf << "EXTRA_CFLAGS := -g -fno-eliminate-unused-debug-types" << endl;
924
925 // RHBZ 655231: later rhel6 kernels' module-signing kbuild logic breaks out-of-tree modules
926 omf << "CONFIG_MODULE_SIG := n" << endl;
927
928 // NB: We use -include instead of #include because that gives us more power.
929 // Using #include searches relative to the source's path, which in this case
930 // is /tmp/..., so that's not helpful. Using -include will search relative
931 // to the cwd, which will be the kernel build root. This means if you have a
932 // full kernel build tree, it's possible to get at types that aren't in the
933 // normal include path, e.g.:
934 // @cast(foo, "bsd_acct_struct", "kernel<kernel/acct.c>")->...
935 omf << "CFLAGS_" << basename << ".o :=";
936 for (size_t i = 0; i < headers.size(); ++i)
937 omf << " -include " << lex_cast_qstring(headers[i]); // XXX right quoting?
938 omf << endl;
939
940 omf << "obj-m := " + basename + ".o" << endl;
941 omf.close();
942
943 // create our empty source file
944 string source(dir + "/" + basename + ".c");
945 ofstream osrc(source.c_str());
946 osrc.close();
947
948 // make the module
949 vector<string> make_cmd = make_make_cmd(s, dir);
950 bool quiet = (s.verbose < 4);
951 int rc = run_make_cmd(s, make_cmd, quiet, quiet);
952 if (rc)
953 s.set_try_server ();
954 return rc;
955 }
956
957
958 // Build a tiny user module to query type information
959 static int
960 make_typequery_umod(systemtap_session& s, const vector<string>& headers, string& name)
961 {
962 static unsigned tick = 0;
963
964 name = s.tmpdir + "/typequery_umod_" + lex_cast(++tick) + ".so";
965
966 // make the module
967 //
968 // NB: As with kmod, using -include makes relative paths more useful. The
969 // cwd in this case will be the cwd of stap itself though, which may be
970 // trickier to deal with. It might be better to "cd `dirname $script`"
971 // first...
972 vector<string> cmd
973 {
974 "gcc", "-shared", "-g", "-fno-eliminate-unused-debug-types",
975 "-xc", "/dev/null", "-o", name,
976 };
977 for (size_t i = 0; i < headers.size(); ++i)
978 cmd.insert(cmd.end(), { "-include", headers[i] });
979
980 bool quiet = (s.verbose < 4);
981 int rc = stap_system (s.verbose, cmd, quiet, quiet);
982 if (rc)
983 s.set_try_server ();
984 return rc;
985 }
986
987
988 int
989 make_typequery(systemtap_session& s, string& module)
990 {
991 int rc;
992 string new_module;
993 vector<string> headers;
994 bool kernel = startswith(module, "kernel");
995
996 for (size_t end, i = kernel ? 6 : 0; i < module.size(); i = end + 1)
997 {
998 if (module[i] != '<')
999 return -1;
1000 end = module.find('>', ++i);
1001 if (end == string::npos)
1002 return -1;
1003 string header = module.substr(i, end - i);
1004 vector<string> matches;
1005 if (regexp_match(header, "^[a-zA-Z0-9/_.+-]+$", matches))
1006 s.print_warning("skipping malformed @cast header \""+ header + "\"");
1007 else
1008 headers.push_back(header);
1009 }
1010 if (headers.empty())
1011 return -1;
1012
1013 if (kernel)
1014 rc = make_typequery_kmod(s, headers, new_module);
1015 else
1016 rc = make_typequery_umod(s, headers, new_module);
1017
1018 if (!rc)
1019 module = new_module;
1020
1021 return rc;
1022 }
1023
1024 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.09385 seconds and 4 git commands to generate.