10 Mar, 2011

1 commit


04 Dec, 2010

2 commits


30 Oct, 2010

2 commits

  • Since MIPS modules' address space differs from the core kernel space, to access
    the _mcount in the core kernel, the kernel functions in modules must use long
    call (-mlong-calls): load the _mcount address into one register and jump to the
    address stored by the register:

    c: 3c030000 lui v1,0x0 b label
    c: R_MIPS_HI16 _mcount
    c: R_MIPS_NONE *ABS*
    c: R_MIPS_NONE *ABS*
    10: 64630000 daddiu v1,v1,0
    10: R_MIPS_LO16 _mcount
    10: R_MIPS_NONE *ABS*
    10: R_MIPS_NONE *ABS*
    14: 03e0082d move at,ra
    18: 0060f809 jalr v1
    label:

    In the old Perl version of recordmcount, we only need to record the position of
    the 1st R_MIPS_HI16 type of _mcount, and later, in ftrace_make_nop(), replace
    the instruction in this position by a "b label" and in ftrace_make_call(),
    replace it back.

    But, the default C version of recordmcount records all of the _mcount symbols,
    so, we must filter the 2nd _mcount like the Perl version of recordmcount does.

    The C version of recordmcount copes with the symbols before they are linked, So
    It doesn't know the type of the symbols and therefore can not filter the
    symbols as the Perl version of recordmcount does. But as we can see above, the
    2nd _mcount symbols of the long call alawys follows the 1st _mcount symbol of
    the same long call, which means the offset from the 1st to the 2nd is fixed, it
    is 0x10-0xc = 4 here, 4 is the length of the 1st load instruciton, for MIPS has
    fixed length of instructions, this offset is always 4.

    And as we know, the _mcount is inserted into the entry of every kernel
    function, the offset between the other _mcount's is expected to be always
    bigger than 4. So, to filter the 2ns _mcount symbol of the long call, we can
    simply check the offset between two _mcount symbols, If it is 4, then, filter
    the 2nd _mcount symbol.

    To avoid touching too much code, an 'empty' function fn_is_fake_mcount() is
    added for all of the archs, and the specific archs can override it via chaning
    the function pointer: is_fake_mcount in do_file() with the e_machine. e.g. This
    patch adds MIPS_is_fake_mcount() to override the default fn_is_fake_mcount()
    pointed by is_fake_mcount.

    This fn_is_fake_mcount() checks if the _mcount symbol is fake, e.g. the 2nd
    _mcount symbol of the long call is fake, for there are 2 _mcount symbols mapped
    to one real mcount call, so, one of them is fake and must be filtered.

    This fn_is_fake_mcount() is called in sift_rel_mcount() after finding the
    _mcount symbols and before adding the _mcount symbol into mrelp, so, it can
    prevent the fake mcount symbol going into the last __mcount_loc table.

    Signed-off-by: Wu Zhangjin
    LKML-Reference:
    Signed-off-by: Steven Rostedt
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • MIPS64 has 'weird' Elf64_Rel.r_info[1,2], which must be used instead of
    the generic Elf64_Rel.r_info, otherwise, the C version of recordmcount
    will not work for "segmentation fault".

    Usage of "union mips_r_info" and the functions MIPS64_r_sym() and
    MIPS64_r_info() written by Maciej W. Rozycki

    ----
    [1] http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf
    [2] arch/mips/include/asm/module.h

    Tested-by: Wu Zhangjin
    Signed-off-by: John Reiser
    Signed-off-by: Maciej W. Rozycki
    LKML-Reference:
    LKML-Reference:
    Signed-off-by: Steven Rostedt
    Signed-off-by: Ralf Baechle

    John Reiser
     

15 Oct, 2010

3 commits

  • The file kernel/trace/ftrace.c references the mcount() call to
    convert the mcount() callers to nops. But because it references
    mcount(), the mcount() address is placed in the relocation table.

    The C version of recordmcount reads the relocation table of all
    object files, and it will add all references to mcount to the
    __mcount_loc table that is used to find the places that call mcount()
    and change the call to a nop. When recordmcount finds the mcount reference
    in kernel/trace/ftrace.o, it saves that location even though the code
    is not a call, but references mcount as data.

    On boot up, when all calls are converted to nops, the code has a safety
    check to determine what op code it is actually replacing before it
    replaces it. If that op code at the address does not match, then
    a warning is printed and the function tracer is disabled.

    The reference to mcount in ftrace.c, causes this warning to trigger,
    since the reference is not a call to mcount(). The ftrace.c file is
    not compiled with the -pg flag, so no calls to mcount() should be
    expected.

    This patch simply makes recordmcount.c skip the kernel/trace/ftrace.c
    file. This was the same solution used by the perl version of
    recordmcount.

    Reported-by: Ingo Molnar
    Cc: John Reiser
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • The elf reader for recordmcount.c had duplicate functions for both
    32 bit and 64 bit elf handling. This was due to the need of using
    the 32 and 64 bit elf structures.

    This patch consolidates the two by using macros to define the 32
    and 64 bit names in a recordmcount.h file, and then by just defining
    a RECORD_MCOUNT_64 macro and including recordmcount.h twice we
    create the funtions for both the 32 bit version as well as the
    64 bit version using one code source.

    Cc: John Reiser
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • Currently, the mcount callers are found with a perl script that does
    an objdump on every file in the kernel. This is a C version of that
    same code which should increase the performance time of compiling
    the kernel with dynamic ftrace enabled.

    Signed-off-by: John Reiser

    [ Updated the code to include .text.unlikely section as well as
    changing the format to follow Linux coding style. ]

    Signed-off-by: Steven Rostedt

    John Reiser