1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! Memory layout.
16
17 #![allow(unused_unsafe)]
18
19 #[cfg(target_arch = "aarch64")]
20 use crate::arch::aarch64::linker::__stack_chk_guard;
21 use crate::arch::VirtualAddress;
22 use crate::memory::{max_stack_size, PAGE_SIZE};
23 use core::ops::Range;
24
25 #[cfg(target_arch = "aarch64")]
26 pub use crate::arch::aarch64::layout as crosvm;
27
28 /// First address that can't be translated by a level 1 TTBR0_EL1.
29 pub const MAX_VIRT_ADDR: usize = 1 << 40;
30
31 /// Get an address from a linker-defined symbol.
32 #[macro_export]
33 macro_rules! linker_addr {
34 ($symbol:ident) => {{
35 #[cfg(target_arch = "aarch64")]
36 let addr = (&raw const $crate::arch::aarch64::linker::$symbol) as usize;
37 VirtualAddress(addr)
38 }};
39 }
40
41 /// Gets the virtual address range between a pair of linker-defined symbols.
42 #[macro_export]
43 macro_rules! linker_region {
44 ($begin:ident,$end:ident) => {{
45 let start = linker_addr!($begin);
46 let end = linker_addr!($end);
47 start..end
48 }};
49 }
50
51 /// Executable code.
text_range() -> Range<VirtualAddress>52 pub fn text_range() -> Range<VirtualAddress> {
53 linker_region!(text_begin, text_end)
54 }
55
56 /// Read-only data.
rodata_range() -> Range<VirtualAddress>57 pub fn rodata_range() -> Range<VirtualAddress> {
58 linker_region!(rodata_begin, rodata_end)
59 }
60
61 /// Region which may contain a footer appended to the binary at load time.
image_footer_range() -> Range<VirtualAddress>62 pub fn image_footer_range() -> Range<VirtualAddress> {
63 linker_region!(image_footer_begin, image_footer_end)
64 }
65
66 /// Initialised writable data.
data_range() -> Range<VirtualAddress>67 pub fn data_range() -> Range<VirtualAddress> {
68 linker_region!(data_begin, data_end)
69 }
70
71 /// Zero-initialized writable data.
bss_range() -> Range<VirtualAddress>72 pub fn bss_range() -> Range<VirtualAddress> {
73 linker_region!(bss_begin, bss_end)
74 }
75
76 /// Writable data region for .data and .bss.
data_bss_range() -> Range<VirtualAddress>77 pub fn data_bss_range() -> Range<VirtualAddress> {
78 linker_region!(data_begin, bss_end)
79 }
80
81 /// Writable data region for the stack.
stack_range() -> Range<VirtualAddress>82 pub fn stack_range() -> Range<VirtualAddress> {
83 let end = linker_addr!(init_stack_pointer);
84 let start = if let Some(stack_size) = max_stack_size() {
85 assert_eq!(stack_size % PAGE_SIZE, 0);
86 let start = VirtualAddress(end.0.checked_sub(stack_size).unwrap());
87 assert!(start >= linker_addr!(stack_limit));
88 start
89 } else {
90 linker_addr!(stack_limit)
91 };
92
93 start..end
94 }
95
96 /// Writable data region for the exception handler stack.
eh_stack_range() -> Range<VirtualAddress>97 pub fn eh_stack_range() -> Range<VirtualAddress> {
98 linker_region!(eh_stack_limit, init_eh_stack_pointer)
99 }
100
101 /// Range of the page at UART_PAGE_ADDR of PAGE_SIZE.
102 #[cfg(target_arch = "aarch64")]
console_uart_page() -> Range<VirtualAddress>103 pub fn console_uart_page() -> Range<VirtualAddress> {
104 VirtualAddress(crosvm::UART_PAGE_ADDR)..VirtualAddress(crosvm::UART_PAGE_ADDR + PAGE_SIZE)
105 }
106
107 /// Read-write data (original).
data_load_address() -> VirtualAddress108 pub fn data_load_address() -> VirtualAddress {
109 linker_addr!(data_lma)
110 }
111
112 /// End of the binary image.
binary_end() -> VirtualAddress113 pub fn binary_end() -> VirtualAddress {
114 linker_addr!(bin_end)
115 }
116
117 /// Value of __stack_chk_guard.
stack_chk_guard() -> u64118 pub fn stack_chk_guard() -> u64 {
119 // SAFETY: __stack_chk_guard shouldn't have any mutable aliases unless the stack overflows. If
120 // it does, then there could be undefined behaviour all over the program, but we want to at
121 // least have a chance at catching it.
122 unsafe { (&raw const __stack_chk_guard).read_volatile() }
123 }
124