07 Jan, 2012

1 commit

  • In ELF64, the sh_flags field is 64-bits wide. recordmcount was
    erroneously treating it as a 32-bit wide field. For little endian
    objects this works because the flags of interest (SHF_EXECINSTR)
    reside in the lower 32 bits of the word, and you get the same result
    with either a 32-bit or 64-bit read. Big endian objects on the
    other hand do not work at all with this error.

    The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects.

    The symptom I observed was that my
    __start_mcount_loc..__stop_mcount_loc was empty even though ftrace
    function tracing was enabled.

    Link: http://lkml.kernel.org/r/1324345362-12230-1-git-send-email-ddaney.cavm@gmail.com

    Cc: stable@kernel.org # 3.0+
    Signed-off-by: David Daney
    Signed-off-by: Steven Rostedt

    David Daney
     

26 May, 2011

1 commit

  • While find_secsym_ndx often finds the unamed local STT_SECTION, if a
    section has only one function in it, the ARM toolchain generates the
    STT_FUNC symbol before the STT_SECTION, and recordmcount finds this
    instead.

    This is problematic on ARM because in ARM ELFs, "if a [STT_FUNC] symbol
    addresses a Thumb instruction, its value is the address of the
    instruction with bit zero set (in a relocatable object, the section
    offset with bit zero set)". This leads to incorrect mcount addresses
    being recorded.

    Fix this by not using STT_FUNC symbols as the base on ARM.

    Signed-off-by: Rabin Vincent
    Link: http://lkml.kernel.org/r/1305134631-31617-1-git-send-email-rabin@rab.in
    Signed-off-by: Steven Rostedt

    Rabin Vincent
     

17 May, 2011

7 commits

  • Introduce mcount_adjust{,_32,_64} to the C implementation of
    recordmcount analog to $mcount_adjust in the perl script.
    The adjustment is added to the address of the relocations
    against the mcount symbol. If this adjustment is done by
    recordmcount at compile time the ftrace_call_adjust function
    can be turned into a nop.

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

    Martin Schwidefsky
     
  • The code to get the symbol, string, and relp pointers in the two functions
    sift_rel_mcount() and nop_mcount() are identical and also non-trivial.
    Moving this duplicate code into a single helper function makes the code
    easier to read and more maintainable.

    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023739.723658553@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • The code in sift_rel_mcount() and nop_mcount() to get the mcount symbol
    number is identical. Replace the two locations with a call to a function
    that does the work.

    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023739.488093407@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • There's some sections that should not have mcount recorded and should not have
    modifications to the that code. But currently they waste some time by calling
    mcount anyway (which simply returns). As the real answer should be to
    either whitelist the section or have gcc ignore it fully.

    This change adds a option to recordmcount to warn when it finds a section
    that is ignored by ftrace but still contains mcount callers. This is not on
    by default as developers may not know if the section should be completely
    ignored or added to the whitelist.

    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023738.476989377@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • There are sections that are ignored by ftrace for the function tracing because
    the text is in a section that can be removed without notice. The mcount calls
    in these sections are ignored and ftrace never sees them. The downside of this
    is that the functions in these sections still call mcount. Although the mcount
    function is defined in assembly simply as a return, this added overhead is
    unnecessary.

    The solution is to convert these callers into nops at compile time.
    A better solution is to add 'notrace' to the section markers, but as new sections
    come up all the time, it would be nice that they are delt with when they
    are created.

    Later patches will deal with finding these sections and doing the proper solution.

    Thanks to H. Peter Anvin for giving me the right nops to use for x86.

    Cc: "H. Peter Anvin"
    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023738.237101176@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • PROGBITS is not enough to determine if the section should be modified
    or not. Only process sections that are marked as executable.

    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023737.991485123@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • The Linux ftrace subsystem style for comparing is:

    var == 1
    var > 0

    and not:

    1 == var
    0 < var

    It is considered that Linux developers are smart enough not to do the

    if (var = 1)

    mistake.

    Cc: John Reiser
    Link: http://lkml.kernel.org/r/20110421023737.290712238@goodmis.org
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     

06 Jan, 2011

1 commit


04 Dec, 2010

1 commit


02 Dec, 2010

1 commit

  • It looks to me like the change which introduced "virtual functions"
    forgot about cross-platform endianness.

    Thank you to Arnaud for supplying before+after data files do_mounts*.o.

    This fixes a MIPS build failure triggered by recordmcount.

    Reported-by: Arnaud Lacombe
    Tested-by: Arnaud Lacombe
    Acked-by: Wu Zhangjin
    Acked-by: Ralf Baechle
    Signed-off-by: John Reiser
    Signed-off-by: Steven Rostedt

    John Reiser
     

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

1 commit

  • 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