From 67eff66438688fddebe41f77fd252a3b2b135271 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 3 Mar 2003 20:58:42 +0000 Subject: Initial effort at adding profiling support. --- extra/Configs/Config.in | 37 ++++++++++++++++++++++++++++++ extra/gcc-uClibc/Makefile | 5 ++++ extra/gcc-uClibc/gcc-uClibc.c | 32 +++++++++++++++++++++++++- extra/scripts/get-needed-libgcc-objects.sh | 2 +- extra/scripts/initfini.awk | 9 ++++++-- 5 files changed, 81 insertions(+), 4 deletions(-) (limited to 'extra') diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index c02c28c8f..112369f7e 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -97,6 +97,43 @@ config UCLIBC_CTOR_DTOR or dtors and want your binaries to be as small as possible, then answer N. +config UCLIBC_PROFILING + bool "Support gprof profiling" + default y + help + If you wish to build uClibc with support for application profiling + using the gprof tool, then you should enable this feature. Then in + addition to building uClibc with profiling support, you will also + need to recompile all your shared libraries with the profiling + enabled version of uClibc. To add profiling support to your + applications, you must compile things using the gcc options + "-fprofile-arcs -pg". Then when you run your applications, a + gmon.out file will be generated which can then be analyzed by + 'gprof'. + + These exist a number of less invasive alternatives that do not + require your to specially instrument your application, and recompile + and relink everything. + + Many people have had good results using the combination of Valgrind + to generate profiling information and KCachegrind for analysis: + http://developer.kde.org/~sewardj/ + http://kcachegrind.sourceforge.net/ + + The OProfile system-wide profiler is another alternative: + http://oprofile.sourceforge.net/ + + Prospect is another alternative based on OProfile: + http://prospect.sourceforge.net/ + + And the Linux Trace Toolkit (LTT) is also a fine tool: + http://www.opersys.com/LTT/ + + If none of these tools do what you need, you can of course enable + this option, rebuild everything, and use 'gprof'. There is both a + size and performance penelty to profiling your applications this way, + so most people should answer N. + config UCLIBC_HAS_THREADS bool "POSIX Threading Support" default y diff --git a/extra/gcc-uClibc/Makefile b/extra/gcc-uClibc/Makefile index 523b10113..e312d1792 100644 --- a/extra/gcc-uClibc/Makefile +++ b/extra/gcc-uClibc/Makefile @@ -36,6 +36,11 @@ else endif ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y) @echo "#define __UCLIBC_CTOR_DTOR__ 1" >> gcc-uClibc.h +ifeq ($(strip $(UCLIBC_PROFILING)),y) + @echo "#define __UCLIBC_PROFILING__ 1" >> gcc-uClibc.h +else + @echo "#undef __UCLIBC_PROFILING__" >> gcc-uClibc.h +endif else @echo "#undef __UCLIBC_CTOR_DTOR__" >> gcc-uClibc.h endif diff --git a/extra/gcc-uClibc/gcc-uClibc.c b/extra/gcc-uClibc/gcc-uClibc.c index 8cb8a8f3c..5b002b9d2 100644 --- a/extra/gcc-uClibc/gcc-uClibc.c +++ b/extra/gcc-uClibc/gcc-uClibc.c @@ -149,6 +149,10 @@ int main(int argc, char **argv) int ctor_dtor = 1, cplusplus = 0, use_nostdinc_plus = 0; char *GPLUSPLUS_BIN = NULL; #endif +#ifdef __UCLIBC_PROFILING__ + int profile = 0; + char *gcrt1_path[2]; +#endif application_name = basename(argv[0]); if (application_name[0] == '-') @@ -208,6 +212,10 @@ int main(int argc, char **argv) xstrcat(&(crt0_path[0]), devprefix, "/lib/crt0.o", NULL); xstrcat(&(crt0_path[1]), builddir, "/lib/crt0.o", NULL); #endif +#ifdef __UCLIBC_PROFILING__ + xstrcat(&(gcrt1_path[0]), devprefix, "/lib/gcrt1.o", NULL); + xstrcat(&(gcrt1_path[1]), builddir, "/lib/gcrt1.o", NULL); +#endif xstrcat(&(our_lib_path[0]), "-L", devprefix, "/lib", NULL); xstrcat(&(our_lib_path[1]), "-L", builddir, "/lib", NULL); @@ -312,13 +320,25 @@ int main(int argc, char **argv) } } break; +#ifdef __UCLIBC_PROFILING__ + case 'p': + if (strcmp("-pg",argv[i]) == 0) { + profile = 1; + } + break; +#endif case 'f': /* Check if we are doing PIC */ if (strcmp("-fPIC",argv[i]) == 0) { use_pic = 1; } else if (strcmp("-fpic",argv[i]) == 0) { use_pic = 1; + } +#ifdef __UCLIBC_PROFILING__ + else if (strcmp("-fprofile-arcs",argv[i]) == 0) { + profile = 1; } +#endif break; case '-': @@ -420,6 +440,11 @@ int main(int argc, char **argv) if (linking && source_count) { +#ifdef __UCLIBC_PROFILING__ + if (profile) { + gcc_argv[i++] = gcrt1_path[use_build_dir]; + } +#endif #ifdef __UCLIBC_CTOR_DTOR__ if (ctor_dtor) { gcc_argv[i++] = crti_path[use_build_dir]; @@ -431,7 +456,12 @@ int main(int argc, char **argv) } #endif if (use_start) { - gcc_argv[i++] = crt0_path[use_build_dir]; +#ifdef __UCLIBC_PROFILING__ + if (!profile) +#endif + { + gcc_argv[i++] = crt0_path[use_build_dir]; + } } for ( l = 0 ; l < k ; l++ ) { if (gcc_argument[l]) gcc_argv[i++] = gcc_argument[l]; diff --git a/extra/scripts/get-needed-libgcc-objects.sh b/extra/scripts/get-needed-libgcc-objects.sh index 04e6737f9..6aac14b4c 100755 --- a/extra/scripts/get-needed-libgcc-objects.sh +++ b/extra/scripts/get-needed-libgcc-objects.sh @@ -20,7 +20,7 @@ echo " partial linking..." rm -f libc.ldr $LD $LDFLAGS -r -o libc.ldr $CRTOBJS --whole-archive ../libc.a -if $NM --undefined-only libc.ldr 2>&1 | grep -v "^main$" | grep -v "^_GLOBAL_OFFSET_TABLE_$" | grep -v "_gp_disp" > sym.need ; then +if $NM --undefined-only libc.ldr 2>&1 | grep -v "^main$" | grep -v "^_GLOBAL_OFFSET_TABLE_$" | grep -v "_gp_disp" | grep -v "^etext$" | grep -v "^__gmon_start__$" > sym.need ; then EXIT_WITH_ERROR=0 rm -f obj.need touch obj.need diff --git a/extra/scripts/initfini.awk b/extra/scripts/initfini.awk index 818cfa26f..ef183db6c 100755 --- a/extra/scripts/initfini.awk +++ b/extra/scripts/initfini.awk @@ -12,6 +12,7 @@ BEGIN \ system("/bin/rm -f crt[in].S"); omitcrti=0; omitcrtn=0; + do_sh_specials = 0; glb_idx = 0; while(getline < "initfini.S") { if(/\.endp/) {endp=1} @@ -30,11 +31,11 @@ BEGIN \ close("initfini.S"); } # special rules for the SuperH targets (They do nothing on other targets) -/SH_GLB_BEGINS/ && glb_idx==0 {omitcrti +=1} +/SH_GLB_BEGINS/ && glb_idx==0 {omitcrti +=1;do_sh_specials++} /_init_SH_GLB/ && glb_idx>=1 {print glb_label[0] glb >> "crti.S"} /_fini_SH_GLB/ && glb_idx>=2 {print glb_label[1] glb >> "crti.S"} /SH_GLB_ENDS/ && glb_idx==0 {omitcrti -=1} -/SH_GLB/ || /_GLOBAL_OFFSET_TABLE_/{getline} +/SH_GLB/ || /_GLOBAL_OFFSET_TABLE_/ && do_sh_specials>=1 {getline} # special rules for H8/300 (sorry quick hack) /.h8300h/ {end=0} @@ -49,6 +50,10 @@ BEGIN \ /EPILOG_BEGINS/{omitcrtn=0;getline} /EPILOG_ENDS/{omitcrtn=1;getline} /TRAILER_BEGINS/{omitcrti=0;omitcrtn=0;getline} +/GMON_STUFF_BEGINS/{omitcrtn=1;getline} +/GMON_STUFF_PAUSES/{omitcrtn=0;getline} +/GMON_STUFF_UNPAUSES/{omitcrtn=1;getline} +/GMON_STUFF_ENDS/{omitcrtn=0;getline} /END_INIT/ \ { if(endp) -- cgit v1.2.3