Commit work

This commit is contained in:
pjht 2023-09-29 15:44:53 -05:00
parent bf09798825
commit 8fd2b83b40
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
17 changed files with 277 additions and 137 deletions

View File

@ -3,8 +3,8 @@ build-std-features = ["compiler-builtins-mem"]
build-std = ["core", "compiler_builtins", "alloc"]
[build]
target = "x86_64-unknown-none.json"
rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-arg=/home/pjht/projects/os-rust/kernel/eh_frame.ld"]
target = "x86_64-unknown-none"
rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-args=/home/pjht/projects/os-rust/kernel/eh_frame.ld"]
[target.'cfg(target_os = "none")']
runner = "./run.sh"

8
Cargo.lock generated
View File

@ -38,10 +38,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bootloader"
version = "0.10.13"
name = "bootloader_api"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e13520aa8580a2850fc9f5390dc6753f1062fb66f90e5a61bd5c72b55df731"
checksum = "babfb07dea4565842980315ad530a023aa348db43d03dfa104a70fdaca97d48e"
[[package]]
name = "cfg-if"
@ -118,7 +118,7 @@ dependencies = [
name = "kernel"
version = "0.1.0"
dependencies = [
"bootloader",
"bootloader_api",
"crossbeam-queue",
"elfloader",
"hashbrown",

View File

@ -8,39 +8,17 @@ x86_64 = { git = "https://github.com/pjht/x86_64", features = ["experimental"] }
tar-no-std = { path = "../tar-no-std" }
unwinding = { path = "../unwinding", default-features = false, features = ["personality", "panic", "unwinder", "fde-static", "hide-trace"] }
uart_16550 = "0.2.15"
spin = "0.9.2"
linked_list_allocator = "0.9.1"
elfloader = "0.14.0"
uart_16550 = "0.2.18"
spin = "0.9.4"
linked_list_allocator = "0.10.4"
elfloader = "0.16.0"
tap = "1.0.1"
replace_with = { version = "0.1.7", default-features = false, features = ["nightly"] }
hashbrown = "0.12.0"
hashbrown = "0.13.1"
pic8259 = "0.10.2"
bootloader = "0.10.13"
bootloader_api = "0.11.0"
static_assertions = "1.1.0"
crossbeam-queue = { version = "0.3.4", default-features = false, features = ["alloc"] }
slab = { version = "0.4.6", default-features = false }
crossbeam-queue = { version = "0.3.8", default-features = false, features = ["alloc"] }
slab = { version = "0.4.7", default-features = false }
intrusive-collections = "0.9.4"
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
strip = true
[features]
[package.metadata.bootimage]
run-args = ["-nographic", "-m", "4G", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "--no-reboot", "-hdb", "../ext2.img"]
[package.metadata.bootloader]
map-physical-memory = true
dynamic-range-start = "0xFFFF_8000_0000_0000"
# physical-memory-offset = "0xFFFFFF8000000000"
# kernel-stack-address = "0xFFFFFF7FFFE00000"
# boot-info-address = "0xFFFFFF7FFFC00000"
# kernel-stack-size = 2093056 # 511 pages
[patch.crates-io]
x86_64 = { git = "https://github.com/pjht/x86_64" }
xmas-elf = "0.8.0"

Binary file not shown.

3
run.sh
View File

@ -1,3 +0,0 @@
#! /bin/bash
cd ../simple_boot
cargo run -- $@

View File

@ -1,4 +1,4 @@
use bootloader::boot_info::BootInfo;
use bootloader_api::BootInfo;
use core::ops::Deref;
use spin::Once;

View File

@ -1,5 +1,5 @@
use crate::{
print, println,
dbg, print, println,
virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE},
INITRD, TASKING,
};
@ -215,6 +215,9 @@ extern "C" fn syscall_handler() {
let mut retval = 0;
let mut retval2 = regs.rcx;
let mut retval3 = regs.rdx;
// if regs.rax == 16 {
// println!("Syscall {}", regs.rax);
// }
match regs.rax {
0 => {
retval = if let Some(chr) = char::from_u32(regs.rcx as u32) {
@ -358,11 +361,16 @@ extern "C" fn syscall_handler() {
let size = regs.rcx as usize;
let rounded_size = size + (4096 - (size % 4096));
KERNEL_SPACE.lock().alloc_force_user = true;
let buffer = Box::into_raw(
Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE)
.tap_mut(|v| v.resize(rounded_size, 0))
.into_boxed_slice(),
);
// let buffer = Box::into_raw(
// Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE)
// .tap_mut(|v| v.resize(rounded_size, 0))
// .into_boxed_slice(),
// );
let mut buffer = Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE);
// dbg!(KERNEL_SPACE.lock().translate(VirtAddr::new(0xffff_8000_003f_f000)));
buffer.resize(rounded_size, 0);
let buffer = buffer.into_boxed_slice();
let buffer = Box::into_raw(buffer);
KERNEL_SPACE.lock().alloc_force_user = false;
retval = TASKING.lock().data_buffers_mut().insert(buffer) as u64;
retval2 = buffer as *mut u8 as u64;
@ -370,6 +378,9 @@ extern "C" fn syscall_handler() {
}
_ => (),
};
// if regs.rax == 16 {
// println!("Syscall {} done", regs.rax);
// }
unsafe {
asm!(
"mov rbx, [rip+SYSCALL_REGS+8]",

View File

@ -1,13 +1,50 @@
use crate::virtual_memory::KERNEL_SPACE;
use alloc::{alloc::Layout, boxed::Box};
use linked_list_allocator::LockedHeap;
use core::{
alloc::{GlobalAlloc, Layout},
ptr::NonNull,
};
use linked_list_allocator::hole::HoleList;
use spin::Mutex;
use x86_64::structures::paging::PageTableFlags;
struct Heap(Mutex<HoleList>);
unsafe impl Send for Heap {}
unsafe impl Sync for Heap {}
unsafe impl GlobalAlloc for Heap {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let mut locked_self = self.0.lock();
let ptr = locked_self
.allocate_first_fit(layout)
.map(|(allocation, _)| allocation.as_ptr())
.unwrap_or_else(|_| {
drop(locked_self);
let num_pages = layout.size().div_ceil(4096) * 2;
unsafe {
self.dealloc(
KERNEL_SPACE.lock().map_free(num_pages, PageTableFlags::empty()).unwrap(),
Layout::from_size_align(num_pages * 4096, 4096).unwrap(),
);
}
self.0
.lock()
.allocate_first_fit(layout)
.map(|(allocation, _)| allocation.as_ptr())
.unwrap()
});
assert!((ptr as usize & (layout.align() - 1)) == 0);
ptr
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { self.0.lock().deallocate(NonNull::new_unchecked(ptr), layout) };
}
}
#[global_allocator]
static HEAP: LockedHeap = LockedHeap::empty();
pub fn init() {
HEAP.lock().init_from_slice(Box::leak(Box::new_uninit_slice_in(131_072 * 4, &*KERNEL_SPACE)));
}
static HEAP: Heap = Heap(Mutex::new(HoleList::empty()));
#[alloc_error_handler]
fn alloc_error_handler(layout: Layout) -> ! {

View File

@ -24,32 +24,40 @@ mod start;
mod tasking;
mod virtual_memory;
use simple_loader::SimpleLoader;
use tasking::TASKING;
pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
use elfloader::ElfBinary;
use simple_loader::SimpleLoader;
use tar_no_std::TarArchiveRef;
use tasking::TASKING;
use x86_64::registers::rflags::{self, RFlags};
pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
pub fn main() {
dbg!();
let mut rflags_data = rflags::read();
dbg!();
rflags_data |= RFlags::IOPL_HIGH | RFlags::IOPL_LOW;
dbg!();
unsafe {
rflags::write(rflags_data);
}
dbg!();
gdt::init();
dbg!();
interrupts::init();
kernel_heap::init();
dbg!();
pit::init(100);
dbg!();
let initrd = TarArchiveRef::new(INITRD);
let init = ElfBinary::new(
initrd
dbg!();
let init = initrd
.entries()
.find(|x| x.filename() == *"bin/init")
.expect("Could not find init in initrd")
.data(),
)
.expect("Init not an ELF binary");
.data();
dbg!();
let init = ElfBinary::new(init).expect("Init not an ELF binary");
dbg!();
TASKING
.lock()
.new_process(
@ -57,4 +65,5 @@ pub fn main() {
SimpleLoader::load(&init).expect("Failed to load init"),
)
.expect("Failed to create init process");
dbg!();
}

View File

@ -1,5 +1,5 @@
use crate::{bootinfo::BOOTINFO, println, virtual_memory::AsVirt};
use bootloader::boot_info::MemoryRegionKind;
use crate::{bootinfo::BOOTINFO, dbg, println, virtual_memory::AsVirt};
use bootloader_api::info::MemoryRegionKind;
use core::mem;
use spin::{Lazy, Mutex};
use tap::Tap;

View File

@ -1,10 +1,14 @@
use crate::virtual_memory::{AddressSpace, PagingError};
use core::slice;
use elfloader::{ElfBinary, ElfLoader, ElfLoaderErr, Flags, LoadableHeaders, Rela, VAddr, P64};
use elfloader::{
arch::x86_64::RelocationTypes, ElfBinary, ElfLoader, ElfLoaderErr, Flags, LoadableHeaders,
RelocationEntry, RelocationType, VAddr,
};
use x86_64::{
structures::paging::{Page, PageTableFlags},
VirtAddr,
};
#[derive(Debug)]
pub enum LoadError {
Paging(PagingError),
@ -37,20 +41,60 @@ impl ElfLoader for SimpleLoader {
fn allocate(&mut self, load_headers: LoadableHeaders) -> Result<(), ElfLoaderErr> {
for header in load_headers {
let start_page = Page::containing_address(VirtAddr::new(header.virtual_addr()));
let num_pages = (header.mem_size().div_ceil(4096)
+ (header.virtual_addr() & 0xFFF).div_ceil(4096))
as usize;
assert!(
(start_page.start_address().as_u64() + num_pages as u64 * 4096)
>= (header.virtual_addr() + header.mem_size())
);
#[allow(clippy::cast_possible_truncation)]
self.0
.map_assert_unused(
start_page,
((header.mem_size() + (header.virtual_addr() % 4096)).div_ceil(4096)) as usize,
PageTableFlags::USER_ACCESSIBLE,
)
.map_only_unused(start_page, num_pages, PageTableFlags::USER_ACCESSIBLE)
.expect("Unable to map region");
}
Ok(())
}
fn relocate(&mut self, _entry: &Rela<P64>) -> Result<(), ElfLoaderErr> {
Err(ElfLoaderErr::UnsupportedRelocationEntry)
fn relocate(&mut self, entry: RelocationEntry) -> Result<(), ElfLoaderErr> {
let rel = match entry.rtype {
RelocationType::x86_64(rel) => rel,
_ => panic!("Non x86_64 relocation"),
};
match rel {
RelocationTypes::R_AMD64_NONE => (),
RelocationTypes::R_AMD64_64 => todo!(),
RelocationTypes::R_AMD64_PC32 => todo!(),
RelocationTypes::R_AMD64_GOT32 => todo!(),
RelocationTypes::R_AMD64_PLT32 => todo!(),
RelocationTypes::R_AMD64_COPY => todo!(),
RelocationTypes::R_AMD64_GLOB_DAT => todo!(),
RelocationTypes::R_AMD64_JMP_SLOT => todo!(),
RelocationTypes::R_AMD64_RELATIVE => {
self.0.run(|| unsafe {
let ptr = entry.offset as *mut u64;
ptr.write(entry.addend.unwrap());
});
}
RelocationTypes::R_AMD64_GOTPCREL => todo!(),
RelocationTypes::R_AMD64_32 => todo!(),
RelocationTypes::R_AMD64_32S => todo!(),
RelocationTypes::R_AMD64_16 => todo!(),
RelocationTypes::R_AMD64_PC16 => todo!(),
RelocationTypes::R_AMD64_8 => todo!(),
RelocationTypes::R_AMD64_PC8 => todo!(),
RelocationTypes::R_AMD64_DTPMOD64 => todo!(),
RelocationTypes::R_AMD64_DTPOFF64 => todo!(),
RelocationTypes::R_AMD64_TPOFF64 => todo!(),
RelocationTypes::R_AMD64_TLSGD => todo!(),
RelocationTypes::R_AMD64_TLSLD => todo!(),
RelocationTypes::R_AMD64_DTPOFF32 => todo!(),
RelocationTypes::R_AMD64_GOTTPOFF => todo!(),
RelocationTypes::R_AMD64_TPOFF32 => todo!(),
RelocationTypes::Unknown(_) => todo!(),
}
// Err(ElfLoaderErr::UnsupportedRelocationEntry)
Ok(())
}
fn load(&mut self, _flags: Flags, base: VAddr, region: &[u8]) -> Result<(), ElfLoaderErr> {

View File

@ -1,7 +1,14 @@
use crate::{bootinfo::BOOTINFO, main, tasking::TASKING};
use bootloader::{boot_info::BootInfo, entry_point};
use bootloader_api::{config::Mapping, entry_point, BootInfo, BootloaderConfig};
entry_point!(start);
pub static BOOTLOADER_CONFIG: BootloaderConfig = {
let mut config = BootloaderConfig::new_default();
config.mappings.physical_memory = Some(Mapping::Dynamic);
config.mappings.dynamic_range_start = Some(0xFFFF_8000_0000_0000);
config
};
entry_point!(start, config = &BOOTLOADER_CONFIG);
#[allow(clippy::missing_panics_doc)]
#[allow(clippy::missing_errors_doc)]

View File

@ -1,6 +1,6 @@
mod holes;
use crate::{bootinfo::BOOTINFO, physical_memory::PHYSICAL_MEMORY};
use crate::{bootinfo::BOOTINFO, dbg, physical_memory::PHYSICAL_MEMORY, println};
use alloc::alloc::{AllocError, Allocator, Layout};
use core::{fmt, ops::Deref, ptr::NonNull, slice};
use replace_with::replace_with_or_abort;
@ -132,7 +132,8 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
}
for i in 256..512 {
if table[i].flags().contains(PageTableFlags::PRESENT) {
let new_flags = table[i].flags() & !PageTableFlags::USER_ACCESSIBLE;
let new_flags =
table[i].flags() | PageTableFlags::WRITABLE | PageTableFlags::USER_ACCESSIBLE;
table[i].set_flags(new_flags);
} else {
// SAFETY: We initialize the newly allocated table before we make a reference to it, so
@ -144,7 +145,9 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
new_child.write(PageTable::new());
new_child_phys
},
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
);
}
}
@ -190,7 +193,6 @@ impl AddressSpace {
}
}
#[allow(unused)]
pub fn activate(self) -> Self {
// This assert should never fire, as the only address space with the is_kernel bool set is
// stored in the KERNEL_SPACE_INTERNAL static, which is a Mutex, and you can never get
@ -213,7 +215,6 @@ impl AddressSpace {
}
}
#[allow(unused)]
fn check_request_unmapped(&self, start: Page, length: usize) -> Result<(), PagingError> {
for page in Page::range(start, start + length as u64) {
if self.translate_addr(page.start_address()).is_some() {
@ -230,7 +231,6 @@ impl AddressSpace {
/// let address_space = AddressSpace::new();
/// address_space.run(|| {/* your closure here */});
/// ```
#[allow(unused)]
pub fn run<F: FnOnce()>(&mut self, func: F) {
replace_with_or_abort(self, |cl_self| {
let old_space = cl_self.activate();
@ -272,22 +272,22 @@ impl AddressSpace {
flags: PageTableFlags,
) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?;
for (page, frame) in (PageRange { start: page, end: page + num_pages as u64 })
.zip(PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 })
{
unsafe {
self.mapper
.map_to_range_with_table_flags(
PageRange { start: page, end: page + num_pages as u64 },
PhysFrameRange { start: phys_frame, end: phys_frame + num_pages as u64 },
.map_to_with_table_flags(
page,
frame,
flags | PageTableFlags::PRESENT,
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
&mut *PHYSICAL_MEMORY.lock(),
)
.map_err(|(err, flush_range)| {
flush_range.flush_range();
err
})?
.flush_range();
)?
.flush();
}
}
Ok(page.start_address().as_mut_ptr())
}
@ -319,22 +319,46 @@ impl AddressSpace {
flags: PageTableFlags,
) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?;
for page in (PageRange { start: page, end: page + num_pages as u64 }) {
unsafe {
let mut phys_mem = PHYSICAL_MEMORY.lock();
let frame = phys_mem.allocate_frame().unwrap();
self.mapper
.map_range_with_table_flags(
PageRange { start: page, end: page + num_pages as u64 },
flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
.map_to_with_table_flags(
page,
frame,
flags
| PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| if self.alloc_force_user {
PageTableFlags::USER_ACCESSIBLE
} else {
PageTableFlags::empty()
},
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
&mut *PHYSICAL_MEMORY.lock(),
)
.map_err(|(err, flush_range)| {
flush_range.flush_range();
err
})?
.flush_range();
&mut *phys_mem,
)?
.flush();
}
}
// unsafe {
// self.mapper
// .map_range_with_table_flags(
// PageRange { start: page, end: page + num_pages as u64 },
// flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
// PageTableFlags::PRESENT
// | PageTableFlags::WRITABLE
// | PageTableFlags::USER_ACCESSIBLE,
// &mut *PHYSICAL_MEMORY.lock(),
// )
// .map_err(|(err, flush_range)| {
// flush_range.flush_range();
// err
// })?
// .flush_range();
// }
Ok(page.start_address().as_mut_ptr())
}
@ -383,6 +407,42 @@ impl AddressSpace {
unsafe { self.map(page, num_pages, flags) }
}
/// Same behavior as `map`, but only maps unmapped pages, and
/// thus is safe.
#[allow(unused)]
pub fn map_only_unused(
&mut self,
page: Page,
num_pages: usize,
flags: PageTableFlags,
) -> Result<*mut u8, PagingError> {
self.check_request_valid(page, num_pages)?;
if self.alloc_force_user {
panic!();
}
for page in (PageRange { start: page, end: page + num_pages as u64 }) {
if self.translate_addr(page.start_address()).is_some() {
continue;
}
unsafe {
let mut phys_mem = PHYSICAL_MEMORY.lock();
let frame = phys_mem.allocate_frame().unwrap();
self.mapper
.map_to_with_table_flags(
page,
frame,
flags | PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
PageTableFlags::PRESENT
| PageTableFlags::WRITABLE
| PageTableFlags::USER_ACCESSIBLE,
&mut *phys_mem,
)?
.flush();
}
}
Ok(page.start_address().as_mut_ptr())
}
/// Finds a range of free pages and returns the starting page
fn find_free_pages(&self, num_pages: usize) -> Result<Page, PagingError> {
let mut remaining_pages = num_pages;
@ -459,18 +519,29 @@ unsafe impl Allocator for ASpaceMutex {
PageTableFlags::empty()
};
let start = space.map_free(size / 4096, flags).map_err(|_| AllocError)?;
// if space.alloc_force_user {
// dbg!(start);
// }
Ok(unsafe { slice::from_raw_parts_mut(start.cast::<u8>(), size) }.into())
}
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
let start_page = Page::from_start_address(VirtAddr::new(ptr.as_ptr() as u64)).unwrap();
for page in Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64)
{
unsafe {
self.0.lock().mapper.unmap_range(
Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64),
&mut *PHYSICAL_MEMORY.lock(),
)
let (frame, flush) = self.0.lock().mapper.unmap(page).unwrap();
PHYSICAL_MEMORY.lock().deallocate_frame(frame);
flush.flush();
}
.unwrap()
.flush_all();
}
// unsafe {
// self.0.lock().mapper.unmap_range(
// Page::range(start_page, start_page + (layout.size().div_ceil(4096) - 1) as u64),
// &mut *PHYSICAL_MEMORY.lock(),
// )
// }
// .unwrap()
// .flush_all();
}
}

View File

@ -1 +1 @@
{"installs":{"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)":{"version_req":null,"bins":["init"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"},"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)":{"version_req":null,"bins":["test_proc"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"}}}
{"installs":{"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)":{"version_req":null,"bins":["init"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.68.0-nightly (3020239de 2023-01-09)\nbinary: rustc\ncommit-hash: 3020239de947ec52677e9b4e853a6a9fc073d1f9\ncommit-date: 2023-01-09\nhost: x86_64-unknown-linux-gnu\nrelease: 1.68.0-nightly\nLLVM version: 15.0.6\n"},"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)":{"version_req":null,"bins":["test_proc"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"}}}

Binary file not shown.

Binary file not shown.

View File

@ -1,14 +0,0 @@
{
"llvm-target": "x86_64-unknown-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"features": "-mmx,-sse,+soft-float"
}