History

Merge branch 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (40 commits) tracing: Separate raw syscall from syscall tracer ring-buffer-benchmark: Add parameters to set produce/consumer priorities tracing, function tracer: Clean up strstrip() usage ring-buffer benchmark: Run producer/consumer threads at nice +19 tracing: Remove the stale include/trace/power.h tracing: Only print objcopy version warning once from recordmcount tracing: Prevent build warning: 'ftrace_graph_buf' defined but not used ring-buffer: Move access to commit_page up into function used tracing: do not disable interrupts for trace_clock_local ring-buffer: Add multiple iterations between benchmark timestamps kprobes: Sanitize struct kretprobe_instance allocations tracing: Fix to use __always_unused attribute compiler: Introduce __always_unused tracing: Exit with error if a weak function is used in recordmcount.pl tracing: Move conditional into update_funcs() in recordmcount.pl tracing: Add regex for weak functions in recordmcount.pl tracing: Move mcount section search to front of loop in recordmcount.pl tracing: Fix objcopy revision check in recordmcount.pl tracing: Check absolute path of input file in recordmcount.pl tracing: Correct the check for number of arguments in recordmcount.pl ...

Linus Torvalds committed 16 years ago

Commit 96fa2b52 parents 7a797cd b8007ef28 files · +856 −518Browse files

Showing the changes to scripts (1 of 28 files). Show all

Unified · Split

scripts/recordmcount.pl+120−99
@@ -6,77 +6,93 @@ · 5 unmodified lines
66 # all the offsets to the calls to mcount.
77 #
88 #
9−# What we want to end up with is a section in vmlinux called
10−# __mcount_loc that contains a list of pointers to all the
11−# call sites in the kernel that call mcount. Later on boot up, the kernel
12−# will read this list, save the locations and turn them into nops.
13−# When tracing or profiling is later enabled, these locations will then
14−# be converted back to pointers to some function.
9+# What we want to end up with this is that each object file will have a
10+# section called __mcount_loc that will hold the list of pointers to mcount
11+# callers. After final linking, the vmlinux will have within .init.data the
12+# list of all callers to mcount between __start_mcount_loc and __stop_mcount_loc.
13+# Later on boot up, the kernel will read this list, save the locations and turn
14+# them into nops. When tracing or profiling is later enabled, these locations
15+# will then be converted back to pointers to some function.
1516 #
1617 # This is no easy feat. This script is called just after the original
1718 # object is compiled and before it is linked.
1819 #
19−# The references to the call sites are offsets from the section of text
20−# that the call site is in. Hence, all functions in a section that
21−# has a call site to mcount, will have the offset from the beginning of
22−# the section and not the beginning of the function.
20+# When parse this object file using 'objdump', the references to the call
21+# sites are offsets from the section that the call site is in. Hence, all
22+# functions in a section that has a call site to mcount, will have the
23+# offset from the beginning of the section and not the beginning of the
24+# function.
25+#
26+# But where this section will reside finally in vmlinx is undetermined at
27+# this point. So we can't use this kind of offsets to record the final
28+# address of this call site.
29+#
30+# The trick is to change the call offset referring the start of a section to
31+# referring a function symbol in this section. During the link step, 'ld' will
32+# compute the final address according to the information we record.
2333 #
24−# The trick is to find a way to record the beginning of the section.
25−# The way we do this is to look at the first function in the section
26−# which will also be the location of that section after final link.
2734 # e.g.
2835 #
2936 # .section ".sched.text", "ax"
30−# .globl my_func
31−# my_func:
3237 # [...]
33−# call mcount (offset: 0x5)
38+# func1:
39+# [...]
40+# call mcount (offset: 0x10)
3441 # [...]
3542 # ret
36−# other_func:
43+# .globl fun2
44+# func2: (offset: 0x20)
3745 # [...]
38−# call mcount (offset: 0x1b)
46+# [...]
47+# ret
48+# func3:
49+# [...]
50+# call mcount (offset: 0x30)
3951 # [...]
4052 #
4153 # Both relocation offsets for the mcounts in the above example will be
42−# offset from .sched.text. If we make another file called tmp.s with:
54+# offset from .sched.text. If we choose global symbol func2 as a reference and
55+# make another file called tmp.s with the new offsets:
4356 #
4457 # .section __mcount_loc
45−# .quad my_func + 0x5
46−# .quad my_func + 0x1b
58+# .quad func2 - 0x10
59+# .quad func2 + 0x10
4760 #
48−# We can then compile this tmp.s into tmp.o, and link it to the original
61+# We can then compile this tmp.s into tmp.o, and link it back to the original
4962 # object.
5063 #
51−# But this gets hard if my_func is not globl (a static function).
52−# In such a case we have:
64+# In our algorithm, we will choose the first global function we meet in this
65+# section as the reference. But this gets hard if there is no global functions
66+# in this section. In such a case we have to select a local one. E.g. func1:
5367 #
5468 # .section ".sched.text", "ax"
55−# my_func:
69+# func1:
5670 # [...]
57−# call mcount (offset: 0x5)
71+# call mcount (offset: 0x10)
5872 # [...]
5973 # ret
60−# other_func:
74+# func2:
6175 # [...]
62−# call mcount (offset: 0x1b)
76+# call mcount (offset: 0x20)
6377 # [...]
78+# .section "other.section"
6479 #
6580 # If we make the tmp.s the same as above, when we link together with
66−# the original object, we will end up with two symbols for my_func:
81+# the original object, we will end up with two symbols for func1:
6782 # one local, one global. After final compile, we will end up with
68−# an undefined reference to my_func.
83+# an undefined reference to func1 or a wrong reference to another global
84+# func1 in other files.
6985 #
7086 # Since local objects can reference local variables, we need to find
7187 # a way to make tmp.o reference the local objects of the original object
72−# file after it is linked together. To do this, we convert the my_func
88+# file after it is linked together. To do this, we convert func1
7389 # into a global symbol before linking tmp.o. Then after we link tmp.o
74−# we will only have a single symbol for my_func that is global.
75−# We can convert my_func back into a local symbol and we are done.
90+# we will only have a single symbol for func1 that is global.
91+# We can convert func1 back into a local symbol and we are done.
7692 #
7793 # Here are the steps we take:
7894 #
79−# 1) Record all the local symbols by using 'nm'
95+# 1) Record all the local and weak symbols by using 'nm'
8096 # 2) Use objdump to find all the call site offsets and sections for
8197 # mcount.
8298 # 3) Compile the list into its own object.
@@ -86,10 +102,8 @@ · 3 unmodified lines
86102 # 6) Link together this new object with the list object.
87103 # 7) Convert the local functions back to local symbols and rename
88104 # the result as the original object.
89−# End.
90105 # 8) Link the object with the list object.
91106 # 9) Move the result back to the original object.
92−# End.
93107 #
94108
95109 use strict;
@@ -99,7 +113,7 @@ $P =~ s@.*/@@g; · 3 unmodified lines
99113
100114 my $V = '0.1';
101115
102−if ($#ARGV < 7) {
116+if ($#ARGV != 10) {
103117 print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
104118 print "version: $V\n";
105119 exit(1);
@@ -109,7 +123,7 @@ my ($arch, $bits, $objdump, $objcopy, $cc, · 3 unmodified lines
109123 $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
110124
111125 # This file refers to mcount and shouldn't be ftraced, so lets' ignore it
112−if ($inputfile eq "kernel/trace/ftrace.o") {
126+if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
113127 exit(0);
114128 }
115129
@@ -119,6 +133,7 @@ my %text_sections = ( · 3 unmodified lines
119133 ".sched.text" => 1,
120134 ".spinlock.text" => 1,
121135 ".irqentry.text" => 1,
136+ ".text.unlikely" => 1,
122137 );
123138
124139 $objdump = "objdump" if ((length $objdump) == 0);
@@ -137,13 +152,47 @@ my %weak; # List of weak functions · 12 unmodified lines
137152 my %convert; # List of local functions used that needs conversion
138153
139154 my $type;
140−my $nm_regex; # Find the local functions (return function)
155+my $local_regex; # Match a local function (return function)
156+my $weak_regex; # Match a weak function (return function)
141157 my $section_regex; # Find the start of a section
142158 my $function_regex; # Find the name of a function
143159 # (return offset and func name)
144160 my $mcount_regex; # Find the call site to mcount (return offset)
145161 my $alignment; # The .align value to use for $mcount_section
146162 my $section_type; # Section header plus possible alignment command
163+my $can_use_local = 0; # If we can use local function references
164+
165+# Shut up recordmcount if user has older objcopy
166+my $quiet_recordmcount = ".tmp_quiet_recordmcount";
167+my $print_warning = 1;
168+$print_warning = 0 if ( -f $quiet_recordmcount);
169+
170+##
171+# check_objcopy - whether objcopy supports --globalize-symbols
172+#
173+# --globalize-symbols came out in 2.17, we must test the version
174+# of objcopy, and if it is less than 2.17, then we can not
175+# record local functions.
176+sub check_objcopy
177+{
178+ open (IN, "$objcopy --version |") or die "error running $objcopy";
179+ while (<IN>) {
180+ if (/objcopy.*\s(\d+)\.(\d+)/) {
181+ $can_use_local = 1 if ($1 > 2 || ($1 == 2 && $2 >= 17));
182+ last;
183+ }
184+ }
185+ close (IN);
186+
187+ if (!$can_use_local && $print_warning) {
188+ print STDERR "WARNING: could not find objcopy version or version " .
189+ "is less than 2.17.\n" .
190+ "\tLocal function references are disabled.\n";
191+ open (QUIET, ">$quiet_recordmcount");
192+ printf QUIET "Disables the warning from recordmcount.pl\n";
193+ close QUIET;
194+ }
195+}
147196
148197 if ($arch eq "x86") {
149198 if ($bits == 64) {
@@ -157,7 +206,8 @@ if ($arch eq "x86") { · 7 unmodified lines
157206 # We base the defaults off of i386, the other archs may
158207 # feel free to change them in the below if statements.
159208 #
160−$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
209+$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
210+$weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
161211 $section_regex = "Disassembly of section\\s+(\\S+):";
162212 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
163213 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
@@ -206,7 +256,7 @@ if ($arch eq "x86_64") { · 42 unmodified lines
206256 $cc .= " -m32";
207257
208258 } elsif ($arch eq "powerpc") {
209− $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
259+ $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
210260 $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
211261 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
212262
@@ -278,44 +328,17 @@ if ($filename =~ m,^(.*)(\.\S),) { · 65 unmodified lines
278328 my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
279329 my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
280330
281−#
282−# --globalize-symbols came out in 2.17, we must test the version
283−# of objcopy, and if it is less than 2.17, then we can not
284−# record local functions.
285−my $use_locals = 01;
286−my $local_warn_once = 0;
287−my $found_version = 0;
288−
289−open (IN, "$objcopy --version |") || die "error running $objcopy";
290−while (<IN>) {
291− if (/objcopy.*\s(\d+)\.(\d+)/) {
292− my $major = $1;
293− my $minor = $2;
294−
295− $found_version = 1;
296− if ($major < 2 ||
297− ($major == 2 && $minor < 17)) {
298− $use_locals = 0;
299− }
300− last;
301− }
302−}
303−close (IN);
304−
305−if (!$found_version) {
306− print STDERR "WARNING: could not find objcopy version.\n" .
307− "\tDisabling local function references.\n";
308−}
331+check_objcopy();
309332
310333 #
311334 # Step 1: find all the local (static functions) and weak symbols.
312−# 't' is local, 'w/W' is weak (we never use a weak function)
335+# 't' is local, 'w/W' is weak
313336 #
314337 open (IN, "$nm $inputfile|") || die "error running $nm";
315338 while (<IN>) {
316− if (/$nm_regex/) {
339+ if (/$local_regex/) {
317340 $locals{$1} = 1;
318− } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
341+ } elsif (/$weak_regex/) {
319342 $weak{$2} = $1;
320343 }
321344 }
@@ -333,26 +356,20 @@ my $offset = 0; # offset of ref_func to section beginning · 11 unmodified lines
333356 #
334357 sub update_funcs
335358 {
336− return if ($#offsets < 0);
337−
338− defined($ref_func) || die "No function to reference";
359+ return unless ($ref_func and @offsets);
339360
340− # A section only had a weak function, to represent it.
341− # Unfortunately, a weak function may be overwritten by another
342− # function of the same name, making all these offsets incorrect.
343− # To be safe, we simply print a warning and bail.
361+ # Sanity check on weak function. A weak function may be overwritten by
362+ # another function of the same name, making all these offsets incorrect.
344363 if (defined $weak{$ref_func}) {
345− print STDERR
346− "$inputfile: WARNING: referencing weak function" .
364+ die "$inputfile: ERROR: referencing weak function" .
347365 " $ref_func for mcount\n";
348− return;
349366 }
350367
351368 # is this function static? If so, note this fact.
352369 if (defined $locals{$ref_func}) {
353370
354371 # only use locals if objcopy supports globalize-symbols
355− if (!$use_locals) {
372+ if (!$can_use_local) {
356373 return;
357374 }
358375 $convert{$ref_func} = 1;
@@ -378,9 +395,27 @@ open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump"; · 19 unmodified lines
378395
379396 my $text;
380397
398+
399+# read headers first
381400 my $read_headers = 1;
382401
383402 while (<IN>) {
403+
404+ if ($read_headers && /$mcount_section/) {
405+ #
406+ # Somehow the make process can execute this script on an
407+ # object twice. If it does, we would duplicate the mcount
408+ # section and it will cause the function tracer self test
409+ # to fail. Check if the mcount section exists, and if it does,
410+ # warn and exit.
411+ #
412+ print STDERR "ERROR: $mcount_section already in $inputfile\n" .
413+ "\tThis may be an indication that your build is corrupted.\n" .
414+ "\tDelete $inputfile and try again. If the same object file\n" .
415+ "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
416+ exit(-1);
417+ }
418+
384419 # is it a section?
385420 if (/$section_regex/) {
386421 $read_headers = 0;
@@ -392,7 +427,7 @@ while (<IN>) { · 5 unmodified lines
392427 $read_function = 0;
393428 }
394429 # print out any recorded offsets
395− update_funcs() if (defined($ref_func));
430+ update_funcs();
396431
397432 # reset all markers and arrays
398433 $text_found = 0;
@@ -421,21 +456,7 @@ while (<IN>) { · 22 unmodified lines
421456 $offset = hex $1;
422457 }
423458 }
424− } elsif ($read_headers && /$mcount_section/) {
425− #
426− # Somehow the make process can execute this script on an
427− # object twice. If it does, we would duplicate the mcount
428− # section and it will cause the function tracer self test
429− # to fail. Check if the mcount section exists, and if it does,
430− # warn and exit.
431− #
432− print STDERR "ERROR: $mcount_section already in $inputfile\n" .
433− "\tThis may be an indication that your build is corrupted.\n" .
434− "\tDelete $inputfile and try again. If the same object file\n" .
435− "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
436− exit(-1);
437459 }
438−
439460 # is this a call site to mcount? If so, record it to print later
440461 if ($text_found && /$mcount_regex/) {
441462 $offsets[$#offsets + 1] = hex $1;
@@ -443,7 +464,7 @@ while (<IN>) { · 1 unmodified line
443464 }
444465
445466 # dump out anymore offsets that may have been found
446−update_funcs() if (defined($ref_func));
467+update_funcs();
447468
448469 # If we did not find any mcount callers, we are done (do nothing).
449470 if (!$opened) {