Fix calculation of zero offset.
gcc emits `.zero 8` for 8 bytes of zero rather than `.xword 0`. This
corrects the faulty logic that was trying to handle that before.
This also adds logic to check that the calculated offsets are correct
when doing a build to catch error like this in future.
Change-Id: Ic4fbb958e71b1ee1c025458ee5d2b241f989803d
diff --git a/Makefile b/Makefile
index fdcfd6c..888e823 100644
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,7 @@
TGT := $(patsubst %.c,%.o,$(OUT)/$(patsubst src/%,%,$(1)))
GLOBAL_OBJS += $$(TGT)
REMAIN_SRCS := $$(filter-out $(1),$$(REMAIN_SRCS))
-$$(TGT): $(ROOT_DIR)$(1) | $$(dir $$(TGT))
+$$(TGT): $(ROOT_DIR)$(1) $(GLOBAL_OFFSETS) | $$(dir $$(TGT))
$$(info CC $(ROOT_DIR)$1)
@$(CC) $(COPTS) $(DEP_GEN) -c $(ROOT_DIR)$(1) -o $$@
endef
@@ -100,10 +100,11 @@
GLOBAL_OFFSETS += $$(TGT)
$$(TGT): $(ROOT_DIR)$(1) | $$(dir $$(TGT))
$$(info GENOFFSET $(ROOT_DIR)$1)
- @$(CC) $(COPTS) $(DEP_GEN) -MT $$@ -S -c $(ROOT_DIR)$(1) -o - | \
+ @$(CC) -DGEN_OFFSETS $(COPTS) $(DEP_GEN) -MT $$@ -S -c $(ROOT_DIR)$(1) -o - | \
grep ^DEFINE_OFFSET -A1 | \
grep -v ^--$ | \
sed 's/^DEFINE_OFFSET__\([^:]*\):/#define \1 \\/' | \
+ sed 's/\.zero.*/0/' | \
sed 's/\.[^\t][^\t]*//' > $$@
endef
@@ -170,7 +171,7 @@
@find $(ROOT_DIR)inc/ -name *.c -o -name *.h | xargs clang-format -style file -i
# see .clang-tidy
-tidy:
+tidy: $(GLOBAL_OFFSETS)
@find $(ROOT_DIR)src/ -name *.c -exec clang-tidy {} -fix -- -target $(TARGET) $(COPTS) \;
-include $(patsubst %,%.d,$(GLOBAL_OBJS),$(GLOBAL_OFFSETS))
diff --git a/inc/decl_offsets.h b/inc/decl_offsets.h
index fbcff34..ede3ad7 100644
--- a/inc/decl_offsets.h
+++ b/inc/decl_offsets.h
@@ -1,9 +1,35 @@
#ifndef _DECL_OFFSETS_H
#define _DECL_OFFSETS_H
+#ifdef GEN_OFFSETS
+
+/* When generating offsets, create constants which can be extracted from the
+ * generated assembly. */
+
#define DECL(name, type, field) \
const size_t DEFINE_OFFSET__##name = offsetof(type, field)
#define DECL_SIZE(name, type) const size_t DEFINE_OFFSET__name = sizeof(type)
+#else /* GEN_OFFSETS */
+
+/* When not generating offsets, validate that the extracted values are as
+ * expected. */
+
+#include <assert.h>
+
+#define DECL(name, type, field) DECL_1(#name, name, offsetof(type, field))
+#define DECL_1(name, actual, expected) \
+ static_assert((actual) == (expected), \
+ "Offset " name " should be " #expected \
+ " and not " #actual)
+
+#define DECL_SIZE(name, type) DECL_SIZE_1(#name, name, sizeof(type))
+#define DECL_SIZE_1(name, actual, expected) \
+ static_assert((actual) == (expected), \
+ "Size " #name " should be " #expected \
+ " and not" #actual)
+
+#endif /* GEN_OFFSETS */
+
#endif /* _DECL_OFFSETS_H */
diff --git a/src/arch/aarch64/offsets.c b/src/arch/aarch64/offsets.c
index 8c49fed..8e7e9df 100644
--- a/src/arch/aarch64/offsets.c
+++ b/src/arch/aarch64/offsets.c
@@ -1,3 +1,7 @@
+#ifndef GEN_OFFSETS
+#include "offsets.h"
+#endif /* GEN_OFFSETS */
+
#include "cpu.h"
#include "decl_offsets.h"
diff --git a/src/arch/aarch64/rules.mk b/src/arch/aarch64/rules.mk
index 4abf817..a006751 100644
--- a/src/arch/aarch64/rules.mk
+++ b/src/arch/aarch64/rules.mk
@@ -2,6 +2,7 @@
SRCS += exceptions.S
SRCS += handler.c
SRCS += mm.c
+SRCS += offsets.c
SRCS += params.c
OFFSET_SRCS += offsets.c