linux-stable-rt/scripts
Steven Rostedt 8da3821ba5 ftrace: create __mcount_loc section
This patch creates a section in the kernel called "__mcount_loc".
This will hold a list of pointers to the mcount relocation for
each call site of mcount.

For example:

objdump -dr init/main.o
[...]
Disassembly of section .text:

0000000000000000 <do_one_initcall>:
   0:   55                      push   %rbp
[...]
000000000000017b <init_post>:
 17b:   55                      push   %rbp
 17c:   48 89 e5                mov    %rsp,%rbp
 17f:   53                      push   %rbx
 180:   48 83 ec 08             sub    $0x8,%rsp
 184:   e8 00 00 00 00          callq  189 <init_post+0xe>
                        185: R_X86_64_PC32      mcount+0xfffffffffffffffc
[...]

We will add a section to point to each function call.

   .section __mcount_loc,"a",@progbits
[...]
   .quad .text + 0x185
[...]

The offset to of the mcount call site in init_post is an offset from
the start of the section, and not the start of the function init_post.
The mcount relocation is at the call site 0x185 from the start of the
.text section.

  .text + 0x185  == init_post + 0xa

We need a way to add this __mcount_loc section in a way that we do not
lose the relocations after final link.  The .text section here will
be attached to all other .text sections after final link and the
offsets will be meaningless.  We need to keep track of where these
.text sections are.

To do this, we use the start of the first function in the section.
do_one_initcall.  We can make a tmp.s file with this function as a reference
to the start of the .text section.

   .section __mcount_loc,"a",@progbits
[...]
   .quad do_one_initcall + 0x185
[...]

Then we can compile the tmp.s into a tmp.o

  gcc -c tmp.s -o tmp.o

And link it into back into main.o.

  ld -r main.o tmp.o -o tmp_main.o
  mv tmp_main.o main.o

But we have a problem.  What happens if the first function in a section
is not exported, and is a static function. The linker will not let
the tmp.o use it.  This case exists in main.o as well.

Disassembly of section .init.text:

0000000000000000 <set_reset_devices>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   e8 00 00 00 00          callq  9 <set_reset_devices+0x9>
                        5: R_X86_64_PC32        mcount+0xfffffffffffffffc

The first function in .init.text is a static function.

00000000000000a8 t __setup_set_reset_devices
000000000000105f t __setup_str_set_reset_devices
0000000000000000 t set_reset_devices

The lowercase 't' means that set_reset_devices is local and is not exported.
If we simply try to link the tmp.o with the set_reset_devices we end
up with two symbols: one local and one global.

 .section __mcount_loc,"a",@progbits
 .quad set_reset_devices + 0x10

00000000000000a8 t __setup_set_reset_devices
000000000000105f t __setup_str_set_reset_devices
0000000000000000 t set_reset_devices
                 U set_reset_devices

We still have an undefined reference to set_reset_devices, and if we try
to compile the kernel, we will end up with an undefined reference to
set_reset_devices, or even worst, it could be exported someplace else,
and then we will have a reference to the wrong location.

To handle this case, we make an intermediate step using objcopy.
We convert set_reset_devices into a global exported symbol before linking
it with tmp.o and set it back afterwards.

00000000000000a8 t __setup_set_reset_devices
000000000000105f t __setup_str_set_reset_devices
0000000000000000 T set_reset_devices

00000000000000a8 t __setup_set_reset_devices
000000000000105f t __setup_str_set_reset_devices
0000000000000000 T set_reset_devices

00000000000000a8 t __setup_set_reset_devices
000000000000105f t __setup_str_set_reset_devices
0000000000000000 t set_reset_devices

Now we have a section in main.o called __mcount_loc that we can place
somewhere in the kernel using vmlinux.ld.S and access it to convert
all these locations that call mcount into nops before starting SMP
and thus, eliminating the need to do this with kstop_machine.

Note, A well documented perl script (scripts/recordmcount.pl) is used
to do all this in one location.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2008-10-14 10:34:40 +02:00
..
basic kernel-doc: new P directive for DOC: sections 2008-01-28 23:14:35 +01:00
genksyms kbuild: genksyms: Include extern information in dumps 2008-07-31 23:01:31 +02:00
kconfig kconfig: readd lost change count 2008-09-29 08:03:01 -07:00
ksymoops
mod Marker depmod fix core kernel list 2008-10-06 16:34:19 -07:00
package Kbuild: Fix deb-pkg target to work with kernel versions ending with -<text-without-digit> 2008-02-09 10:51:47 +01:00
rt-tester
selinux SELinux: add gitignore file for mdp script 2008-09-05 21:43:38 +10:00
.gitignore Add binoffset to gitignore 2008-02-09 10:43:58 +01:00
Kbuild.include kbuild: fix cc-option and cc-option-yn 2008-09-09 11:52:33 -07:00
Lindent scripts/Lindent: support gnu indent v2.2.10 2008-04-29 08:06:04 -07:00
Makefile selinux: add support for installing a dummy policy (v2) 2008-08-27 08:54:08 +10:00
Makefile.build ftrace: create __mcount_loc section 2008-10-14 10:34:40 +02:00
Makefile.clean kbuild: fix some minor typoes 2008-04-25 20:18:48 +02:00
Makefile.fwinst firmware: silence __fw_modbuild and __fw_modinst 'Nothing to be done' messages 2008-08-02 07:52:29 +01:00
Makefile.headersinst kbuild: install all headers when arch is changed 2008-07-25 22:12:18 +02:00
Makefile.host kbuild: fix some minor typoes 2008-04-25 20:18:48 +02:00
Makefile.lib kbuild: create new CFLAGS_REMOVE_(basename).o option 2008-05-23 22:43:33 +02:00
Makefile.modinst kbuild: fix installing external modules 2008-01-28 23:14:36 +01:00
Makefile.modpost markers: fix duplicate modpost entry 2008-07-22 09:59:41 -07:00
bin2c.c
binoffset.c
bloat-o-meter fix bloat-o-meter for ppc64 2007-12-17 19:28:17 -08:00
checkincludes.pl
checkkconfigsymbols.sh
checkpatch.pl checkpatch: version 0.21 2008-07-24 10:47:27 -07:00
checkstack.pl [S390] Fix checkstack for s390 2008-10-10 21:34:03 +02:00
checksyscalls.sh
checkversion.pl
cleanfile
cleanpatch
conmakehash.c
decodecode Mark 'scripts/decodecode' executable 2008-05-30 14:02:21 -07:00
diffconfig kconfig: add diffconfig utility 2008-07-25 22:12:41 +02:00
export_report.pl
extract-ikconfig
gcc-version.sh kbuild: fix buglet in gcc-version.sh 2008-01-28 23:14:36 +01:00
gcc-x86_64-has-stack-protector.sh
gen_initramfs_list.sh kbuild: fix unportability in gen_initramfs_list.sh 2008-04-28 22:50:51 +02:00
headers.sh kbuild: prepare headers_* for arch/$ARCH/include 2008-07-25 22:12:33 +02:00
headers_check.pl kbuild: optimize headers_* targets 2008-07-25 22:12:16 +02:00
headers_install.pl kbuild: install all headers when arch is changed 2008-07-25 22:12:18 +02:00
kallsyms.c kbuild: filter away debug symbols from kernel symbols 2008-05-19 20:07:58 +02:00
kernel-doc kernel-doc: allow structs whose members are all private 2008-09-23 08:09:13 -07:00
makelst
mkcompile_h
mkmakefile kbuild: scripts/mkmakefile: dynamic determination of output directory 2008-01-28 23:14:38 +01:00
mksysmap kbuild: filter away debug symbols from kernel symbols 2008-05-19 20:07:58 +02:00
mkuboot.sh
mkversion
namespace.pl
patch-kernel bugfix for scripts/patch-kernel in 2.6 sublevel stepping 2008-08-06 22:11:33 +02:00
pnmtologo.c
profile2linkerlist.pl
recordmcount.pl ftrace: create __mcount_loc section 2008-10-14 10:34:40 +02:00
setlocalversion setlocalversion: do not describe if there is nothing to describe 2008-07-25 22:12:53 +02:00
show_delta
unifdef.c
ver_linux kbuild: scripts/ver_linux: don't set PATH 2008-07-31 23:36:54 +02:00