ftrace/recordmcount: cleanups and updates for recordmcount processing
Steven Rostedt
maintainerIngo,
Please pull the latest tip/perf/core-2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core-2
Martin Schwidefsky (3):
ftrace/recordmcount: mcount address adjustment ftrace/x86: mcount offset calculation ftrace/s390: mcount offset calculation
Michal Marek (1):
ftrace/kbuild: Add recordmcount files to force full build
Steven Rostedt (11):
ftrace/trivial: Clean up recordmcount.c to use Linux style comparisons ftrace/trivial: Clean up record mcount to use Linux switch style
ftrace: Add .kprobe.text section to whitelist for recordmcount.c ftrace/recordmcount: Modify only executable sections ftrace/recordmcount: Make ignored mcount calls into nops at compile time ftrace/recordmcount: Add warning logic to warn on mcount not recorded kbuild/recordmcount: Add RECORDMCOUNT_WARN to warn about mcount callers
ftrace: Avoid recording mcount on .init sections directly ftrace/x86: Do not trace .discard.text section ftrace/recordmcount: Remove duplicate code to find mcount symbol ftrace/recordmcount: Add helper function get_sym_str_and_relp()
----
Makefile | 1 + arch/s390/include/asm/ftrace.h | 4 +- arch/x86/include/asm/ftrace.h | 7 +- arch/x86/include/asm/setup.h | 2 +- include/linux/init.h | 14 ++-- scripts/Makefile.build | 12 ++- scripts/recordmcount.c | 168 ++++++++++++++++++++++++++------------ scripts/recordmcount.h | 174 +++++++++++++++++++++++++++++++-------- scripts/recordmcount.pl | 5 + 9 files changed, 279 insertions(+), 108 deletions(-)
Steven Rostedt
maintainerPATCH 1/15 ftrace/kbuild: Add recordmcount files to force full build
From: Michal Marek <[email protected]>
Modifications to recordmcount must be performed on all object files to stay consistent with what the kernel code may expect. Add the recordmcount files to the main dependencies to make sure any change to them causes a full recompile.
--- scripts/Makefile.build | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
scripts/Makefile.build +5 -2
@@ -252,6 +252,8 @@ sub_cmd_record_mcount = \ if [ $(@) != "scripts/mod/empty.o" ]; then \ $(objtree)/scripts/recordmcount "$(@)"; \ fi; +recordmcount_source := $(srctree)/scripts/recordmcount.c \ + $(srctree)/scripts/recordmcount.h else sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
@@ -259,6 +261,7 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \ "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; +recordmcount_source := $(srctree)/scripts/recordmcount.pl endif cmd_record_mcount = \ if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
@@ -279,13 +282,13 @@ define rule_cc_o_c endef # Built-in and composite module parts -$(obj)/%.o: $(src)/%.c FORCE +$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) # Single-part modules are special since we need to mark them in $(MODVERDIR) -$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE +$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 2/15 ftrace/trivial: Clean up recordmcount.c to use Linux style
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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.
--- scripts/recordmcount.c | 48 ++++++++++++++++++++++++------------------------ scripts/recordmcount.h | 16 ++++++++-------- 2 files changed, 32 insertions(+), 32 deletions(-)
scripts/recordmcount.c +24 -24
@@ -78,7 +78,7 @@ static off_t ulseek(int const fd, off_t const offset, int const whence) { off_t const w = lseek(fd, offset, whence); -if ((off_t)-1 == w) { +if (w == (off_t)-1 ) {perror ("lseek" );fail_file (); }
@@ -111,7 +111,7 @@ static void * umalloc(size_t size) {void *const addr =malloc (size); -if (0 == addr) { +if (addr ==0 ) {fprintf (stderr,"malloc failed: %zu bytes\n" , size);fail_file (); }
@@ -136,7 +136,7 @@ static void *mmap_file(char const *fname)void *addr; fd_map =open (fname,O_RDWR ); -if (0 > fd_map ||0 >fstat (fd_map, &sb)) { +if (fd_map <0 ||fstat (fd_map, &sb) <0 ) {perror (fname);fail_file (); }
@@ -147,7 +147,7 @@ static void *mmap_file(char const *fname) addr =mmap (0 , sb.st_size,PROT_READ |PROT_WRITE ,MAP_PRIVATE , fd_map,0 ); mmap_failed =0 ; -if (MAP_FAILED == addr) { +if (addr ==MAP_FAILED ) { mmap_failed =1 ; addr =umalloc (sb.st_size);uread (fd_map, addr, sb.st_size);
@@ -206,12 +206,12 @@ static uint32_t (*w2)(uint16_t);static int is_mcounted_section_name (char const *const txtname) { -return 0 ==strcmp (".text" , txtname) || -0 ==strcmp (".ref.text" , txtname) || -0 ==strcmp (".sched.text" , txtname) || -0 ==strcmp (".spinlock.text" , txtname) || -0 ==strcmp (".irqentry.text" , txtname) || -0 ==strcmp (".text.unlikely" , txtname); +return strcmp (".text" , txtname) ==0 || +strcmp (".ref.text" , txtname) ==0 || +strcmp (".sched.text" , txtname) ==0 || +strcmp (".spinlock.text" , txtname) ==0 || +strcmp (".irqentry.text" , txtname) ==0 || +strcmp (".text.unlikely" , txtname) ==0 ; }/* 32 bit and 64 bit are very similar */
@@ -270,7 +270,7 @@ do_file(char const *const fname)fail_file (); }break ;case ELFDATA2LSB : { -if (1 != *(unsigned char const *)&endian) { +if (*(unsigned char const *)&endian !=1 ) {/* main() is big endian, file.o is little endian. */ w = w4rev; w2 = w2rev;
@@ -278,7 +278,7 @@ do_file(char const *const fname) } }break ;case ELFDATA2MSB : { -if (0 != *(unsigned char const *)&endian) { +if (*(unsigned char const *)&endian !=0 ) {/* main() is little endian, file.o is big endian. */ w = w4rev; w2 = w2rev;
@@ -286,9 +286,9 @@ do_file(char const *const fname) } }break ; }/* end switch */ -if (0 !=memcmp (ELFMAG , ehdr->e_ident,SELFMAG ) - ||ET_REL !=w2 (ehdr->e_type) - ||EV_CURRENT != ehdr->e_ident[EI_VERSION ]) { +if (memcmp (ELFMAG , ehdr->e_ident,SELFMAG ) !=0 + ||w2 (ehdr->e_type) !=ET_REL + || ehdr->e_ident[EI_VERSION ] !=EV_CURRENT ) {fprintf (stderr,"unrecognized ET_REL file %s\n" , fname);fail_file (); }
@@ -321,15 +321,15 @@ do_file(char const *const fname)fail_file (); }break ;case ELFCLASS32 : { -if (sizeof (Elf32_Ehdr) !=w2 (ehdr->e_ehsize) - ||sizeof (Elf32_Shdr) !=w2 (ehdr->e_shentsize)) { +if (w2 (ehdr->e_ehsize) !=sizeof (Elf32_Ehdr) + ||w2 (ehdr->e_shentsize) !=sizeof (Elf32_Shdr)) {fprintf (stderr,"unrecognized ET_REL file: %s\n" , fname);fail_file (); } -if (EM_S390 ==w2 (ehdr->e_machine)) +if (w2 (ehdr->e_machine) ==EM_S390 ) reltype =R_390_32 ; -if (EM_MIPS ==w2 (ehdr->e_machine)) { +if (w2 (ehdr->e_machine) ==EM_MIPS ) { reltype =R_MIPS_32 ; is_fake_mcount32 = MIPS32_is_fake_mcount; }
@@ -337,15 +337,15 @@ do_file(char const *const fname) }break ;case ELFCLASS64 : {Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; -if (sizeof (Elf64_Ehdr) !=w2 (ghdr->e_ehsize) - ||sizeof (Elf64_Shdr) !=w2 (ghdr->e_shentsize)) { +if (w2 (ghdr->e_ehsize) !=sizeof (Elf64_Ehdr) + ||w2 (ghdr->e_shentsize) !=sizeof (Elf64_Shdr)) {fprintf (stderr,"unrecognized ET_REL file: %s\n" , fname);fail_file (); } -if (EM_S390 ==w2 (ghdr->e_machine)) +if (w2 (ghdr->e_machine) ==EM_S390 ) reltype =R_390_64 ; -if (EM_MIPS ==w2 (ghdr->e_machine)) { +if (w2 (ghdr->e_machine) ==EM_MIPS ) { reltype =R_MIPS_64 ; Elf64_r_sym = MIPS64_r_sym; Elf64_r_info = MIPS64_r_info;
@@ -371,7 +371,7 @@ main(int argc, char const *argv[]) }/* Process each file in turn, allowing deep failure. */ -for (--argc, ++argv;0 < argc; --argc, ++argv) { +for (--argc, ++argv; argc >0 ; --argc, ++argv) {int const sjval =setjmp (jmpenv);int len;
scripts/recordmcount.h +8 -8
@@ -275,12 +275,12 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,Elf_Sym const *const symp = &sym0[Elf_r_sym (relp)];char const *symname = &str0[w (symp->st_name)]; -char const *mcount ='_' == gpfx ?"_mcount" :"mcount" ; +char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; -if ('.' == symname[0 ]) +if (symname[0 ] =='.' ) ++symname;/* ppc64 hack */ -if (0 ==strcmp (mcount, symname) || - (altmcount &&0 ==strcmp (altmcount, symname))) +if (strcmp (mcount, symname) ==0 || + (altmcount &&strcmp (altmcount, symname) ==0 )) mcountsym =Elf_r_sym (relp); }
@@ -290,7 +290,7 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, mrelp->r_offset =_w (offbase + ((void *)mlocp - (void *)mloc0));Elf_r_info (mrelp, recsym, reltype); -if (sizeof (Elf_Rela) == rel_entsize) { +if (rel_entsize ==sizeof (Elf_Rela)) { ((Elf_Rela *)mrelp)->r_addend = addend; *mlocp++ =0 ; }else
@@ -354,12 +354,12 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */Elf_Shdr const *const txthdr = &shdr0[w (relhdr->sh_info)];char const *const txtname = &shstrtab[w (txthdr->sh_name)]; -if (0 ==strcmp ("__mcount_loc" , txtname)) { +if (strcmp ("__mcount_loc" , txtname) ==0 ) {fprintf (stderr,"warning: __mcount_loc already exists: %s\n" , fname);succeed_file (); } -if (SHT_PROGBITS !=w (txthdr->sh_type) || +if (w (txthdr->sh_type) !=SHT_PROGBITS || !is_mcounted_section_name (txtname))return NULL ;return txtname;
@@ -370,7 +370,7 @@ static char const *has_rel_mcount(Elf_Shdr const *const relhdr,char const *const shstrtab, char const *const fname) { - if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type)) + if (w(relhdr->sh_type) != SHT_REL && w(relhdr->sh_type) != SHT_RELA) return NULL; return __has_rel_mcount(relhdr, shdr0, shstrtab, fname); }
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 3/15 ftrace/trivial: Clean up record mcount to use Linux switch style
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The Linux style for switch statements is:
switch (var) {
case x:
[...]
break;
}Not:
switch (var) {
case x: {
[...]
} break;--- scripts/recordmcount.c | 43 ++++++++++++++++++++++--------------------- 1 files changed, 22 insertions(+), 21 deletions(-)
scripts/recordmcount.c +22 -21
@@ -264,27 +264,27 @@ do_file(char const *const fname) w8 = w8nat;switch (ehdr->e_ident[EI_DATA ]) {static unsigned int const endian =1 ; -default : { +default :fprintf (stderr,"unrecognized ELF data encoding %d: %s\n" , ehdr->e_ident[EI_DATA ], fname);fail_file (); - }break ; -case ELFDATA2LSB : { +break ; +case ELFDATA2LSB :if (*(unsigned char const *)&endian !=1 ) {/* main() is big endian, file.o is little endian. */ w = w4rev; w2 = w2rev; w8 = w8rev; } - }break ; -case ELFDATA2MSB : { +break ; +case ELFDATA2MSB :if (*(unsigned char const *)&endian !=0 ) {/* main() is little endian, file.o is big endian. */ w = w4rev; w2 = w2rev; w8 = w8rev; } - }break ; +break ; }/* end switch */ if (memcmp (ELFMAG , ehdr->e_ident,SELFMAG ) !=0 || w2(ehdr->e_type) != ET_REL
@@ -295,11 +295,11 @@ do_file(char const *const fname) gpfx =0 ;switch (w2 (ehdr->e_machine)) { -default : { +default :fprintf (stderr,"unrecognized e_machine %d %s\n" ,w2 (ehdr->e_machine), fname);fail_file (); - }break ; +break ;case EM_386 : reltype =R_386_32 ;break ;case EM_ARM : reltype =R_ARM_ABS32 ; altmcount ="__gnu_mcount_nc" ;
@@ -315,12 +315,12 @@ do_file(char const *const fname) }/* end switch */ switch (ehdr->e_ident[EI_CLASS ]) { -default : { +default :fprintf (stderr,"unrecognized ELF class %d %s\n" , ehdr->e_ident[EI_CLASS ], fname);fail_file (); - }break ; -case ELFCLASS32 : { +break ; +case ELFCLASS32 :if (w2 (ehdr->e_ehsize) !=sizeof (Elf32_Ehdr) ||w2 (ehdr->e_shentsize) !=sizeof (Elf32_Shdr)) { fprintf(stderr,
@@ -334,7 +334,7 @@ do_file(char const *const fname) is_fake_mcount32 = MIPS32_is_fake_mcount; }do32 (ehdr, fname, reltype); - }break ; +break ;case ELFCLASS64 : {Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; if (w2(ghdr->e_ehsize) != sizeof(Elf64_Ehdr)
@@ -352,7 +352,8 @@ do_file(char const *const fname) is_fake_mcount64 = MIPS64_is_fake_mcount; }do64 (ghdr, fname, reltype); - }break ; +break ; + } }/* end switch */ cleanup ();
@@ -386,23 +387,23 @@ main(int argc, char const *argv[])continue ;switch (sjval) { -default : { +default :fprintf (stderr,"internal error: %s\n" , argv[0 ]);exit (1 ); - }break ; -case SJ_SETJMP : {/* normal sequence */ +break ; +case SJ_SETJMP :/* normal sequence */ /* Avoid problems if early cleanup() */ fd_map =-1 ; ehdr_curr =NULL ; mmap_failed =1 ;do_file (argv[0 ]); - }break ; -case SJ_FAIL : {/* error in do_file or below */ +break ; +case SJ_FAIL :/* error in do_file or below */ ++n_error; - }break ; -case SJ_SUCCEED : {/* premature success */ +break ; +case SJ_SUCCEED :/* premature success */ /* do nothing */ - }break ; +break ; }/* end switch */ }return !!n_error;
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 4/15 ftrace: Add .kprobe.text section to whitelist for recordmcount.c
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The .kprobe.text section is safe to modify mcount to nop and tracing. Add it to the whitelist in recordmcount.c and recordmcount.pl.
--- scripts/recordmcount.c | 1 + scripts/recordmcount.pl | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
scripts/recordmcount.c +1 -0
@@ -211,6 +211,7 @@ is_mcounted_section_name(char const *const txtname)strcmp (".sched.text" , txtname) ==0 ||strcmp (".spinlock.text" , txtname) ==0 ||strcmp (".irqentry.text" , txtname) ==0 || +strcmp (".kprobes.text" , txtname) ==0 ||strcmp (".text.unlikely" , txtname) ==0 ; }
scripts/recordmcount.pl +1 -0
@@ -134,6 +134,7 @@ my %text_sections = ( ".sched.text" => 1, ".spinlock.text" => 1, ".irqentry.text" => 1, + ".kprobes.text" => 1, ".text.unlikely" => 1, );
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 5/15 ftrace/recordmcount: Modify only executable sections
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
PROGBITS is not enough to determine if the section should be modified or not. Only process sections that are marked as executable.
--- scripts/recordmcount.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
scripts/recordmcount.h +1 -0
@@ -360,6 +360,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */succeed_file (); }if (w (txthdr->sh_type) !=SHT_PROGBITS || + !(w (txthdr->sh_flags) &SHF_EXECINSTR ) || !is_mcounted_section_name (txtname))return NULL ;return txtname;
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 6/15 ftrace/recordmcount: Make ignored mcount calls into nops at compile
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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.
--- scripts/recordmcount.c | 40 ++++++++++++++++++++++- scripts/recordmcount.h | 82 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 116 insertions(+), 6 deletions(-)
scripts/recordmcount.c +38 -2
@@ -118,6 +118,34 @@ umalloc(size_t size)return addr; } +static unsigned char ideal_nop5_x86_64[5 ] = {0x0f ,0x1f ,0x44 ,0x00 ,0x00 }; +static unsigned char ideal_nop5_x86_32[5 ] = {0x3e ,0x8d ,0x74 ,0x26 ,0x00 }; +static unsigned char *ideal_nop; + +static char rel_type_nop; + +static int (*make_nop)(void *map,size_t const offset); + +static int make_nop_x86 (void *map,size_t const offset) +{ +uint32_t *ptr; +unsigned char *op; + +/* Confirm we have 0xe8 0x0 0x0 0x0 0x0 */ + ptr = map + offset; +if (*ptr !=0 ) +return -1 ; + + op = map + offset -1 ; +if (*op !=0xe8 ) +return -1 ; + +/* convert to nop */ +ulseek (fd_map, offset -1 ,SEEK_SET ); +uwrite (fd_map, ideal_nop,5 ); +return 0 ; +} +/* * Get the whole file as a programming convenience in order to avoid * malloc+lseek+read+free of many pieces. If successful, then mmap
@@ -301,7 +329,11 @@ do_file(char const *const fname) w2(ehdr->e_machine), fname);fail_file ();break ; -case EM_386 : reltype =R_386_32 ;break ; +case EM_386 : + reltype =R_386_32 ; + make_nop = make_nop_x86; + ideal_nop = ideal_nop5_x86_32; +break ;case EM_ARM : reltype =R_ARM_ABS32 ; altmcount ="__gnu_mcount_nc" ;break ;
@@ -312,7 +344,11 @@ do_file(char const *const fname)case EM_S390 :/* reltype: e_class */ gpfx ='_' ;break ;case EM_SH : reltype =R_SH_DIR32 ;break ;case EM_SPARCV9 : reltype =R_SPARC_64 ; gpfx ='_' ;break ; -case EM_X86_64 : reltype =R_X86_64_64 ;break ; +case EM_X86_64 : + make_nop = make_nop_x86; + ideal_nop = ideal_nop5_x86_64; + reltype =R_X86_64_64 ; +break ; }/* end switch */ switch (ehdr->e_ident[EI_CLASS ]) {
scripts/recordmcount.h +78 -4
132 lines not on this page · raw message
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 7/15 ftrace/recordmcount: Add warning logic to warn on mcount not
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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.
--- scripts/recordmcount.c | 32 ++++++++++++++++++++++++-------- scripts/recordmcount.h | 22 +++++++++++++++++----- 2 files changed, 41 insertions(+), 13 deletions(-)
scripts/recordmcount.c +24 -8
@@ -24,6 +24,7 @@#include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> +#include <getopt.h> #include <elf.h> #include <fcntl.h> #include <setjmp.h>
@@ -39,6 +40,7 @@ static char gpfx; /* prefix for global symbol name (sometimes '_') */static struct stat sb;/* Remember .st_size, etc. */ static jmp_buf jmpenv;/* setjmp/longjmp per-file error escape */ static const char *altmcount;/* alternate mcount symbol name */ +static int warn_on_notrace_sect;/* warn when section has mcount not being recorded */ /* setjmp() return values */ enum {
@@ -397,19 +399,33 @@ do_file(char const *const fname) }int -main (int argc,char const *argv[]) +main (int argc,char *argv[]) {const char ftrace[] ="/ftrace.o" ;int ftrace_size =sizeof (ftrace) -1 ;int n_error =0 ;/* gcc-4.3.0 false positive complaint */ +int c; +int i; -if (argc <=1 ) { -fprintf (stderr,"usage: recordmcount file.o...\n" ); +while ((c =getopt (argc, argv,"w" )) >=0 ) { +switch (c) { +case 'w' : + warn_on_notrace_sect =1 ; +break ; +default : +fprintf (stderr,"usage: recordmcount [-w] file.o...\n" ); +return 0 ; + } + } + +if ((argc - optind) <1 ) { +fprintf (stderr,"usage: recordmcount [-w] file.o...\n" );return 0 ; }/* Process each file in turn, allowing deep failure. */ -for (--argc, ++argv; argc >0 ; --argc, ++argv) { +for (i = optind; i < argc; i++) { +char *file = argv[i];int const sjval =setjmp (jmpenv);int len;
@@ -418,14 +434,14 @@ main(int argc, char const *argv[])* function but does not call it. Since ftrace.o should * not be traced anyway, we just skip it. */ - len =strlen (argv[0 ]); + len =strlen (file);if (len >= ftrace_size && -strcmp (argv[0 ] + (len - ftrace_size), ftrace) ==0 ) +strcmp (file + (len - ftrace_size), ftrace) ==0 )continue ;switch (sjval) {default : -fprintf (stderr,"internal error: %s\n" , argv[0 ]); +fprintf (stderr,"internal error: %s\n" , file);exit (1 );break ;case SJ_SETJMP :/* normal sequence */
@@ -433,7 +449,7 @@ main(int argc, char const *argv[]) fd_map =-1 ; ehdr_curr =NULL ; mmap_failed =1 ; -do_file (argv[0 ]); +do_file (file);break ;case SJ_FAIL :/* error in do_file or below */ ++n_error;
scripts/recordmcount.h +17 -5
@@ -313,7 +313,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,* into nops. */ static void nop_mcount (Elf_Shdr const *const relhdr, -Elf_Ehdr const *const ehdr) +Elf_Ehdr const *const ehdr, +const char *const txtname) {Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w (ehdr->e_shoff) + (void *)ehdr);
@@ -336,6 +337,7 @@ static void nop_mcount(Elf_Shdr const *const relhdr,unsigned mcountsym =0 ;unsigned t; +int once =0 ;for (t = nrel; t; --t) {int ret =-1 ;
@@ -353,8 +355,18 @@ static void nop_mcount(Elf_Shdr const *const relhdr, mcountsym =Elf_r_sym (relp); } -if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) - ret =make_nop ((void *)ehdr, shdr->sh_offset + relp->r_offset); +if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) { +if (make_nop) + ret =make_nop ((void *)ehdr, shdr->sh_offset + relp->r_offset); +if (warn_on_notrace_sect && !once) { +printf ("Section %s has mcount callers being ignored\n" , + txtname); + once =1 ; +/* just warn? */ +if (!make_nop) +return ; + } + }/* * If we successfully removed the mcount, mark the relocation
@@ -501,12 +513,12 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) mlocp =sift_rel_mcount (mlocp, (void *)mlocp - (void *)mloc0, &mrelp, relhdr, ehdr, recsym, recval, reltype); - }else if (make_nop && txtname) { + }else if (txtname && (warn_on_notrace_sect || make_nop)) {/* * This section is ignored by ftrace, but still * has mcount calls. Convert them to nops now. */ -nop_mcount (relhdr, ehdr); +nop_mcount (relhdr, ehdr, txtname); } }if (mloc0 != mlocp) {
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 8/15 kbuild/recordmcount: Add RECORDMCOUNT_WARN to warn about mcount
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
When mcount is called in a section that ftrace will not modify it into a nop, we want to warn about this. But not warn about this always. Now if the user builds the kernel with the option RECORDMCOUNT_WARN=1 then the build will warn about mcount callers that are ignored and will just waste execution time.
--- Makefile | 1 + scripts/Makefile.build | 5 ++++- 2 files changed, 5 insertions(+), 1 deletions(-)
Makefile +1 -0
@@ -1268,6 +1268,7 @@ help: @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)' @echo ' make C=2 [targets] Force check of all c source with $$CHECK' @echo ' make W=1 [targets] Enable extra gcc checks' + @echo ' make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections' @echo '' @echo 'Execute "make" or "make all" to build all targets marked with [*] ' @echo 'For further info see the ./README file'
scripts/Makefile.build +4 -1
@@ -244,13 +244,16 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD ifdef BUILD_C_RECORDMCOUNT +ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") + RECORDMCOUNT_FLAGS = -w +endif # Due to recursion, we must skip empty.o. # The empty.o file is created in the make process in order to determine # the target endianness and word size. It is made before all other C # files, including recordmcount. sub_cmd_record_mcount = \ if [ $(@) != "scripts/mod/empty.o" ]; then \ - $(objtree)/scripts/recordmcount "$(@)"; \ + $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ fi; recordmcount_source := $(srctree)/scripts/recordmcount.c \ $(srctree)/scripts/recordmcount.h
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 9/15 ftrace: Avoid recording mcount on .init sections directly
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The init and exit sections should not be traced and adding a call to mcount to them is a waste of text and instruction cache. Have the macro section attributes include notrace to ignore these functions for tracing from the build.
--- include/linux/init.h | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-)
include/linux/init.h +7 -7
@@ -79,29 +79,29 @@#define __exitused __used#endif -#define __exit __section(.exit.text) __exitused __cold +#define __exit __section(.exit.text) __exitused __cold notrace/* Used for HOTPLUG */ -#define __devinit __section(.devinit.text) __cold +#define __devinit __section(.devinit.text) __cold notrace#define __devinitdata __section(.devinit.data)#define __devinitconst __section(.devinit.rodata) -#define __devexit __section(.devexit.text) __exitused __cold +#define __devexit __section(.devexit.text) __exitused __cold notrace#define __devexitdata __section(.devexit.data)#define __devexitconst __section(.devexit.rodata)/* Used for HOTPLUG_CPU */ -#define __cpuinit __section(.cpuinit.text) __cold +#define __cpuinit __section(.cpuinit.text) __cold notrace#define __cpuinitdata __section(.cpuinit.data)#define __cpuinitconst __section(.cpuinit.rodata) -#define __cpuexit __section(.cpuexit.text) __exitused __cold +#define __cpuexit __section(.cpuexit.text) __exitused __cold notrace#define __cpuexitdata __section(.cpuexit.data)#define __cpuexitconst __section(.cpuexit.rodata)/* Used for MEMORY_HOTPLUG */ -#define __meminit __section(.meminit.text) __cold +#define __meminit __section(.meminit.text) __cold notrace#define __meminitdata __section(.meminit.data)#define __meminitconst __section(.meminit.rodata) -#define __memexit __section(.memexit.text) __exitused __cold +#define __memexit __section(.memexit.text) __exitused __cold notrace#define __memexitdata __section(.memexit.data)#define __memexitconst __section(.memexit.rodata)
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 10/15 ftrace/x86: Do not trace .discard.text section
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The section called .discard.text has tracing attached to it and is currently ignored by ftrace. But it does include a call to the mcount stub. Adding a notrace to the code keeps gcc from adding the useless mcount caller to it.
--- arch/x86/include/asm/setup.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/include/asm/setup.h +1 -1
@@ -88,7 +88,7 @@ void *extend_brk(size_t size, size_t align);* executable.) */ #define RESERVE_BRK (name,sz) \ - static void __section(.discard.text) __used \ + static void __section(.discard.text) __used notrace \ __brk_reservation_fn_##name##__(void) { \ asm volatile ( \ ".pushsection .brk_reservation,\"aw\",@nobits;" \
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 11/15 ftrace/recordmcount: Remove duplicate code to find mcount symbol
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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.
--- scripts/recordmcount.h | 51 +++++++++++++++++++++++++---------------------- 1 files changed, 27 insertions(+), 24 deletions(-)
scripts/recordmcount.h +27 -24
@@ -28,6 +28,7 @@#undef __has_rel_mcount#undef has_rel_mcount#undef tot_relsize +#undef get_mcountsym#undef do_func#undef Elf_Addr#undef Elf_Ehdr
@@ -56,6 +57,7 @@# define has_rel_mcount has64_rel_mcount# define tot_relsize tot64_relsize# define do_func do64 +# define get_mcountsym get_mcountsym_64# define is_fake_mcount is_fake_mcount64# define fn_is_fake_mcount fn_is_fake_mcount64# define MIPS_is_fake_mcount MIPS64_is_fake_mcount
@@ -85,6 +87,7 @@# define has_rel_mcount has32_rel_mcount# define tot_relsize tot32_relsize# define do_func do32 +# define get_mcountsym get_mcountsym_32# define is_fake_mcount is_fake_mcount32# define fn_is_fake_mcount fn_is_fake_mcount32# define MIPS_is_fake_mcount MIPS32_is_fake_mcount
@@ -237,6 +240,26 @@ static void append_func(Elf_Ehdr *const ehdr,uwrite (fd_map, ehdr,sizeof (*ehdr)); } +static unsigned get_mcountsym (Elf_Sym const *const sym0, +Elf_Rel const *relp, +char const *const str0) +{ +unsigned mcountsym =0 ; + +Elf_Sym const *const symp = + &sym0[Elf_r_sym (relp)]; +char const *symname = &str0[w (symp->st_name)]; +char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; + +if (symname[0 ] =='.' ) + ++symname;/* ppc64 hack */ +if (strcmp (mcount, symname) ==0 || + (altmcount &&strcmp (altmcount, symname) ==0 )) + mcountsym =Elf_r_sym (relp); + +return mcountsym; +} +/* * Look at the relocations in order to find the calls to mcount. * Accumulate the section offsets that are found, and their relocation info,
@@ -274,18 +297,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,unsigned t;for (t = nrel; t; --t) { -if (!mcountsym) { -Elf_Sym const *const symp = - &sym0[Elf_r_sym (relp)]; -char const *symname = &str0[w (symp->st_name)]; -char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; - -if (symname[0 ] =='.' ) - ++symname;/* ppc64 hack */ -if (strcmp (mcount, symname) ==0 || - (altmcount &&strcmp (altmcount, symname) ==0 )) - mcountsym =Elf_r_sym (relp); - } +if (!mcountsym) + mcountsym =get_mcountsym (sym0, relp, str0);if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) {uint_t const addend =_w (_w (relp->r_offset) - recval);
@@ -342,18 +355,8 @@ static void nop_mcount(Elf_Shdr const *const relhdr,for (t = nrel; t; --t) {int ret =-1 ; -if (!mcountsym) { -Elf_Sym const *const symp = - &sym0[Elf_r_sym (relp)]; -char const *symname = &str0[w (symp->st_name)]; -char const *mcount = gpfx =='_' ?"_mcount" :"mcount" ; - -if (symname[0 ] =='.' ) - ++symname;/* ppc64 hack */ -if (strcmp (mcount, symname) ==0 || - (altmcount &&strcmp (altmcount, symname) ==0 )) - mcountsym =Elf_r_sym (relp); - } +if (!mcountsym) + mcountsym =get_mcountsym (sym0, relp, str0);if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) {if (make_nop)
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 12/15 ftrace/recordmcount: Add helper function get_sym_str_and_relp()
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
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.
--- scripts/recordmcount.h | 67 ++++++++++++++++++++++++++--------------------- 1 files changed, 37 insertions(+), 30 deletions(-)
scripts/recordmcount.h +37 -30
@@ -29,6 +29,7 @@#undef has_rel_mcount#undef tot_relsize#undef get_mcountsym +#undef get_sym_str_and_relp#undef do_func#undef Elf_Addr#undef Elf_Ehdr
@@ -56,6 +57,7 @@# define __has_rel_mcount __has64_rel_mcount# define has_rel_mcount has64_rel_mcount# define tot_relsize tot64_relsize +# define get_sym_str_and_relp get_sym_str_and_relp_64# define do_func do64# define get_mcountsym get_mcountsym_64# define is_fake_mcount is_fake_mcount64
@@ -86,6 +88,7 @@# define __has_rel_mcount __has32_rel_mcount# define has_rel_mcount has32_rel_mcount# define tot_relsize tot32_relsize +# define get_sym_str_and_relp get_sym_str_and_relp_32# define do_func do32# define get_mcountsym get_mcountsym_32# define is_fake_mcount is_fake_mcount32
@@ -260,6 +263,29 @@ static unsigned get_mcountsym(Elf_Sym const *const sym0,return mcountsym; } +static void get_sym_str_and_relp (Elf_Shdr const *const relhdr, +Elf_Ehdr const *const ehdr, +Elf_Sym const **sym0, +char const **str0, +Elf_Rel const **relp) +{ +Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w (ehdr->e_shoff) + + (void *)ehdr); +unsigned const symsec_sh_link =w (relhdr->sh_link); +Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; +Elf_Shdr const *const strsec = &shdr0[w (symsec->sh_link)]; +Elf_Rel const *const rel0 = (Elf_Rel const *)(_w (relhdr->sh_offset) + + (void *)ehdr); + + *sym0 = (Elf_Sym const *)(_w (symsec->sh_offset) + + (void *)ehdr); + + *str0 = (char const *)(_w (strsec->sh_offset) + + (void *)ehdr); + + *relp = rel0; +} +/* * Look at the relocations in order to find the calls to mcount. * Accumulate the section offsets that are found, and their relocation info,
@@ -276,26 +302,16 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, {uint_t *const mloc0 = mlocp;Elf_Rel *mrelp = *mrelpp; -Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w (ehdr->e_shoff) - + (void *)ehdr); -unsigned const symsec_sh_link =w (relhdr->sh_link); -Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; -Elf_Sym const *const sym0 = (Elf_Sym const *)(_w (symsec->sh_offset) - + (void *)ehdr); - -Elf_Shdr const *const strsec = &shdr0[w (symsec->sh_link)]; -char const *const str0 = (char const *)(_w (strsec->sh_offset) - + (void *)ehdr); - -Elf_Rel const *const rel0 = (Elf_Rel const *)(_w (relhdr->sh_offset) - + (void *)ehdr); +Elf_Sym const *sym0; +char const *str0; +Elf_Rel const *relp;unsigned rel_entsize =_w (relhdr->sh_entsize);unsigned const nrel =_w (relhdr->sh_size) / rel_entsize; -Elf_Rel const *relp = rel0; -unsigned mcountsym =0 ;unsigned t; +get_sym_str_and_relp (relhdr, ehdr, &sym0, &str0, &relp); +for (t = nrel; t; --t) {if (!mcountsym) mcountsym =get_mcountsym (sym0, relp, str0);
@@ -331,27 +347,18 @@ static void nop_mcount(Elf_Shdr const *const relhdr, {Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w (ehdr->e_shoff) + (void *)ehdr); -unsigned const symsec_sh_link =w (relhdr->sh_link); -Elf_Shdr const *const symsec = &shdr0[symsec_sh_link]; -Elf_Sym const *const sym0 = (Elf_Sym const *)(_w (symsec->sh_offset) - + (void *)ehdr); - -Elf_Shdr const *const strsec = &shdr0[w (symsec->sh_link)]; -char const *const str0 = (char const *)(_w (strsec->sh_offset) - + (void *)ehdr); - -Elf_Rel const *const rel0 = (Elf_Rel const *)(_w (relhdr->sh_offset) - + (void *)ehdr); +Elf_Sym const *sym0; +char const *str0; +Elf_Rel const *relp; +Elf_Shdr const *const shdr = &shdr0[w (relhdr->sh_info)];unsigned rel_entsize =_w (relhdr->sh_entsize);unsigned const nrel =_w (relhdr->sh_size) / rel_entsize; -Elf_Rel const *relp = rel0; - -Elf_Shdr const *const shdr = &shdr0[w (relhdr->sh_info)]; -unsigned mcountsym =0 ;unsigned t;int once =0 ; +get_sym_str_and_relp (relhdr, ehdr, &sym0, &str0, &relp); +for (t = nrel; t; --t) {int ret =-1 ;
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 13/15 ftrace/recordmcount: mcount address adjustment
In reply to Steven RostedtFrom: Martin Schwidefsky <[email protected]>
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.
--- scripts/recordmcount.h | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
scripts/recordmcount.h +7 -2
@@ -22,6 +22,7 @@#undef is_fake_mcount#undef fn_is_fake_mcount#undef MIPS_is_fake_mcount +#undef mcount_adjust#undef sift_rel_mcount#undef nop_mcount#undef find_secsym_ndx
@@ -63,6 +64,7 @@# define is_fake_mcount is_fake_mcount64# define fn_is_fake_mcount fn_is_fake_mcount64# define MIPS_is_fake_mcount MIPS64_is_fake_mcount +# define mcount_adjust mcount_adjust_64# define Elf_Addr Elf64_Addr# define Elf_Ehdr Elf64_Ehdr# define Elf_Shdr Elf64_Shdr
@@ -94,6 +96,7 @@# define is_fake_mcount is_fake_mcount32# define fn_is_fake_mcount fn_is_fake_mcount32# define MIPS_is_fake_mcount MIPS32_is_fake_mcount +# define mcount_adjust mcount_adjust_32# define Elf_Addr Elf32_Addr# define Elf_Ehdr Elf32_Ehdr# define Elf_Shdr Elf32_Shdr
@@ -132,6 +135,8 @@ static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) }static void (*Elf_r_info)(Elf_Rel *const rp,unsigned sym,unsigned type) = fn_ELF_R_INFO; +static int mcount_adjust =0 ; +/* * MIPS mcount long call has 2 _mcount symbols, only the position of the 1st * _mcount symbol is needed for dynamic function tracer, with it, to disable
@@ -317,8 +322,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, mcountsym =get_mcountsym (sym0, relp, str0);if (mcountsym ==Elf_r_sym (relp) && !is_fake_mcount (relp)) { -uint_t const addend =_w (_w (relp->r_offset) - recval); - +uint_t const addend = +_w (_w (relp->r_offset) - recval + mcount_adjust); mrelp->r_offset =_w (offbase + ((void *)mlocp - (void *)mloc0));Elf_r_info (mrelp, recsym, reltype);
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 14/15 ftrace/x86: mcount offset calculation
In reply to Steven RostedtFrom: Martin Schwidefsky <[email protected]>
Do the mcount offset adjustment in the recordmcount.pl/recordmcount.[ch] at compile time and not in ftrace_call_adjust at run time.
--- arch/x86/include/asm/ftrace.h | 7 +++---- scripts/recordmcount.c | 2 ++ scripts/recordmcount.pl | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-)
arch/x86/include/asm/ftrace.h +3 -4
@@ -38,11 +38,10 @@ extern void mcount(void);static inline unsigned long ftrace_call_adjust (unsigned long addr) {/* -* call mcount is "e8 <4 byte offset>" -* The addr points to the 4 byte offset and the caller of this -* function wants the pointer to e8. Simply subtract one. +* addr is the address of the mcount call instruction. +* recordmcount does the necessary offset calculation. */ -return addr -1 ; +return addr; }#ifdef CONFIG_DYNAMIC_FTRACE
scripts/recordmcount.c +2 -0
@@ -335,6 +335,7 @@ do_file(char const *const fname) reltype =R_386_32 ; make_nop = make_nop_x86; ideal_nop = ideal_nop5_x86_32; + mcount_adjust_32 =-1 ;break ;case EM_ARM : reltype =R_ARM_ABS32 ; altmcount ="__gnu_mcount_nc" ;
@@ -350,6 +351,7 @@ do_file(char const *const fname) make_nop = make_nop_x86; ideal_nop = ideal_nop5_x86_64; reltype =R_X86_64_64 ; + mcount_adjust_64 =-1 ;break ; }/* end switch */
scripts/recordmcount.pl +2 -0
@@ -223,6 +223,7 @@ if ($arch eq "x86_64") { $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; $alignment = 8; + $mcount_adjust = -1; # force flags for this arch $ld .= " -m elf_x86_64";
@@ -232,6 +233,7 @@ if ($arch eq "x86_64") { } elsif ($arch eq "i386") { $alignment = 4; + $mcount_adjust = -1; # force flags for this arch $ld .= " -m elf_i386";
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerPATCH 15/15 ftrace/s390: mcount offset calculation
In reply to Steven RostedtFrom: Martin Schwidefsky <[email protected]>
Do the mcount offset adjustment in the recordmcount.pl/recordmcount.[ch] at compile time and not in ftrace_call_adjust at run time.
--- arch/s390/include/asm/ftrace.h | 4 +--- scripts/recordmcount.c | 8 ++++++-- scripts/recordmcount.pl | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-)
arch/s390/include/asm/ftrace.h +1 -3
@@ -11,15 +11,13 @@ struct dyn_arch_ftrace { };#ifdef CONFIG_64BIT #define MCOUNT_INSN_SIZE 12 -#define MCOUNT_OFFSET 8#else #define MCOUNT_INSN_SIZE 20 -#define MCOUNT_OFFSET 4#endif static inline unsigned long ftrace_call_adjust (unsigned long addr) { -return addr -MCOUNT_OFFSET ; +return addr; }#endif /* __ASSEMBLY__ */
scripts/recordmcount.c +6 -2
@@ -368,8 +368,10 @@ do_file(char const *const fname) "unrecognized ET_REL file: %s\n", fname);fail_file (); } -if (w2 (ehdr->e_machine) ==EM_S390 ) +if (w2 (ehdr->e_machine) ==EM_S390 ) { reltype =R_390_32 ; + mcount_adjust_32 =-4 ; + }if (w2 (ehdr->e_machine) ==EM_MIPS ) { reltype =R_MIPS_32 ; is_fake_mcount32 = MIPS32_is_fake_mcount;
@@ -384,8 +386,10 @@ do_file(char const *const fname) "unrecognized ET_REL file: %s\n", fname);fail_file (); } -if (w2 (ghdr->e_machine) ==EM_S390 ) +if (w2 (ghdr->e_machine) ==EM_S390 ) { reltype =R_390_64 ; + mcount_adjust_64 =-8 ; + }if (w2 (ghdr->e_machine) ==EM_MIPS ) { reltype =R_MIPS_64 ; Elf64_r_sym = MIPS64_r_sym;
scripts/recordmcount.pl +2 -0
@@ -243,12 +243,14 @@ if ($arch eq "x86_64") { } elsif ($arch eq "s390" && $bits == 32) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_32\\s+_mcount\$"; + $mcount_adjust = -4; $alignment = 4; $ld .= " -m elf_s390"; $cc .= " -m31"; } elsif ($arch eq "s390" && $bits == 64) { $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; + $mcount_adjust = -8; $alignment = 8; $type = ".quad"; $ld .= " -m elf64_s390";
Signature · 1 line
1.7.4.4
Steven Rostedt
maintainerQuoted 7 lines · Steven Rostedt
Ingo,
Please pull the latest tip/perf/core-2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core-2
Note, this is not based off of my tip/perf/core branch, but is based off of tip separately.
I'm not sure why you don't want to pull my tip/perf/core directly yet. I'd like to get that infrastructure in and tested before the 40 merge window so that we can focus on the perf function tracing in the 41 window, and not try to figure out where bugs are between the two.
That pull request is here:
http://marc.info/?l=linux-kernel&m=130469692420787
Thanks,
-- Steve
Quoted 11 lines · Steven Rostedt
Quoted 7 lines · Steven Rostedt
Ingo,
Please pull the latest tip/perf/core-2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core-2Note, this is not based off of my tip/perf/core branch, but is based off of tip separately.
I pulled your tip/perf/core (b9df92d2a94e) on May 1, almost 3 weeks ago, into tip:perf/core.
Quoted 1 line
I'm not sure why you don't want to pull my tip/perf/core directly yet.
Because i already have? :-)
Quoted 7 lines
[...] I'd like to get that infrastructure in and tested before the 40 merge window so that we can focus on the perf function tracing in the 41 window, and not try to figure out where bugs are between the two.
That pull request is here:
Well, that is an RFC patchset, named:
[RFC][PATCH 00/13] ftrace: Allow multiple users to pick and choose functions
In that mail you specifically said:
" I'm posting this patch series as an RFC, but I do not expect it to change
much. I still have to put it through more tests even though I ran several on each set already. "
... with no pull vector in it. If you want me to pull something you need to put it into a branch i can see and you need to send a pull request :-)
Thanks,
Ingo
Steven Rostedt
maintainerQuoted 8 lines · Ingo Molnar
In that mail you specifically said:
" I'm posting this patch series as an RFC, but I do not expect it to change
much. I still have to put it through more tests even though I ran several on each set already. "... with no pull vector in it. If you want me to pull something you need to put it into a branch i can see and you need to send a pull request :-)
Ouch! My fault. Something happened where my pull request never got sent out. I picked the link from my mail box not noticing it was the RFC.
I'll push it out again.
Thanks,
-- Steve
Quoted 30 lines · Steven Rostedt
Ingo,
Please pull the latest tip/perf/core-2 tree, which can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
tip/perf/core-2Martin Schwidefsky (3):
ftrace/recordmcount: mcount address adjustment ftrace/x86: mcount offset calculation ftrace/s390: mcount offset calculationMichal Marek (1):
ftrace/kbuild: Add recordmcount files to force full buildSteven Rostedt (11):
ftrace/trivial: Clean uprecordmcount.cto use Linux style comparisons ftrace/trivial: Clean up record mcount to use Linux switch style
ftrace: Add .kprobe.text section to whitelist forrecordmcount.cftrace/recordmcount: Modify only executable sections ftrace/recordmcount: Make ignored mcount calls into nops at compile time ftrace/recordmcount: Add warning logic to warn on mcount not recorded kbuild/recordmcount: AddRECORDMCOUNT_WARNto warn about mcount callers
ftrace: Avoid recording mcount on .init sections directly ftrace/x86: Do not trace .discard.text section ftrace/recordmcount: Remove duplicate code to find mcount symbol ftrace/recordmcount: Add helper functionget_sym_str_and_relp()----
Quoted 10 lines
Makefile | 1 + arch/s390/include/asm/ftrace.h | 4 +- arch/x86/include/asm/ftrace.h | 7 +- arch/x86/include/asm/setup.h | 2 +- include/linux/init.h | 14 ++-- scripts/Makefile.build | 12 ++- scripts/recordmcount.c | 168 ++++++++++++++++++++++++++------------ scripts/recordmcount.h | 174 +++++++++++++++++++++++++++++++-------- scripts/recordmcount.pl | 5 + 9 files changed, 279 insertions(+), 108 deletions(-)
Pulled, thanks a lot Steve!
Ingo