From 65b94ef5ba1981c74a99cb43ee768fbf480c698b Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Wed, 10 May 2017 00:00:04 -0400 Subject: Sigh, right offset for the wrong register. Get the PC (the address we interrupted) rather than LR (the return address from the function we interrupted). Also, change u_short and u_int to unsigned short and unsigned int, since gcc recently decided that those aren't part of the C99 standard. Finally, add profilable versions of memcpy, memset, and friends, because they get called a lot in the course of unit testing, and it would be nice to know who's calling them. --- libraries/libprof/Makefile | 20 ++++++++++++++++++++ libraries/libprof/README.txt | 4 ++++ libraries/libprof/gmon.c | 17 ++++++++--------- libraries/libprof/gmon.h | 10 +++++----- libraries/libprof/profil.c | 11 +++++------ libraries/libprof/profil.h | 10 +++++----- 6 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 libraries/libprof/Makefile (limited to 'libraries') diff --git a/libraries/libprof/Makefile b/libraries/libprof/Makefile new file mode 100644 index 0000000..4fe5fb4 --- /dev/null +++ b/libraries/libprof/Makefile @@ -0,0 +1,20 @@ +LIB = libprof.a + +OBJS = gmon.o profil.o profiler.o + +# Don't profile the profiling code, because that way lies madness (and recursion). +CFLAGS := $(subst -pg,,$(CFLAGS)) + +all: $(LIB) + +%.o : %.c + $(CC) $(CFLAGS) -c -o $@ $< + +%.o : %.S + $(CC) $(CFLAGS) -c -o $@ $< + +$(LIB): $(OBJS) + $(AR) -r $@ $^ + +clean: + rm -f $(OBJS) $(LIB) diff --git a/libraries/libprof/README.txt b/libraries/libprof/README.txt index 9db27a6..1fe378c 100644 --- a/libraries/libprof/README.txt +++ b/libraries/libprof/README.txt @@ -50,6 +50,10 @@ In the OpenOCD console, enable semihosting: > arm semihosting enable +In another window, start the debugger: + + $ sw/stm32/bin/debug projects/hsm/hsm + In the CLI, type `profile start`, then start the unit test or whatever will be exercising the hsm. Afterwards, in the CLI, type `profile stop`. diff --git a/libraries/libprof/gmon.c b/libraries/libprof/gmon.c index 458028b..92054fc 100644 --- a/libraries/libprof/gmon.c +++ b/libraries/libprof/gmon.c @@ -38,7 +38,6 @@ #include #include "gmon.h" #include "profil.h" -#include #include #define bzero(ptr,size) memset (ptr, 0, size); @@ -98,9 +97,9 @@ void monstartup (size_t lowpc, size_t highpc) { p->tos = (struct tostruct *)cp; cp += p->tossize; - p->kcount = (u_short *)cp; + p->kcount = (unsigned short *)cp; cp += p->kcountsize; - p->froms = (u_short *)cp; + p->froms = (unsigned short *)cp; p->tos[0].link = 0; @@ -238,7 +237,7 @@ void _mcount_internal(uint32_t *frompcindex, uint32_t *selfpc) { goto done; } frompcindex = (uint32_t*)&p->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*p->froms))]; - toindex = *((u_short*)frompcindex); /* get froms[] value */ + toindex = *((unsigned short*)frompcindex); /* get froms[] value */ if (toindex == 0) { /* * first time traversing this arc @@ -247,7 +246,7 @@ void _mcount_internal(uint32_t *frompcindex, uint32_t *selfpc) { if (toindex >= p->tolimit) { /* more tos[] entries than we can handle! */ goto overflow; } - *((u_short*)frompcindex) = (u_short)toindex; /* store new 'to' value into froms[] */ + *((unsigned short*)frompcindex) = (unsigned short)toindex; /* store new 'to' value into froms[] */ top = &p->tos[toindex]; top->selfpc = (size_t)selfpc; top->count = 1; @@ -283,8 +282,8 @@ void _mcount_internal(uint32_t *frompcindex, uint32_t *selfpc) { top = &p->tos[toindex]; top->selfpc = (size_t)selfpc; top->count = 1; - top->link = *((u_short*)frompcindex); - *(u_short*)frompcindex = (u_short)toindex; + top->link = *((unsigned short*)frompcindex); + *(unsigned short*)frompcindex = (unsigned short)toindex; goto done; } /* @@ -301,8 +300,8 @@ void _mcount_internal(uint32_t *frompcindex, uint32_t *selfpc) { top->count++; toindex = prevtop->link; prevtop->link = top->link; - top->link = *((u_short*)frompcindex); - *((u_short*)frompcindex) = (u_short)toindex; + top->link = *((unsigned short*)frompcindex); + *((unsigned short*)frompcindex) = (unsigned short)toindex; goto done; } } diff --git a/libraries/libprof/gmon.h b/libraries/libprof/gmon.h index 5eb5180..8b5ecf0 100644 --- a/libraries/libprof/gmon.h +++ b/libraries/libprof/gmon.h @@ -125,8 +125,8 @@ struct gmonhdr { struct tostruct { size_t selfpc; /* callee address/program counter. The caller address is in froms[] array which points to tos[] array */ long count; /* how many times it has been called */ - u_short link; /* link to next entry in hash table. For tos[0] this points to the last used entry */ - u_short pad; /* additional padding bytes, to have entries 4byte aligned */ + unsigned short link; /* link to next entry in hash table. For tos[0] this points to the last used entry */ + unsigned short pad; /* additional padding bytes, to have entries 4byte aligned */ }; /* @@ -150,13 +150,13 @@ struct rawarc { */ struct gmonparam { int state; - u_short *kcount; /* histogram PC sample array */ + unsigned short *kcount; /* histogram PC sample array */ size_t kcountsize; /* size of kcount[] array in bytes */ - u_short *froms; /* array of hashed 'from' addresses. The 16bit value is an index into the tos[] array */ + unsigned short *froms; /* array of hashed 'from' addresses. The 16bit value is an index into the tos[] array */ size_t fromssize; /* size of froms[] array in bytes */ struct tostruct *tos; /* to struct, contains histogram counter */ size_t tossize; /* size of tos[] array in bytes */ - long tolimit; + long tolimit; size_t lowpc; /* low program counter of area */ size_t highpc; /* high program counter */ size_t textsize; /* code size */ diff --git a/libraries/libprof/profil.c b/libraries/libprof/profil.c index 004af77..0654879 100644 --- a/libraries/libprof/profil.c +++ b/libraries/libprof/profil.c @@ -17,7 +17,6 @@ #include #include "profil.h" #include -#include #include "stm32f4xx_hal.h" /* __get_MSP */ @@ -30,7 +29,7 @@ extern void set_SysTick_hook(void (*hook)(void)); /* sample the current program counter */ static void SysTick_hook(void) { - size_t pc = (size_t)((uint32_t *)__get_MSP())[7]; + size_t pc = (size_t)((uint32_t *)__get_MSP())[8]; if (pc >= prof.lowpc && pc < prof.highpc) { size_t idx = PROFIDX (pc, prof.lowpc, prof.scale); prof.counter[idx]++; @@ -55,7 +54,7 @@ static int profile_on (struct profinfo *p) { * start or stop profiling * * profiling goes into the SAMPLES buffer of size SIZE (which is treated - * as an array of u_shorts of size size/2) + * as an array of unsigned shorts of size size/2) * * each bin represents a range of pc addresses from OFFSET. The number * of pc addresses in a bin depends on SCALE. (A scale of 65536 maps @@ -63,7 +62,7 @@ static int profile_on (struct profinfo *p) { * a scale of 1 maps each bin to 128k address). Scale may be 1 - 65536, * or zero to turn off profiling */ -int profile_ctl (struct profinfo *p, char *samples, size_t size, size_t offset, u_int scale) { +int profile_ctl (struct profinfo *p, char *samples, size_t size, size_t offset, unsigned int scale) { size_t maxbin; if (scale > 65536) { @@ -75,7 +74,7 @@ int profile_ctl (struct profinfo *p, char *samples, size_t size, size_t offset, memset(samples, 0, size); memset(p, 0, sizeof *p); maxbin = size >> 1; - prof.counter = (u_short*)samples; + prof.counter = (unsigned short*)samples; prof.lowpc = offset; prof.highpc = PROFADDR(maxbin, offset, scale); prof.scale = scale; @@ -88,7 +87,7 @@ int profile_ctl (struct profinfo *p, char *samples, size_t size, size_t offset, Every SLEEPTIME interval, the user's program counter (PC) is examined: offset is subtracted and the result is multiplied by scale. The word pointed to by this address is incremented. */ -int profil (char *samples, size_t size, size_t offset, u_int scale) { +int profil (char *samples, size_t size, size_t offset, unsigned int scale) { return profile_ctl (&prof, samples, size, offset, scale); } diff --git a/libraries/libprof/profil.h b/libraries/libprof/profil.h index af7a3ed..c72dc00 100644 --- a/libraries/libprof/profil.h +++ b/libraries/libprof/profil.h @@ -48,13 +48,13 @@ typedef enum { } PROFILE_State; struct profinfo { - PROFILE_State state; /* profiling state */ - u_short *counter; /* profiling counters */ + PROFILE_State state; /* profiling state */ + unsigned short *counter; /* profiling counters */ size_t lowpc, highpc; /* range to be profiled */ - u_int scale; /* scale value of bins */ + unsigned int scale; /* scale value of bins */ }; -int profile_ctl(struct profinfo *, char *, size_t, size_t, u_int); -int profil(char *, size_t, size_t, u_int); +int profile_ctl(struct profinfo *, char *, size_t, size_t, unsigned int); +int profil(char *, size_t, size_t, unsigned int); #endif /* __PROFIL_H__ */ -- cgit v1.2.3