aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2015-12-03 15:36:50 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-12-03 15:36:50 +1100
commitc15cab6f07181310cbce47037f19c35b74ab8918 (patch)
tree77c33a9e2ac64e994c59aeb71060a60b6d0a248f
parent11eea4785fee409aa79e08c1679ec175563f36ae (diff)
downloadskiboot-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.main4
-rw-r--r--extract-gcov.c31
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"