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_RUSTFLAGS += -C relocation-model=static
50endif
51
52# LTO
53ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_LTO)))
54ifeq (true,$(call TOBOOL,$(USER_LTO_ENABLED)))
55MODULE_COMPILEFLAGS += \
56	-fvisibility=hidden \
57	-flto=thin \
58	-fsplit-lto-unit \
59
60endif
61
62# CFI
63MODULE_CFI_ENABLED := false
64# TODO(192512327): Re-enable CFI for Rust modules
65ifeq ($(call TOBOOL,$(MODULE_IS_RUST)),false)
66ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_CFI)))
67ifeq (true,$(call TOBOOL,$(CFI_ENABLED)))
68MODULE_CFI_ENABLED := true
69endif
70
71ifdef USER_CFI_ENABLED
72MODULE_CFI_ENABLED := $(call TOBOOL,$(USER_CFI_ENABLED))
73endif
74endif # !MODULE_DISABLE_CFI
75endif
76
77ifeq (true,$(call TOBOOL,$(MODULE_CFI_ENABLED)))
78MODULE_COMPILEFLAGS += \
79	-fsanitize-blacklist=trusty/kernel/lib/ubsan/exemptlist \
80	-fsanitize=cfi \
81	-DCFI_ENABLED
82MODULE_LIBRARY_DEPS += trusty/kernel/lib/ubsan
83
84ifeq (true,$(call TOBOOL,$(CFI_DIAGNOSTICS)))
85MODULE_COMPILEFLAGS += -fno-sanitize-trap=cfi
86endif
87endif # MODULE_CFI_ENABLED
88
89endif # !MODULE_DISABLE_LTO
90
91# Branch Target Identification
92MODULE_ENABLE_BTI:=false
93ifeq (true,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_BTI)))
94ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_BTI)))
95MODULE_ENABLE_BTI:=$(call TOBOOL,$(KERNEL_BTI_ENABLED))
96endif
97endif
98
99# Pointer Authentication Codes
100MODULE_ENABLE_PAC:=false
101ifeq (true,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_PAC)))
102ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_PAC)))
103MODULE_ENABLE_PAC:=$(call TOBOOL,$(KERNEL_PAC_ENABLED))
104endif
105endif
106
107# Decide on the branch protection scheme
108ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_BTI)))
109ifeq ($(call TOBOOL,$(TRUSTY_APP_IN_TREE)),false)
110MODULE_LDFLAGS += -z bti-report=warning
111endif
112ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_PAC)))
113MODULE_COMPILEFLAGS += -mbranch-protection=bti+pac-ret \
114                       -DBTI_ENABLED \
115                       -DPAC_ENABLED
116MODULE_RUSTFLAGS += -Z branch-protection=bti,pac-ret
117else # !MODULE_ENABLE_PAC
118MODULE_COMPILEFLAGS += -mbranch-protection=bti \
119                       -DBTI_ENABLED
120MODULE_RUSTFLAGS += -Z branch-protection=bti
121endif
122else # !MODULE_ENABLE_BTI
123ifeq (true,$(call TOBOOL,$(MODULE_ENABLE_PAC)))
124MODULE_COMPILEFLAGS += -mbranch-protection=pac-ret \
125                       -DPAC_ENABLED
126MODULE_RUSTFLAGS += -Z branch-protection=pac-ret
127endif
128endif
129
130# Stack protector
131ifneq (true,$(call TOBOOL,$(MODULE_DISABLE_STACK_PROTECTOR)))
132ifeq (true,$(call TOBOOL,$(USER_STACK_PROTECTOR)))
133MODULE_COMPILEFLAGS += -fstack-protector-strong
134endif
135else
136MODULE_COMPILEFLAGS += -fno-stack-protector
137endif
138
139# Shadow call stack
140ifeq (true,$(call TOBOOL,$(SCS_ENABLED)))
141# set in arch/$(ARCH)/toolchain.mk iff shadow call stack is supported
142ifeq (false,$(call TOBOOL,$(ARCH_$(ARCH)_SUPPORTS_SCS)))
143$(error Error: Shadow call stack is not supported for $(ARCH))
144endif
145
146ifeq (false,$(call TOBOOL,$(TRUSTY_APP_DISABLE_SCS)))
147ifeq (false,$(call TOBOOL,$(MODULE_DISABLE_SCS)))
148# architectures that support SCS should set the flag that reserves
149# a register for the shadow call stack in their toolchain.mk file
150MODULE_COMPILEFLAGS += -fsanitize=shadow-call-stack
151
152# The Rust target aarch64-unknown-trusty enables reserve-x18 by default.
153# Doing so through rustc args causes a warning and is unnecessary, so we
154# don't pass it explicitly via MODULE_RUSTFLAGS if TRUSTY_USER_ARCH is arm64.
155# See https://github.com/rust-lang/rust/issues/96472#issuecomment-1200319324
156# for why rustc warns on this and it is not a rustc bug.
157
158endif
159else  # TRUSTY_APP_DISABLE_SCS
160$(warning $(MODULE) has set TRUSTY_APP_DISABLE_SCS, this flag only works as intended for apps w/o dependencies)
161endif
162endif # SCS_ENABLED
163
164# Code coverage
165ifeq (true,$(call TOBOOL,$(USER_COVERAGE_ENABLED)))
166ifeq (false,$(call TOBOOL, $(MODULE_DISABLE_COVERAGE)))
167MODULE_LIBRARY_DEPS += trusty/user/base/lib/sancov
168
169# -fno-optimize-sibling-calls/-fno-inline is necessary to get correct caller
170# information in the sancov instrumentation.
171MODULE_COMPILEFLAGS += \
172	-fsanitize-coverage-ignorelist=trusty/user/base/lib/sancov/exemptlist \
173	-fsanitize-coverage=trace-pc-guard \
174	-fno-inline \
175	-fno-optimize-sibling-calls
176
177endif
178endif
179
180# Source based code coverage
181ifeq (true,$(call TOBOOL,$(UNITTEST_COVERAGE_ENABLED)))
182ifeq (false,$(call TOBOOL, $(MODULE_DISABLE_COVERAGE)))
183MODULE_COMPILEFLAGS += -DUNITTEST_COVERAGE  \
184	-fprofile-instr-generate \
185	-fcoverage-mapping \
186	-mllvm \
187	-enable-value-profiling=false
188
189endif
190endif
191
192# Fuzzing build
193ifeq (true,$(call TOBOOL,$(FUZZING_BUILD_ENABLED)))
194MODULE_COMPILEFLAGS += \
195	-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \
196
197endif
198
199# HWASan
200ifeq (true,$(call TOBOOL,$(USER_HWASAN_ENABLED)))
201MODULE_DEFINES += \
202	HWASAN_ENABLED=1 \
203	HWASAN_SHADOW_SCALE=4 \
204
205MODULE_LIBRARY_DEPS += trusty/user/base/lib/hwasan
206MODULE_COMPILEFLAGS += \
207	-fsanitize-blacklist=trusty/user/base/lib/hwasan/exemptlist \
208	-fsanitize=hwaddress \
209	-mllvm -hwasan-with-tls=0 \
210	-mllvm -hwasan-globals=0 \
211	-mllvm -hwasan-use-short-granules=0 \
212
213endif
214
215MODULE_DEFINES += TRUSTY_USERSPACE=1
216
217endif # TRUSTY_USERSPACE
218
219MODULE_CFI_ENABLED :=
220MODULE_DISABLE_BTI :=
221MODULE_DISABLE_CFI :=
222MODULE_DISABLE_COVERAGE :=
223MODULE_DISABLE_LTO :=
224MODULE_DISABLE_SCS :=
225MODULE_DISABLE_STACK_PROTECTOR :=
226