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 pub mod crosvm;
18 
19 use crate::console::BASE_ADDRESS;
20 use crate::linker::__stack_chk_guard;
21 use aarch64_paging::paging::VirtualAddress;
22 use core::ops::Range;
23 use core::ptr::addr_of;
24 
25 /// First address that can't be translated by a level 1 TTBR0_EL1.
26 pub const MAX_VIRT_ADDR: usize = 1 << 40;
27 
28 /// Get an address from a linker-defined symbol.
29 #[macro_export]
30 macro_rules! linker_addr {
31     ($symbol:ident) => {{
32         // SAFETY: We're just getting the address of an extern static symbol provided by the linker,
33         // not dereferencing it.
34         let addr = unsafe { addr_of!($crate::linker::$symbol) as usize };
35         VirtualAddress(addr)
36     }};
37 }
38 
39 /// Gets the virtual address range between a pair of linker-defined symbols.
40 #[macro_export]
41 macro_rules! linker_region {
42     ($begin:ident,$end:ident) => {{
43         let start = linker_addr!($begin);
44         let end = linker_addr!($end);
45 
46         start..end
47     }};
48 }
49 
50 /// Memory reserved for the DTB.
dtb_range() -> Range<VirtualAddress>51 pub fn dtb_range() -> Range<VirtualAddress> {
52     linker_region!(dtb_begin, dtb_end)
53 }
54 
55 /// Executable code.
text_range() -> Range<VirtualAddress>56 pub fn text_range() -> Range<VirtualAddress> {
57     linker_region!(text_begin, text_end)
58 }
59 
60 /// Read-only data.
rodata_range() -> Range<VirtualAddress>61 pub fn rodata_range() -> Range<VirtualAddress> {
62     linker_region!(rodata_begin, rodata_end)
63 }
64 
65 /// Initialised writable data.
data_range() -> Range<VirtualAddress>66 pub fn data_range() -> Range<VirtualAddress> {
67     linker_region!(data_begin, data_end)
68 }
69 
70 /// Zero-initialized writable data.
bss_range() -> Range<VirtualAddress>71 pub fn bss_range() -> Range<VirtualAddress> {
72     linker_region!(bss_begin, bss_end)
73 }
74 
75 /// Writable data region for the stack.
stack_range(stack_size: usize) -> Range<VirtualAddress>76 pub fn stack_range(stack_size: usize) -> Range<VirtualAddress> {
77     let end = linker_addr!(init_stack_pointer);
78     let start = VirtualAddress(end.0.checked_sub(stack_size).unwrap());
79     assert!(start >= linker_addr!(stack_limit));
80 
81     start..end
82 }
83 
84 /// All writable sections, excluding the stack.
scratch_range() -> Range<VirtualAddress>85 pub fn scratch_range() -> Range<VirtualAddress> {
86     linker_region!(eh_stack_limit, bss_end)
87 }
88 
89 /// UART console range.
console_uart_range() -> Range<VirtualAddress>90 pub fn console_uart_range() -> Range<VirtualAddress> {
91     const CONSOLE_LEN: usize = 1; // `uart::Uart` only uses one u8 register.
92 
93     VirtualAddress(BASE_ADDRESS)..VirtualAddress(BASE_ADDRESS + CONSOLE_LEN)
94 }
95 
96 /// Read-write data (original).
data_load_address() -> VirtualAddress97 pub fn data_load_address() -> VirtualAddress {
98     linker_addr!(data_lma)
99 }
100 
101 /// End of the binary image.
binary_end() -> VirtualAddress102 pub fn binary_end() -> VirtualAddress {
103     linker_addr!(bin_end)
104 }
105 
106 /// Value of __stack_chk_guard.
stack_chk_guard() -> u64107 pub fn stack_chk_guard() -> u64 {
108     // SAFETY: __stack_chk_guard shouldn't have any mutable aliases unless the stack overflows. If
109     // it does, then there could be undefined behaviour all over the program, but we want to at
110     // least have a chance at catching it.
111     unsafe { addr_of!(__stack_chk_guard).read_volatile() }
112 }
113