Auto-generate header of struct offsets/sizes
Code written in assembly needs to be told the offsets of struct members.
Currently these are hardcoded and static_assert-ed at compile time,
requiring manual updates every time struct declarations change.
This patch adds a mechanism for auto-generating a header with these
constants.
It uses a "hack" similar to other projects, e.g. Linux, where the
integer constant is used as an immediate in an inline assembly block.
The file is compiled and the constant extracted by a script which
generates the header file. For easy grep-ing, the constant is compiled
into a '.ascii' string, surrounded by magic strings, and extracted using
the 'strings' binutils tool.
To guarantee correctness, the same source file is compiled again as part
of the Hafnium binary but this time the declarations are converted to
static_asserts which check the values.
Fix: 120137356
Test: ./kokoru/ubuntu/build.sh
Change-Id: I551126519675e73cb01b4beb4ff9b1200b9b3de7
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index c1ac799..0972dde 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -12,6 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import("//build/toolchain/offset_size_header.gni")
+
+offset_size_header("offsets") {
+ sources = [
+ "offsets.c",
+ ]
+ path = "hf/arch/offsets.h"
+}
+
# Hypervisor specific code.
source_set("hypervisor") {
public_configs = [ "//src/arch/aarch64:config" ]
@@ -24,13 +33,13 @@
sources += [
"debug_el1.c",
"handler.c",
- "offsets.c",
"perfmon.c",
"psci_handler.c",
"sysregs.c",
]
deps = [
+ ":offsets",
"//src/arch/aarch64:arch",
"//src/arch/aarch64:entry",
"//src/arch/aarch64:smc",
diff --git a/src/arch/aarch64/hypervisor/exceptions.S b/src/arch/aarch64/hypervisor/exceptions.S
index e8e391b..b8a1fcd 100644
--- a/src/arch/aarch64/hypervisor/exceptions.S
+++ b/src/arch/aarch64/hypervisor/exceptions.S
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "offsets.h"
+#include "hf/arch/offsets.h"
#include "exception_macros.S"
/**
diff --git a/src/arch/aarch64/hypervisor/hypervisor_entry.S b/src/arch/aarch64/hypervisor/hypervisor_entry.S
index ce76aa5..5867805 100644
--- a/src/arch/aarch64/hypervisor/hypervisor_entry.S
+++ b/src/arch/aarch64/hypervisor/hypervisor_entry.S
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "offsets.h"
+#include "hf/arch/offsets.h"
/**
* Called only on first boot after the image has been relocated and BSS zeroed.
diff --git a/src/arch/aarch64/hypervisor/offsets.c b/src/arch/aarch64/hypervisor/offsets.c
index 1f32581..b99273c 100644
--- a/src/arch/aarch64/hypervisor/offsets.c
+++ b/src/arch/aarch64/hypervisor/offsets.c
@@ -14,24 +14,15 @@
* limitations under the License.
*/
-#include "offsets.h"
-
#include "hf/cpu.h"
-#include "hf/static_assert.h"
+#include "hf/offset_size_header.h"
-#define CHECK_OFFSET(name, type, field) \
- CHECK_OFFSET_1(#name, name, offsetof(type, field))
-#define CHECK_OFFSET_1(name, actual, expected) \
- static_assert((actual) == (expected), \
- "Offset " name " should be " #expected \
- " and not " #actual)
+DEFINE_OFFSETOF(CPU_ID, struct cpu, id)
+DEFINE_OFFSETOF(CPU_STACK_BOTTOM, struct cpu, stack_bottom)
+DEFINE_OFFSETOF(VCPU_REGS, struct vcpu, regs)
+DEFINE_OFFSETOF(VCPU_LAZY, struct vcpu, regs.lazy)
+DEFINE_OFFSETOF(VCPU_FREGS, struct vcpu, regs.fp)
-CHECK_OFFSET(CPU_ID, struct cpu, id);
-CHECK_OFFSET(CPU_STACK_BOTTOM, struct cpu, stack_bottom);
-CHECK_OFFSET(VCPU_REGS, struct vcpu, regs);
-CHECK_OFFSET(VCPU_LAZY, struct vcpu, regs.lazy);
-CHECK_OFFSET(VCPU_FREGS, struct vcpu, regs.fp);
-
-#ifdef VCPU_GIC
-CHECK_OFFSET(VCPU_GIC, struct vcpu, regs.gic);
+#if GIC_VERSION == 3 || GIC_VERSION == 4
+DEFINE_OFFSETOF(VCPU_GIC, struct vcpu, regs.gic)
#endif
diff --git a/src/arch/aarch64/hypervisor/offsets.h b/src/arch/aarch64/hypervisor/offsets.h
deleted file mode 100644
index cc2621b..0000000
--- a/src/arch/aarch64/hypervisor/offsets.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2018 The Hafnium Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-/* These are checked in offset.c. */
-#define CPU_ID 0
-#define CPU_STACK_BOTTOM 8
-#define VCPU_REGS 32
-#define VCPU_LAZY (VCPU_REGS + 264)
-#define VCPU_FREGS (VCPU_LAZY + 280)
-
-#if GIC_VERSION == 3 || GIC_VERSION == 4
-#define VCPU_GIC (VCPU_FREGS + 528)
-#endif