linux/scripts/recordmcount.h

692 lines
19 KiB

ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
2014-06-17 10:39:53 +01:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
2014-06-17 10:39:53 +01:00
ftrace/MIPS: Add module support for C version of recordmcount 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 <wuzhangjin@gmail.com> LKML-Reference: <b866f0138224340a132d31861fa3f9300dee30ac.1288176026.git.wuzhangjin@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2010-10-27 18:59:08 +08:00
recordmcount: Fix spurious mcount entries on powerpc An impending change to enable HAVE_C_RECORDMCOUNT on powerpc leads to warnings such as the following: # modprobe kprobe_example ftrace-powerpc: Not expected bl: opcode is 3c4c0001 WARNING: CPU: 0 PID: 227 at kernel/trace/ftrace.c:2001 ftrace_bug+0x90/0x318 Modules linked in: CPU: 0 PID: 227 Comm: modprobe Not tainted 5.2.0-rc6-00678-g1c329100b942 #2 NIP: c000000000264318 LR: c00000000025d694 CTR: c000000000f5cd30 REGS: c000000001f2b7b0 TRAP: 0700 Not tainted (5.2.0-rc6-00678-g1c329100b942) MSR: 900000010282b033 <SF,HV,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 28228222 XER: 00000000 CFAR: c0000000002642fc IRQMASK: 0 <snip> NIP [c000000000264318] ftrace_bug+0x90/0x318 LR [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 Call Trace: [c000000001f2ba40] [0000000000000004] 0x4 (unreliable) [c000000001f2bad0] [c00000000025d694] ftrace_process_locs+0x4f4/0x5e0 [c000000001f2bb90] [c00000000020ff10] load_module+0x25b0/0x30c0 [c000000001f2bd00] [c000000000210cb0] sys_finit_module+0xc0/0x130 [c000000001f2be20] [c00000000000bda4] system_call+0x5c/0x70 Instruction dump: 419e0018 2f83ffff 419e00bc 2f83ffea 409e00cc 4800001c 0fe00000 3c62ff96 39000001 39400000 386386d0 480000c4 <0fe00000> 3ce20003 39000001 3c62ff96 ---[ end trace 4c438d5cebf78381 ]--- ftrace failed to modify [<c0080000012a0008>] 0xc0080000012a0008 actual: 01:00:4c:3c Initializing ftrace call sites ftrace record flags: 2000000 (0) expected tramp: c00000000006af4c Looking at the relocation records in __mcount_loc shows a few spurious entries: RELOCATION RECORDS FOR [__mcount_loc]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_ADDR64 .text.unlikely+0x0000000000000008 0000000000000008 R_PPC64_ADDR64 .text.unlikely+0x0000000000000014 0000000000000010 R_PPC64_ADDR64 .text.unlikely+0x0000000000000060 0000000000000018 R_PPC64_ADDR64 .text.unlikely+0x00000000000000b4 0000000000000020 R_PPC64_ADDR64 .init.text+0x0000000000000008 0000000000000028 R_PPC64_ADDR64 .init.text+0x0000000000000014 The first entry in each section is incorrect. Looking at the relocation records, the spurious entries correspond to the R_PPC64_ENTRY records: RELOCATION RECORDS FOR [.text.unlikely]: OFFSET TYPE VALUE 0000000000000000 R_PPC64_REL64 .TOC.-0x0000000000000008 0000000000000008 R_PPC64_ENTRY *ABS* 0000000000000014 R_PPC64_REL24 _mcount <snip> The problem is that we are not validating the return value from get_mcountsym() in sift_rel_mcount(). With this entry, mcountsym is 0, but Elf_r_sym(relp) also ends up being 0. Fix this by ensuring mcountsym is valid before processing the entry. Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Tested-by: Satheesh Rajendran <sathnaga@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2019-06-27 00:08:01 +05:30