1#
2# Copyright (c) 2023, Google, Inc. All rights reserved
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17# Ensure we have frame pointers in Rust, for stack back-tracing and tools
18MODULE_RUSTFLAGS += -C force-frame-pointers=y
19
20ifeq ($(call TOBOOL,$(MODULE_ADD_IMPLICIT_DEPS)),true)
21# Add global library dependencies to the build path
22MODULE_LIBRARY_DEPS += $(GLOBAL_USER_LIBRARY_DEPS)
23
24ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),true)
25MODULE_LIBRARY_DEPS += trusty/user/base/lib/libstd-rust
26else
27MODULE_LIBRARY_DEPS += trusty/user/base/lib/libc-trusty
28endif
29endif
30
31# Remaining flags only apply to the trusty userspace, not the test-runner, which
32# is also built with the library system.
33ifeq (true,$(call TOBOOL,$(TRUSTY_USERSPACE)))
34
35# Control function inlining
36USERSPACE_INLINE_FUNCTIONS ?= true
37ifeq ($(call TOBOOL,$(USERSPACE_INLINE_FUNCTIONS)),true)
38MODULE_COMPILEFLAGS += -finline
39else
40MODULE_COMPILEFLAGS += -fno-inline-functions
41endif
42
43# If ASLR is disabled, don't make PIEs, it burns space
44ifneq ($(ASLR), false)
45	# Generate PIE code to allow ASLR to be applied
46	MODULE_COMPILEFLAGS += -fPIC
47	MODULE_RUSTFLAGS += -C relocation-model=pic
48else
49	MODULE_COMPILEFLAGS += -fno-PIC -fno-PIE
50	MODULE_RUSTFLAGS += -C relocation-model=static
51endif
52
53# LTO
54ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_LTO)))
55ifeq (true,$(call TOBOOL,$(USER_LTO_ENABLED)))
56MODULE_COMPILEFLAGS += \
57	-fvisibility=hidden \
58	-flto=thin \
59	-fsplit-lto-unit \
60
61endif
62
63# CFI
64MODULE_CFI_ENABLED := false
65# TODO(192512327): Re-enable CFI for Rust modules
66ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),false)
67ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_CFI)))
68ifeq (true,$(call TOBOOL,$(CFI_ENABLED)))
69MODULE_CFI_ENABLED := true
70endif
71
72ifdef USER_CFI_ENABLED
73MODULE_CFI_ENABLED := $(call TOBOOL,$(USER_CFI_ENABLED))
74endif
75endif # !MODULE_DISABLE_CFI
76endif
77
78ifeq (true,$(call TOBOOL,$(MODULE_CFI_ENABLED)))
79MODULE_COMPILEFLAGS += \
80	-fsanitize-blacklist=trusty/kernel/lib/ubsan/exemptlist \
81	-fsanitize=cfi \
82	-DCFI_ENABLED
83MODULE_LIBRARY_DEPS += trusty/kernel/lib/ubsan
84
85ifeq (true,$(call TOBOOL,$(CFI_DIAGNOSTICS)))
86MODULE_COMPILEFLAGS += -fno-sanitize-trap=cfi
87endif
88endif # MODULE_CFI_ENABLED
89
90endif # !MODULE_DISABLE_LTO
91
92# Branch Target Identification
93MODULE_ENABLE_BTI:=false
94ifeq (true,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_BTI)))
95ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_BTI)))
96MODULE_ENABLE_BTI:=$(call TOBOOL,$(KERNEL_BTI_ENABLED))
97endif
98endif
99
100# Pointer Authentication Codes
101MODULE_ENABLE_PAC:=false
102ifeq (true,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_PAC)))
103ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_PAC)))
104MODULE_ENABLE_PAC:=$(call TOBOOL,$(KERNEL_PAC_ENABLED))
105endif
106endif
107
108# Decide on the branch protection scheme
109ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_BTI)))
110ifeq ($(call TOBOOL,$(TRUSTY_APP_IN_TREE)),false)
111MODULE_LDFLAGS += -z bti-report=warning
112endif
113ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_PAC)))
114MODULE_COMPILEFLAGS += -mbranch-protection=bti+pac-ret \
115                       -DBTI_ENABLED \
116                       -DPAC_ENABLED
117MODULE_RUSTFLAGS += -Z branch-protection=bti,pac-ret
118else # !MODULE_ENABLE_PAC
119MODULE_COMPILEFLAGS += -mbranch-protection=bti \
120                       -DBTI_ENABLED
121MODULE_RUSTFLAGS += -Z branch-protection=bti
122endif
123else # !MODULE_ENABLE_BTI
124ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_PAC)))
125MODULE_COMPILEFLAGS += -mbranch-protection=pac-ret \
126                       -DPAC_ENABLED
127MODULE_RUSTFLAGS += -Z branch-protection=pac-ret
128endif
129endif
130
131# Stack protector
132ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_STACK_PROTECTOR)))
133ifeq (true,$(call TOBOOL,$(USER_STACK_PROTECTOR)))
134MODULE_COMPILEFLAGS += -fstack-protector-strong
135endif
136else
137MODULE_COMPILEFLAGS += -fno-stack-protector
138endif
139
140# Shadow call stack
141ifeq (true,$(call TOBOOL,$(SCS_ENABLED)))
142# set in arch/$(ARCH)/toolchain.mk iff shadow call stack is supported
143ifeq (false,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_SCS)))
144$(error Error: Shadow call stack is not supported for $(ARCH))
145endif
146
147ifeq (false,$(call TOBOOL,$(TRUSTY_APP_DISABLE_SCS)))
148ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_SCS)))
149# architectures that support SCS should set the flag that reserves
150# a register for the shadow call stack in their toolchain.mk file
151MODULE_COMPILEFLAGS += -fsanitize=shadow-call-stack
152
153# The Rust target aarch64-unknown-trusty enables reserve-x18 by default.
154# Doing so through rustc args causes a warning and is unnecessary, so we
155# don't pass it explicitly via MODULE_RUSTFLAGS if TRUSTY_USER_ARCH is arm64.
156# See https://github.com/rust-lang/rust/issues/96472#issuecomment-1200319324
157# for why rustc warns on this and it is not a rustc bug.
158
159endif
160else  # TRUSTY_APP_DISABLE_SCS
161$(warning $(MODULE) has set TRUSTY_APP_DISABLE_SCS, this flag only works as intended for apps w/o dependencies)
162endif
163endif # SCS_ENABLED
164
165# Code coverage
166ifeq (true,$(call TOBOOL,$(USER_COVERAGE_ENABLED)))
167ifeq (false,$(call TOBOOL, $(MODULE_DISABLE_COVERAGE)))
168MODULE_LIBRARY_DEPS += trusty/user/base/lib/sancov
169
170# -fno-optimize-sibling-calls/-fno-inline is necessary to get correct caller
171# information in the sancov instrumentation.
172MODULE_COMPILEFLAGS += \
173	-fsanitize-coverage-ignorelist=trusty/user/base/lib/sancov/exemptlist \
174	-fsanitize-coverage=trace-pc-guard \
175	-fno-inline \
176	-fno-optimize-sibling-calls
177
178endif
179endif
180
181# Source based code coverage
182ifeq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED)))
183ifeq (false,$(call TOBOOL, $(MODULE_DISABLE_COVERAGE)))
184MODULE_COMPILEFLAGS += -DUNITTEST_COVERAGE  \
185	-fprofile-instr-generate \
186	-fcoverage-mapping \
187	-mllvm \
188	-enable-value-profiling=false
189
190endif
191endif
192
193# Fuzzing build
194ifeq (true,$(call TOBOOL,$(FUZZING_BUILD_ENABLED)))
195MODULE_COMPILEFLAGS += \
196	-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \
197
198endif
199
200# HWASan
201ifeq (true,$(call TOBOOL,$(USER_HWASAN_ENABLED)))
202MODULE_DEFINES += \
203	HWASAN_ENABLED=1 \
204	HWASAN_SHADOW_SCALE=4 \
205
206MODULE_LIBRARY_DEPS += trusty/user/base/lib/hwasan
207MODULE_COMPILEFLAGS += \
208	-fsanitize-blacklist=trusty/user/base/lib/hwasan/exemptlist \
209	-fsanitize=hwaddress \
210	-mllvm -hwasan-with-tls=0 \
211	-mllvm -hwasan-globals=0 \
212	-mllvm -hwasan-use-short-granules=0 \
213
214endif
215
216MODULE_DEFINES += TRUSTY_USERSPACE=1
217
218endif # TRUSTY_USERSPACE
219
220MODULE_CFI_ENABLED :=
221MODULE_DISABLE_BTI :=
222MODULE_DISABLE_CFI :=
223MODULE_DISABLE_COVERAGE :=
224MODULE_DISABLE_LTO :=
225MODULE_DISABLE_SCS :=
226MODULE_DISABLE_STACK_PROTECTOR :=
227