Merge "Change visibility of alloc share/unshare functions to pub(crate)" into main
diff --git a/vmbase/src/bionic.rs b/vmbase/src/bionic.rs
index 2ce0e83..29fa0ff 100644
--- a/vmbase/src/bionic.rs
+++ b/vmbase/src/bionic.rs
@@ -22,6 +22,7 @@
use core::str;
use crate::console;
+use crate::cstr;
use crate::eprintln;
use crate::read_sysreg;
@@ -79,6 +80,11 @@
unsafe { ERRNO = value };
}
+fn get_errno() -> c_int {
+ // SAFETY: vmbase is currently single-threaded.
+ unsafe { ERRNO }
+}
+
/// Reports a fatal error detected by Bionic.
///
/// # Safety
@@ -154,142 +160,168 @@
#[no_mangle]
extern "C" fn strerror(n: c_int) -> *mut c_char {
- // Messages taken from errno(1).
- let s = match n {
- 0 => "Success",
- 1 => "Operation not permitted",
- 2 => "No such file or directory",
- 3 => "No such process",
- 4 => "Interrupted system call",
- 5 => "Input/output error",
- 6 => "No such device or address",
- 7 => "Argument list too long",
- 8 => "Exec format error",
- 9 => "Bad file descriptor",
- 10 => "No child processes",
- 11 => "Resource temporarily unavailable",
- 12 => "Cannot allocate memory",
- 13 => "Permission denied",
- 14 => "Bad address",
- 15 => "Block device required",
- 16 => "Device or resource busy",
- 17 => "File exists",
- 18 => "Invalid cross-device link",
- 19 => "No such device",
- 20 => "Not a directory",
- 21 => "Is a directory",
- 22 => "Invalid argument",
- 23 => "Too many open files in system",
- 24 => "Too many open files",
- 25 => "Inappropriate ioctl for device",
- 26 => "Text file busy",
- 27 => "File too large",
- 28 => "No space left on device",
- 29 => "Illegal seek",
- 30 => "Read-only file system",
- 31 => "Too many links",
- 32 => "Broken pipe",
- 33 => "Numerical argument out of domain",
- 34 => "Numerical result out of range",
- 35 => "Resource deadlock avoided",
- 36 => "File name too long",
- 37 => "No locks available",
- 38 => "Function not implemented",
- 39 => "Directory not empty",
- 40 => "Too many levels of symbolic links",
- 42 => "No message of desired type",
- 43 => "Identifier removed",
- 44 => "Channel number out of range",
- 45 => "Level 2 not synchronized",
- 46 => "Level 3 halted",
- 47 => "Level 3 reset",
- 48 => "Link number out of range",
- 49 => "Protocol driver not attached",
- 50 => "No CSI structure available",
- 51 => "Level 2 halted",
- 52 => "Invalid exchange",
- 53 => "Invalid request descriptor",
- 54 => "Exchange full",
- 55 => "No anode",
- 56 => "Invalid request code",
- 57 => "Invalid slot",
- 59 => "Bad font file format",
- 60 => "Device not a stream",
- 61 => "No data available",
- 62 => "Timer expired",
- 63 => "Out of streams resources",
- 64 => "Machine is not on the network",
- 65 => "Package not installed",
- 66 => "Object is remote",
- 67 => "Link has been severed",
- 68 => "Advertise error",
- 69 => "Srmount error",
- 70 => "Communication error on send",
- 71 => "Protocol error",
- 72 => "Multihop attempted",
- 73 => "RFS specific error",
- 74 => "Bad message",
- 75 => "Value too large for defined data type",
- 76 => "Name not unique on network",
- 77 => "File descriptor in bad state",
- 78 => "Remote address changed",
- 79 => "Can not access a needed shared library",
- 80 => "Accessing a corrupted shared library",
- 81 => ".lib section in a.out corrupted",
- 82 => "Attempting to link in too many shared libraries",
- 83 => "Cannot exec a shared library directly",
- 84 => "Invalid or incomplete multibyte or wide character",
- 85 => "Interrupted system call should be restarted",
- 86 => "Streams pipe error",
- 87 => "Too many users",
- 88 => "Socket operation on non-socket",
- 89 => "Destination address required",
- 90 => "Message too long",
- 91 => "Protocol wrong type for socket",
- 92 => "Protocol not available",
- 93 => "Protocol not supported",
- 94 => "Socket type not supported",
- 95 => "Operation not supported",
- 96 => "Protocol family not supported",
- 97 => "Address family not supported by protocol",
- 98 => "Address already in use",
- 99 => "Cannot assign requested address",
- 100 => "Network is down",
- 101 => "Network is unreachable",
- 102 => "Network dropped connection on reset",
- 103 => "Software caused connection abort",
- 104 => "Connection reset by peer",
- 105 => "No buffer space available",
- 106 => "Transport endpoint is already connected",
- 107 => "Transport endpoint is not connected",
- 108 => "Cannot send after transport endpoint shutdown",
- 109 => "Too many references: cannot splice",
- 110 => "Connection timed out",
- 111 => "Connection refused",
- 112 => "Host is down",
- 113 => "No route to host",
- 114 => "Operation already in progress",
- 115 => "Operation now in progress",
- 116 => "Stale file handle",
- 117 => "Structure needs cleaning",
- 118 => "Not a XENIX named type file",
- 119 => "No XENIX semaphores available",
- 120 => "Is a named type file",
- 121 => "Remote I/O error",
- 122 => "Disk quota exceeded",
- 123 => "No medium found",
- 124 => "Wrong medium type",
- 125 => "Operation canceled",
- 126 => "Required key not available",
- 127 => "Key has expired",
- 128 => "Key has been revoked",
- 129 => "Key was rejected by service",
- 130 => "Owner died",
- 131 => "State not recoverable",
- 132 => "Operation not possible due to RF-kill",
- 133 => "Memory page has hardware error",
- _ => "Unknown errno value",
+ cstr_error(n).as_ptr().cast_mut().cast()
+}
+
+#[no_mangle]
+extern "C" fn perror(s: *const c_char) {
+ let prefix = if s.is_null() {
+ None
+ } else {
+ // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+ let c_str = unsafe { CStr::from_ptr(s) };
+ // TODO(Rust 1.71): if c_str.is_empty() {
+ if c_str.to_bytes().is_empty() {
+ None
+ } else {
+ Some(c_str.to_str().unwrap())
+ }
};
- s.as_ptr().cast_mut().cast()
+ let error = cstr_error(get_errno()).to_str().unwrap();
+
+ if let Some(prefix) = prefix {
+ eprintln!("{prefix}: {error}");
+ } else {
+ eprintln!("{error}");
+ }
+}
+
+fn cstr_error(n: c_int) -> &'static CStr {
+ // Messages taken from errno(1).
+ match n {
+ 0 => cstr!("Success"),
+ 1 => cstr!("Operation not permitted"),
+ 2 => cstr!("No such file or directory"),
+ 3 => cstr!("No such process"),
+ 4 => cstr!("Interrupted system call"),
+ 5 => cstr!("Input/output error"),
+ 6 => cstr!("No such device or address"),
+ 7 => cstr!("Argument list too long"),
+ 8 => cstr!("Exec format error"),
+ 9 => cstr!("Bad file descriptor"),
+ 10 => cstr!("No child processes"),
+ 11 => cstr!("Resource temporarily unavailable"),
+ 12 => cstr!("Cannot allocate memory"),
+ 13 => cstr!("Permission denied"),
+ 14 => cstr!("Bad address"),
+ 15 => cstr!("Block device required"),
+ 16 => cstr!("Device or resource busy"),
+ 17 => cstr!("File exists"),
+ 18 => cstr!("Invalid cross-device link"),
+ 19 => cstr!("No such device"),
+ 20 => cstr!("Not a directory"),
+ 21 => cstr!("Is a directory"),
+ 22 => cstr!("Invalid argument"),
+ 23 => cstr!("Too many open files in system"),
+ 24 => cstr!("Too many open files"),
+ 25 => cstr!("Inappropriate ioctl for device"),
+ 26 => cstr!("Text file busy"),
+ 27 => cstr!("File too large"),
+ 28 => cstr!("No space left on device"),
+ 29 => cstr!("Illegal seek"),
+ 30 => cstr!("Read-only file system"),
+ 31 => cstr!("Too many links"),
+ 32 => cstr!("Broken pipe"),
+ 33 => cstr!("Numerical argument out of domain"),
+ 34 => cstr!("Numerical result out of range"),
+ 35 => cstr!("Resource deadlock avoided"),
+ 36 => cstr!("File name too long"),
+ 37 => cstr!("No locks available"),
+ 38 => cstr!("Function not implemented"),
+ 39 => cstr!("Directory not empty"),
+ 40 => cstr!("Too many levels of symbolic links"),
+ 42 => cstr!("No message of desired type"),
+ 43 => cstr!("Identifier removed"),
+ 44 => cstr!("Channel number out of range"),
+ 45 => cstr!("Level 2 not synchronized"),
+ 46 => cstr!("Level 3 halted"),
+ 47 => cstr!("Level 3 reset"),
+ 48 => cstr!("Link number out of range"),
+ 49 => cstr!("Protocol driver not attached"),
+ 50 => cstr!("No CSI structure available"),
+ 51 => cstr!("Level 2 halted"),
+ 52 => cstr!("Invalid exchange"),
+ 53 => cstr!("Invalid request descriptor"),
+ 54 => cstr!("Exchange full"),
+ 55 => cstr!("No anode"),
+ 56 => cstr!("Invalid request code"),
+ 57 => cstr!("Invalid slot"),
+ 59 => cstr!("Bad font file format"),
+ 60 => cstr!("Device not a stream"),
+ 61 => cstr!("No data available"),
+ 62 => cstr!("Timer expired"),
+ 63 => cstr!("Out of streams resources"),
+ 64 => cstr!("Machine is not on the network"),
+ 65 => cstr!("Package not installed"),
+ 66 => cstr!("Object is remote"),
+ 67 => cstr!("Link has been severed"),
+ 68 => cstr!("Advertise error"),
+ 69 => cstr!("Srmount error"),
+ 70 => cstr!("Communication error on send"),
+ 71 => cstr!("Protocol error"),
+ 72 => cstr!("Multihop attempted"),
+ 73 => cstr!("RFS specific error"),
+ 74 => cstr!("Bad message"),
+ 75 => cstr!("Value too large for defined data type"),
+ 76 => cstr!("Name not unique on network"),
+ 77 => cstr!("File descriptor in bad state"),
+ 78 => cstr!("Remote address changed"),
+ 79 => cstr!("Can not access a needed shared library"),
+ 80 => cstr!("Accessing a corrupted shared library"),
+ 81 => cstr!(".lib section in a.out corrupted"),
+ 82 => cstr!("Attempting to link in too many shared libraries"),
+ 83 => cstr!("Cannot exec a shared library directly"),
+ 84 => cstr!("Invalid or incomplete multibyte or wide character"),
+ 85 => cstr!("Interrupted system call should be restarted"),
+ 86 => cstr!("Streams pipe error"),
+ 87 => cstr!("Too many users"),
+ 88 => cstr!("Socket operation on non-socket"),
+ 89 => cstr!("Destination address required"),
+ 90 => cstr!("Message too long"),
+ 91 => cstr!("Protocol wrong type for socket"),
+ 92 => cstr!("Protocol not available"),
+ 93 => cstr!("Protocol not supported"),
+ 94 => cstr!("Socket type not supported"),
+ 95 => cstr!("Operation not supported"),
+ 96 => cstr!("Protocol family not supported"),
+ 97 => cstr!("Address family not supported by protocol"),
+ 98 => cstr!("Address already in use"),
+ 99 => cstr!("Cannot assign requested address"),
+ 100 => cstr!("Network is down"),
+ 101 => cstr!("Network is unreachable"),
+ 102 => cstr!("Network dropped connection on reset"),
+ 103 => cstr!("Software caused connection abort"),
+ 104 => cstr!("Connection reset by peer"),
+ 105 => cstr!("No buffer space available"),
+ 106 => cstr!("Transport endpoint is already connected"),
+ 107 => cstr!("Transport endpoint is not connected"),
+ 108 => cstr!("Cannot send after transport endpoint shutdown"),
+ 109 => cstr!("Too many references: cannot splice"),
+ 110 => cstr!("Connection timed out"),
+ 111 => cstr!("Connection refused"),
+ 112 => cstr!("Host is down"),
+ 113 => cstr!("No route to host"),
+ 114 => cstr!("Operation already in progress"),
+ 115 => cstr!("Operation now in progress"),
+ 116 => cstr!("Stale file handle"),
+ 117 => cstr!("Structure needs cleaning"),
+ 118 => cstr!("Not a XENIX named type file"),
+ 119 => cstr!("No XENIX semaphores available"),
+ 120 => cstr!("Is a named type file"),
+ 121 => cstr!("Remote I/O error"),
+ 122 => cstr!("Disk quota exceeded"),
+ 123 => cstr!("No medium found"),
+ 124 => cstr!("Wrong medium type"),
+ 125 => cstr!("Operation canceled"),
+ 126 => cstr!("Required key not available"),
+ 127 => cstr!("Key has expired"),
+ 128 => cstr!("Key has been revoked"),
+ 129 => cstr!("Key was rejected by service"),
+ 130 => cstr!("Owner died"),
+ 131 => cstr!("State not recoverable"),
+ 132 => cstr!("Operation not possible due to RF-kill"),
+ 133 => cstr!("Memory page has hardware error"),
+ _ => cstr!("Unknown errno value"),
+ }
}
diff --git a/vmbase/src/memory/shared.rs b/vmbase/src/memory/shared.rs
index 8d5f457..68f9ebd 100644
--- a/vmbase/src/memory/shared.rs
+++ b/vmbase/src/memory/shared.rs
@@ -27,6 +27,7 @@
use alloc::vec::Vec;
use buddy_system_allocator::{FrameAllocator, LockedFrameAllocator};
use core::alloc::Layout;
+use core::cmp::max;
use core::mem::size_of;
use core::num::NonZeroUsize;
use core::ops::Range;
@@ -354,6 +355,11 @@
}
fn try_shared_alloc(layout: Layout) -> Option<NonNull<u8>> {
+ // Adjusts the layout size to the max of the next power of two and the alignment,
+ // as this is the actual size of the memory allocated in `alloc_aligned()`.
+ let size = max(layout.size().next_power_of_two(), layout.align());
+ let layout = Layout::from_size_align(size, layout.align()).unwrap();
+
let mut shared_pool = SHARED_POOL.get().unwrap().lock();
if let Some(buffer) = shared_pool.alloc_aligned(layout) {