summaryrefslogtreecommitdiff
path: root/extra
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-03-03 20:58:42 +0000
committerEric Andersen <andersen@codepoet.org>2003-03-03 20:58:42 +0000
commit67eff66438688fddebe41f77fd252a3b2b135271 (patch)
tree18dbee3e9afe50d27095140198e2aa34df1de061 /extra
parent2229d0fa131387b9b8ad16ac88347350a080aeb5 (diff)
Initial effort at adding profiling support.
Diffstat (limited to 'extra')
-rw-r--r--extra/Configs/Config.in37
-rw-r--r--extra/gcc-uClibc/Makefile5
-rw-r--r--extra/gcc-uClibc/gcc-uClibc.c32
-rwxr-xr-xextra/scripts/get-needed-libgcc-objects.sh2
-rwxr-xr-xextra/scripts/initfini.awk9
5 files changed, 81 insertions, 4 deletions
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)