• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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