diff options
author | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-12-03 15:36:50 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-12-03 15:36:50 +1100 |
commit | c15cab6f07181310cbce47037f19c35b74ab8918 (patch) | |
tree | 77c33a9e2ac64e994c59aeb71060a60b6d0a248f | |
parent | 11eea4785fee409aa79e08c1679ec175563f36ae (diff) | |
download | skiboot-c15cab6f07181310cbce47037f19c35b74ab8918.zip skiboot-c15cab6f07181310cbce47037f19c35b74ab8918.tar.gz skiboot-c15cab6f07181310cbce47037f19c35b74ab8918.tar.bz2 |
Fix up extract-gcov for gcc > 4.8
The story of extract-gcov is not necessarily a pleasant one, involving
GCC internals, padding of data structures, differences in data structures
that are designed to change whenever GCC wants to and a strong desire
to not implement a VFS in skiboot or some other streaming interface
(and associated userspace and other such blergh).
This patch makes us be all explicit about padding in the structures,
enabling -Wpadding for extract-gcov.c.
We also get all strict over the size of things and add support for
gcc 5.1, which added an extra counter.
There is likely GCC hacking in my future to make this a lot less
fragile.
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | Makefile.main | 4 | ||||
-rw-r--r-- | extract-gcov.c | 31 |
2 files changed, 24 insertions, 11 deletions
diff --git a/Makefile.main b/Makefile.main index b206ee1..c0f0955 100644 --- a/Makefile.main +++ b/Makefile.main @@ -203,8 +203,8 @@ include $(shell find $(SRC)/* -name Makefile.check) extract-gcov: extract-gcov.c $(call Q, HOSTCC ,$(HOSTCC) $(HOSTCFLAGS) \ -DTARGET__GNUC__=`echo '__GNUC__'|$(CC) -E -|grep -v '^#'` \ - -DTARGET__GNUC_MINOR__=`echo '__GNUC__'|$(CC) -E -|grep -v '^#'` \ - -O0 -g -I$(SRC) -o $@ $<,$<) + -DTARGET__GNUC_MINOR__=`echo '__GNUC_MINOR__'|$(CC) -E -|grep -v '^#'` \ + -Wpadded -O0 -g -I$(SRC) -o $@ $<,$<) coverage-report: skiboot.info genhtml --branch-coverage -q -o $@ $< diff --git a/extract-gcov.c b/extract-gcov.c index c9b82f3..a9298fa 100644 --- a/extract-gcov.c +++ b/extract-gcov.c @@ -30,39 +30,48 @@ #include <errno.h> #include <string.h> -typedef unsigned int gcov_unsigned_int; +typedef u32 gcov_unsigned_int; /* You will need to pass -DTARGET__GNUC__=blah when building */ +#if TARGET__GNUC__ >= 5 && TARGET__GNUC_MINOR__ >= 1 +#define GCOV_COUNTERS 10 +#else #if TARGET__GNUC__ >= 4 && TARGET__GNUC_MINOR__ >= 9 #define GCOV_COUNTERS 9 #else #define GCOV_COUNTERS 8 -#endif +#endif /* GCC 4.9 */ +#endif /* GCC 5.1 */ typedef u64 gcov_type; struct gcov_info { gcov_unsigned_int version; + u32 _padding; struct gcov_info *next; gcov_unsigned_int stamp; + u32 _padding2; const char *filename; - void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int); + u64 merge[GCOV_COUNTERS]; unsigned int n_functions; + u32 _padding3; struct gcov_fn_info **functions; }; struct gcov_ctr_info { gcov_unsigned_int num; + u32 _padding; gcov_type *values; -}; +}__attribute__((packed)); struct gcov_fn_info { const struct gcov_info *key; unsigned int ident; unsigned int lineno_checksum; unsigned int cfg_checksum; + u32 _padding; // struct gcov_ctr_info ctrs[0]; -}; +} __attribute__((packed)); /* We have a list of all gcov info set up at startup */ @@ -137,7 +146,8 @@ static void write_gcda(char *addr, struct gcov_info* gi) write_u32(fd, be32toh(gi->version)); write_u32(fd, be32toh(gi->stamp)); - //printf("nfunctions: %d \n", be32toh(gi->n_functions)); + printf("version: %x\tstamp: %d\n", be32toh(gi->version), be32toh(gi->stamp)); + printf("nfunctions: %d \n", be32toh(gi->n_functions)); for(fn = 0; fn < be32toh(gi->n_functions); fn++) { functions = (struct gcov_fn_info**) @@ -146,6 +156,8 @@ static void write_gcda(char *addr, struct gcov_info* gi) fn_info = (struct gcov_fn_info*) SKIBOOT_ADDR(addr, functions[fn]); + printf("function: %p\n", (void*)be64toh((u64)functions[fn])); + write_u32(fd, GCOV_TAG_FUNCTION); write_u32(fd, GCOV_TAG_FUNCTION_LENGTH); write_u32(fd, be32toh(fn_info->ident)); @@ -161,9 +173,8 @@ static void write_gcda(char *addr, struct gcov_info* gi) write_u32(fd, (GCOV_TAG_FOR_COUNTER(ctr))); write_u32(fd, be32toh(ctr_info->num)*2); - /* printf(" ctr %d gcov_ctr_info->num %u\n", - * ctr, be32toh(ctr_info->num)); - */ + printf(" ctr %d gcov_ctr_info->num %u\n", + ctr, be32toh(ctr_info->num)); for(cv = 0; cv < be32toh(ctr_info->num); cv++) { gcov_type *ctrv = (gcov_type *) @@ -192,6 +203,8 @@ int main(int argc, char *argv[]) sizeof(struct gcov_ctr_info), sizeof(struct gcov_fn_info), sizeof(struct gcov_info)); + printf("TARGET GNUC: %d.%d\n", TARGET__GNUC__, TARGET__GNUC_MINOR__); + printf("GCOV_COUNTERS: %d\n", GCOV_COUNTERS); if (argc < 3) { fprintf(stderr, "Usage:\n" |