Blame view

tools/perf/util/llvm-utils.c 12.7 KB
aa61fd05c   Wang Nan   perf tools: Intro...
1
2
3
4
  /*
   * Copyright (C) 2015, Wang Nan <wangnan0@huawei.com>
   * Copyright (C) 2015, Huawei Inc.
   */
175729fc2   Arnaldo Carvalho de Melo   perf tools: Remov...
5
  #include <errno.h>
78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
6
  #include <limits.h>
aa61fd05c   Wang Nan   perf tools: Intro...
7
  #include <stdio.h>
78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
8
  #include <stdlib.h>
2bd42de0e   Wang Nan   perf llvm: Extrac...
9
  #include <linux/err.h>
aa61fd05c   Wang Nan   perf tools: Intro...
10
11
  #include "debug.h"
  #include "llvm-utils.h"
41840d211   Taeung Song   perf config: Move...
12
  #include "config.h"
175729fc2   Arnaldo Carvalho de Melo   perf tools: Remov...
13
  #include "util.h"
4208735d8   Arnaldo Carvalho de Melo   perf tools: Remov...
14
  #include <sys/wait.h>
aa61fd05c   Wang Nan   perf tools: Intro...
15
16
  
  #define CLANG_BPF_CMD_DEFAULT_TEMPLATE				\
59f41af98   Wang Nan   perf llvm: Pass n...
17
  		"$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\
4a4f66a1a   Wang Nan   perf llvm: Pass L...
18
  		"-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE "	\
59f41af98   Wang Nan   perf llvm: Pass n...
19
20
21
22
  		"$CLANG_OPTIONS $KERNEL_INC_OPTIONS "		\
  		"-Wno-unused-value -Wno-pointer-sign "		\
  		"-working-directory $WORKING_DIR "		\
  		"-c \"$CLANG_SOURCE\" -target bpf -O2 -o -"
aa61fd05c   Wang Nan   perf tools: Intro...
23
24
25
26
27
28
29
  
  struct llvm_param llvm_param = {
  	.clang_path = "clang",
  	.clang_bpf_cmd_template = CLANG_BPF_CMD_DEFAULT_TEMPLATE,
  	.clang_opt = NULL,
  	.kbuild_dir = NULL,
  	.kbuild_opts = NULL,
9bc898c70   Wang Nan   perf tests: Add L...
30
  	.user_set_param = false,
aa61fd05c   Wang Nan   perf tools: Intro...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  };
  
  int perf_llvm_config(const char *var, const char *value)
  {
  	if (prefixcmp(var, "llvm."))
  		return 0;
  	var += sizeof("llvm.") - 1;
  
  	if (!strcmp(var, "clang-path"))
  		llvm_param.clang_path = strdup(value);
  	else if (!strcmp(var, "clang-bpf-cmd-template"))
  		llvm_param.clang_bpf_cmd_template = strdup(value);
  	else if (!strcmp(var, "clang-opt"))
  		llvm_param.clang_opt = strdup(value);
  	else if (!strcmp(var, "kbuild-dir"))
  		llvm_param.kbuild_dir = strdup(value);
  	else if (!strcmp(var, "kbuild-opts"))
  		llvm_param.kbuild_opts = strdup(value);
f07846492   Wang Nan   perf llvm: Allow ...
49
50
  	else if (!strcmp(var, "dump-obj"))
  		llvm_param.dump_obj = !!perf_config_bool(var, value);
ecc4c5614   Arnaldo Carvalho de Melo   perf tools: Propa...
51
52
53
  	else {
  		pr_debug("Invalid LLVM config option: %s
  ", value);
aa61fd05c   Wang Nan   perf tools: Intro...
54
  		return -1;
ecc4c5614   Arnaldo Carvalho de Melo   perf tools: Propa...
55
  	}
9bc898c70   Wang Nan   perf tests: Add L...
56
  	llvm_param.user_set_param = true;
aa61fd05c   Wang Nan   perf tools: Intro...
57
58
  	return 0;
  }
4cea3a9cb   Wang Nan   perf tools: Call ...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  
  static int
  search_program(const char *def, const char *name,
  	       char *output)
  {
  	char *env, *path, *tmp = NULL;
  	char buf[PATH_MAX];
  	int ret;
  
  	output[0] = '\0';
  	if (def && def[0] != '\0') {
  		if (def[0] == '/') {
  			if (access(def, F_OK) == 0) {
  				strlcpy(output, def, PATH_MAX);
  				return 0;
  			}
  		} else if (def[0] != '\0')
  			name = def;
  	}
  
  	env = getenv("PATH");
  	if (!env)
  		return -1;
  	env = strdup(env);
  	if (!env)
  		return -1;
  
  	ret = -ENOENT;
  	path = strtok_r(env, ":",  &tmp);
  	while (path) {
  		scnprintf(buf, sizeof(buf), "%s/%s", path, name);
  		if (access(buf, F_OK) == 0) {
  			strlcpy(output, buf, PATH_MAX);
  			ret = 0;
  			break;
  		}
  		path = strtok_r(NULL, ":", &tmp);
  	}
  
  	free(env);
  	return ret;
  }
  
  #define READ_SIZE	4096
  static int
  read_from_pipe(const char *cmd, void **p_buf, size_t *p_read_sz)
  {
  	int err = 0;
  	void *buf = NULL;
  	FILE *file = NULL;
  	size_t read_sz = 0, buf_sz = 0;
76267147f   Arnaldo Carvalho de Melo   perf llvm: Use st...
110
  	char serr[STRERR_BUFSIZE];
4cea3a9cb   Wang Nan   perf tools: Call ...
111
112
113
114
115
  
  	file = popen(cmd, "r");
  	if (!file) {
  		pr_err("ERROR: unable to popen cmd: %s
  ",
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
116
  		       str_error_r(errno, serr, sizeof(serr)));
4cea3a9cb   Wang Nan   perf tools: Call ...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
  		return -EINVAL;
  	}
  
  	while (!feof(file) && !ferror(file)) {
  		/*
  		 * Make buf_sz always have obe byte extra space so we
  		 * can put '\0' there.
  		 */
  		if (buf_sz - read_sz < READ_SIZE + 1) {
  			void *new_buf;
  
  			buf_sz = read_sz + READ_SIZE + 1;
  			new_buf = realloc(buf, buf_sz);
  
  			if (!new_buf) {
  				pr_err("ERROR: failed to realloc memory
  ");
  				err = -ENOMEM;
  				goto errout;
  			}
  
  			buf = new_buf;
  		}
  		read_sz += fread(buf + read_sz, 1, READ_SIZE, file);
  	}
  
  	if (buf_sz - read_sz < 1) {
  		pr_err("ERROR: internal error
  ");
  		err = -EINVAL;
  		goto errout;
  	}
  
  	if (ferror(file)) {
  		pr_err("ERROR: error occurred when reading from pipe: %s
  ",
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
153
  		       str_error_r(errno, serr, sizeof(serr)));
4cea3a9cb   Wang Nan   perf tools: Call ...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  		err = -EIO;
  		goto errout;
  	}
  
  	err = WEXITSTATUS(pclose(file));
  	file = NULL;
  	if (err) {
  		err = -EINVAL;
  		goto errout;
  	}
  
  	/*
  	 * If buf is string, give it terminal '\0' to make our life
  	 * easier. If buf is not string, that '\0' is out of space
  	 * indicated by read_sz so caller won't even notice it.
  	 */
  	((char *)buf)[read_sz] = '\0';
  
  	if (!p_buf)
  		free(buf);
  	else
  		*p_buf = buf;
  
  	if (p_read_sz)
  		*p_read_sz = read_sz;
  	return 0;
  
  errout:
  	if (file)
  		pclose(file);
  	free(buf);
  	if (p_buf)
  		*p_buf = NULL;
  	if (p_read_sz)
  		*p_read_sz = 0;
  	return err;
  }
  
  static inline void
  force_set_env(const char *var, const char *value)
  {
  	if (value) {
  		setenv(var, value, 1);
  		pr_debug("set env: %s=%s
  ", var, value);
  	} else {
  		unsetenv(var);
  		pr_debug("unset env: %s
  ", var);
  	}
  }
  
  static void
  version_notice(void)
  {
  	pr_err(
  "     \tLLVM 3.7 or newer is required. Which can be found from http://llvm.org
  "
  "     \tYou may want to try git trunk:
  "
  "     \t\tgit clone http://llvm.org/git/llvm.git
  "
  "     \t\t     and
  "
  "     \t\tgit clone http://llvm.org/git/clang.git
  
  "
  "     \tOr fetch the latest clang/llvm 3.7 from pre-built llvm packages for
  "
  "     \tdebian/ubuntu:
  "
  "     \t\thttp://llvm.org/apt
  
  "
  "     \tIf you are using old version of clang, change 'clang-bpf-cmd-template'
  "
  "     \toption in [llvm] section of ~/.perfconfig to:
  
  "
  "     \t  \"$CLANG_EXEC $CLANG_OPTIONS $KERNEL_INC_OPTIONS \\
  "
  "     \t     -working-directory $WORKING_DIR -c $CLANG_SOURCE \\
  "
  "     \t     -emit-llvm -o - | /path/to/llc -march=bpf -filetype=obj -o -\"
  "
  "     \t(Replace /path/to/llc with path to your llc)
  
  "
  );
  }
d325d7887   Wang Nan   perf tools: Auto ...
244
245
246
247
248
249
250
  static int detect_kbuild_dir(char **kbuild_dir)
  {
  	const char *test_dir = llvm_param.kbuild_dir;
  	const char *prefix_dir = "";
  	const char *suffix_dir = "";
  
  	char *autoconf_path;
d325d7887   Wang Nan   perf tools: Auto ...
251
252
253
254
  
  	int err;
  
  	if (!test_dir) {
07bc5c699   Wang Nan   perf tools: Make ...
255
256
257
258
259
260
  		/* _UTSNAME_LENGTH is 65 */
  		char release[128];
  
  		err = fetch_kernel_version(NULL, release,
  					   sizeof(release));
  		if (err)
d325d7887   Wang Nan   perf tools: Auto ...
261
  			return -EINVAL;
d325d7887   Wang Nan   perf tools: Auto ...
262

07bc5c699   Wang Nan   perf tools: Make ...
263
  		test_dir = release;
d325d7887   Wang Nan   perf tools: Auto ...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  		prefix_dir = "/lib/modules/";
  		suffix_dir = "/build";
  	}
  
  	err = asprintf(&autoconf_path, "%s%s%s/include/generated/autoconf.h",
  		       prefix_dir, test_dir, suffix_dir);
  	if (err < 0)
  		return -ENOMEM;
  
  	if (access(autoconf_path, R_OK) == 0) {
  		free(autoconf_path);
  
  		err = asprintf(kbuild_dir, "%s%s%s", prefix_dir, test_dir,
  			       suffix_dir);
  		if (err < 0)
  			return -ENOMEM;
  		return 0;
  	}
  	free(autoconf_path);
  	return -ENOENT;
  }
0c6d18bfd   Wang Nan   perf tools: Auto ...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  static const char *kinc_fetch_script =
  "#!/usr/bin/env sh
  "
  "if ! test -d \"$KBUILD_DIR\"
  "
  "then
  "
  "	exit -1
  "
  "fi
  "
  "if ! test -f \"$KBUILD_DIR/include/generated/autoconf.h\"
  "
  "then
  "
  "	exit -1
  "
  "fi
  "
  "TMPDIR=`mktemp -d`
  "
  "if test -z \"$TMPDIR\"
  "
  "then
  "
  "    exit -1
  "
  "fi
  "
  "cat << EOF > $TMPDIR/Makefile
  "
  "obj-y := dummy.o
  "
  "\\$(obj)/%.o: \\$(src)/%.c
  "
  "\t@echo -n \"\\$(NOSTDINC_FLAGS) \\$(LINUXINCLUDE) \\$(EXTRA_CFLAGS)\"
  "
  "EOF
  "
  "touch $TMPDIR/dummy.c
  "
  "make -s -C $KBUILD_DIR M=$TMPDIR $KBUILD_OPTS dummy.o 2>/dev/null
  "
  "RET=$?
  "
  "rm -rf $TMPDIR
  "
  "exit $RET
  ";
2bd42de0e   Wang Nan   perf llvm: Extrac...
334
  void llvm__get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
d325d7887   Wang Nan   perf tools: Auto ...
335
  {
2bd42de0e   Wang Nan   perf llvm: Extrac...
336
337
  	static char *saved_kbuild_dir;
  	static char *saved_kbuild_include_opts;
d325d7887   Wang Nan   perf tools: Auto ...
338
  	int err;
0c6d18bfd   Wang Nan   perf tools: Auto ...
339
  	if (!kbuild_dir || !kbuild_include_opts)
d325d7887   Wang Nan   perf tools: Auto ...
340
341
342
  		return;
  
  	*kbuild_dir = NULL;
0c6d18bfd   Wang Nan   perf tools: Auto ...
343
  	*kbuild_include_opts = NULL;
d325d7887   Wang Nan   perf tools: Auto ...
344

2bd42de0e   Wang Nan   perf llvm: Extrac...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  	if (saved_kbuild_dir && saved_kbuild_include_opts &&
  	    !IS_ERR(saved_kbuild_dir) && !IS_ERR(saved_kbuild_include_opts)) {
  		*kbuild_dir = strdup(saved_kbuild_dir);
  		*kbuild_include_opts = strdup(saved_kbuild_include_opts);
  
  		if (*kbuild_dir && *kbuild_include_opts)
  			return;
  
  		zfree(kbuild_dir);
  		zfree(kbuild_include_opts);
  		/*
  		 * Don't fall through: it may breaks saved_kbuild_dir and
  		 * saved_kbuild_include_opts if detect them again when
  		 * memory is low.
  		 */
  		return;
  	}
d325d7887   Wang Nan   perf tools: Auto ...
362
363
364
365
366
  	if (llvm_param.kbuild_dir && !llvm_param.kbuild_dir[0]) {
  		pr_debug("[llvm.kbuild-dir] is set to \"\" deliberately.
  ");
  		pr_debug("Skip kbuild options detection.
  ");
2bd42de0e   Wang Nan   perf llvm: Extrac...
367
  		goto errout;
d325d7887   Wang Nan   perf tools: Auto ...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
  	}
  
  	err = detect_kbuild_dir(kbuild_dir);
  	if (err) {
  		pr_warning(
  "WARNING:\tunable to get correct kernel building directory.
  "
  "Hint:\tSet correct kbuild directory using 'kbuild-dir' option in [llvm]
  "
  "     \tsection of ~/.perfconfig or set it to \"\" to suppress kbuild
  "
  "     \tdetection.
  
  ");
2bd42de0e   Wang Nan   perf llvm: Extrac...
382
  		goto errout;
d325d7887   Wang Nan   perf tools: Auto ...
383
  	}
0c6d18bfd   Wang Nan   perf tools: Auto ...
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  
  	pr_debug("Kernel build dir is set to %s
  ", *kbuild_dir);
  	force_set_env("KBUILD_DIR", *kbuild_dir);
  	force_set_env("KBUILD_OPTS", llvm_param.kbuild_opts);
  	err = read_from_pipe(kinc_fetch_script,
  			     (void **)kbuild_include_opts,
  			     NULL);
  	if (err) {
  		pr_warning(
  "WARNING:\tunable to get kernel include directories from '%s'
  "
  "Hint:\tTry set clang include options using 'clang-bpf-cmd-template'
  "
  "     \toption in [llvm] section of ~/.perfconfig and set 'kbuild-dir'
  "
  "     \toption in [llvm] to \"\" to suppress this detection.
  
  ",
  			*kbuild_dir);
  
  		free(*kbuild_dir);
  		*kbuild_dir = NULL;
2bd42de0e   Wang Nan   perf llvm: Extrac...
407
  		goto errout;
0c6d18bfd   Wang Nan   perf tools: Auto ...
408
409
410
411
  	}
  
  	pr_debug("include option is set to %s
  ", *kbuild_include_opts);
2bd42de0e   Wang Nan   perf llvm: Extrac...
412
413
414
415
416
417
418
419
420
421
422
423
  
  	saved_kbuild_dir = strdup(*kbuild_dir);
  	saved_kbuild_include_opts = strdup(*kbuild_include_opts);
  
  	if (!saved_kbuild_dir || !saved_kbuild_include_opts) {
  		zfree(&saved_kbuild_dir);
  		zfree(&saved_kbuild_include_opts);
  	}
  	return;
  errout:
  	saved_kbuild_dir = ERR_PTR(-EINVAL);
  	saved_kbuild_include_opts = ERR_PTR(-EINVAL);
d325d7887   Wang Nan   perf tools: Auto ...
424
  }
2bd42de0e   Wang Nan   perf llvm: Extrac...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
  int llvm__get_nr_cpus(void)
  {
  	static int nr_cpus_avail = 0;
  	char serr[STRERR_BUFSIZE];
  
  	if (nr_cpus_avail > 0)
  		return nr_cpus_avail;
  
  	nr_cpus_avail = sysconf(_SC_NPROCESSORS_CONF);
  	if (nr_cpus_avail <= 0) {
  		pr_err(
  "WARNING:\tunable to get available CPUs in this system: %s
  "
  "        \tUse 128 instead.
  ", str_error_r(errno, serr, sizeof(serr)));
  		nr_cpus_avail = 128;
  	}
  	return nr_cpus_avail;
  }
  
  void llvm__dump_obj(const char *path, void *obj_buf, size_t size)
f07846492   Wang Nan   perf llvm: Allow ...
446
447
448
449
450
451
  {
  	char *obj_path = strdup(path);
  	FILE *fp;
  	char *p;
  
  	if (!obj_path) {
042cfb5fa   Alexander Alemayhu   perf tools: Fix t...
452
453
  		pr_warning("WARNING: Not enough memory, skip object dumping
  ");
f07846492   Wang Nan   perf llvm: Allow ...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
  		return;
  	}
  
  	p = strrchr(obj_path, '.');
  	if (!p || (strcmp(p, ".c") != 0)) {
  		pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping
  ",
  			   obj_path);
  		goto out;
  	}
  
  	p[1] = 'o';
  	fp = fopen(obj_path, "wb");
  	if (!fp) {
  		pr_warning("WARNING: failed to open '%s': %s, skip object dumping
  ",
  			   obj_path, strerror(errno));
  		goto out;
  	}
  
  	pr_info("LLVM: dumping %s
  ", obj_path);
  	if (fwrite(obj_buf, size, 1, fp) != 1)
  		pr_warning("WARNING: failed to write to file '%s': %s, skip object dumping
  ",
  			   obj_path, strerror(errno));
  	fclose(fp);
  out:
  	free(obj_path);
  }
4cea3a9cb   Wang Nan   perf tools: Call ...
484
485
486
  int llvm__compile_bpf(const char *path, void **p_obj_buf,
  		      size_t *p_obj_buf_sz)
  {
07bc5c699   Wang Nan   perf tools: Make ...
487
488
  	size_t obj_buf_sz;
  	void *obj_buf = NULL;
59f41af98   Wang Nan   perf llvm: Pass n...
489
  	int err, nr_cpus_avail;
07bc5c699   Wang Nan   perf tools: Make ...
490
  	unsigned int kernel_version;
4a4f66a1a   Wang Nan   perf llvm: Pass L...
491
  	char linux_version_code_str[64];
4cea3a9cb   Wang Nan   perf tools: Call ...
492
  	const char *clang_opt = llvm_param.clang_opt;
78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
493
494
  	char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64];
  	char serr[STRERR_BUFSIZE];
0c6d18bfd   Wang Nan   perf tools: Auto ...
495
  	char *kbuild_dir = NULL, *kbuild_include_opts = NULL;
07bc5c699   Wang Nan   perf tools: Make ...
496
  	const char *template = llvm_param.clang_bpf_cmd_template;
4cea3a9cb   Wang Nan   perf tools: Call ...
497

78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
498
499
500
501
  	if (path[0] != '-' && realpath(path, abspath) == NULL) {
  		err = errno;
  		pr_err("ERROR: problems with path %s: %s
  ",
c8b5f2c96   Arnaldo Carvalho de Melo   tools: Introduce ...
502
  		       path, str_error_r(err, serr, sizeof(serr)));
78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
503
504
  		return -err;
  	}
4cea3a9cb   Wang Nan   perf tools: Call ...
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  	if (!template)
  		template = CLANG_BPF_CMD_DEFAULT_TEMPLATE;
  
  	err = search_program(llvm_param.clang_path,
  			     "clang", clang_path);
  	if (err) {
  		pr_err(
  "ERROR:\tunable to find clang.
  "
  "Hint:\tTry to install latest clang/llvm to support BPF. Check your $PATH
  "
  "     \tand 'clang-path' option in [llvm] section of ~/.perfconfig.
  ");
  		version_notice();
  		return -ENOENT;
  	}
d325d7887   Wang Nan   perf tools: Auto ...
521
522
523
524
  	/*
  	 * This is an optional work. Even it fail we can continue our
  	 * work. Needn't to check error return.
  	 */
2bd42de0e   Wang Nan   perf llvm: Extrac...
525
  	llvm__get_kbuild_opts(&kbuild_dir, &kbuild_include_opts);
d325d7887   Wang Nan   perf tools: Auto ...
526

2bd42de0e   Wang Nan   perf llvm: Extrac...
527
  	nr_cpus_avail = llvm__get_nr_cpus();
59f41af98   Wang Nan   perf llvm: Pass n...
528
529
  	snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d",
  		 nr_cpus_avail);
07bc5c699   Wang Nan   perf tools: Make ...
530
531
  	if (fetch_kernel_version(&kernel_version, NULL, 0))
  		kernel_version = 0;
4a4f66a1a   Wang Nan   perf llvm: Pass L...
532
  	snprintf(linux_version_code_str, sizeof(linux_version_code_str),
07bc5c699   Wang Nan   perf tools: Make ...
533
  		 "0x%x", kernel_version);
4a4f66a1a   Wang Nan   perf llvm: Pass L...
534

59f41af98   Wang Nan   perf llvm: Pass n...
535
  	force_set_env("NR_CPUS", nr_cpus_avail_str);
4a4f66a1a   Wang Nan   perf llvm: Pass L...
536
  	force_set_env("LINUX_VERSION_CODE", linux_version_code_str);
4cea3a9cb   Wang Nan   perf tools: Call ...
537
538
  	force_set_env("CLANG_EXEC", clang_path);
  	force_set_env("CLANG_OPTIONS", clang_opt);
0c6d18bfd   Wang Nan   perf tools: Auto ...
539
  	force_set_env("KERNEL_INC_OPTIONS", kbuild_include_opts);
d325d7887   Wang Nan   perf tools: Auto ...
540
  	force_set_env("WORKING_DIR", kbuild_dir ? : ".");
4cea3a9cb   Wang Nan   perf tools: Call ...
541
542
543
544
545
546
547
  
  	/*
  	 * Since we may reset clang's working dir, path of source file
  	 * should be transferred into absolute path, except we want
  	 * stdin to be source file (testing).
  	 */
  	force_set_env("CLANG_SOURCE",
78478269d   Arnaldo Carvalho de Melo   perf llvm: Use re...
548
  		      (path[0] == '-') ? path : abspath);
4cea3a9cb   Wang Nan   perf tools: Call ...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
  
  	pr_debug("llvm compiling command template: %s
  ", template);
  	err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
  	if (err) {
  		pr_err("ERROR:\tunable to compile %s
  ", path);
  		pr_err("Hint:\tCheck error message shown above.
  ");
  		pr_err("Hint:\tYou can also pre-compile it into .o using:
  ");
  		pr_err("     \t\tclang -target bpf -O2 -c %s
  ", path);
  		pr_err("     \twith proper -I and -D options.
  ");
  		goto errout;
  	}
d325d7887   Wang Nan   perf tools: Auto ...
566
  	free(kbuild_dir);
0c6d18bfd   Wang Nan   perf tools: Auto ...
567
  	free(kbuild_include_opts);
f07846492   Wang Nan   perf llvm: Allow ...
568

4cea3a9cb   Wang Nan   perf tools: Call ...
569
570
571
572
573
574
575
576
577
  	if (!p_obj_buf)
  		free(obj_buf);
  	else
  		*p_obj_buf = obj_buf;
  
  	if (p_obj_buf_sz)
  		*p_obj_buf_sz = obj_buf_sz;
  	return 0;
  errout:
d325d7887   Wang Nan   perf tools: Auto ...
578
  	free(kbuild_dir);
0c6d18bfd   Wang Nan   perf tools: Auto ...
579
  	free(kbuild_include_opts);
4cea3a9cb   Wang Nan   perf tools: Call ...
580
581
582
583
584
585
586
  	free(obj_buf);
  	if (p_obj_buf)
  		*p_obj_buf = NULL;
  	if (p_obj_buf_sz)
  		*p_obj_buf_sz = 0;
  	return err;
  }
9bc898c70   Wang Nan   perf tests: Add L...
587
588
589
590
591
592
593
  
  int llvm__search_clang(void)
  {
  	char clang_path[PATH_MAX];
  
  	return search_program(llvm_param.clang_path, "clang", clang_path);
  }