From 45f2bea2b574c6783cfefe4479cbc0e61a657797 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 08:27:08 -0800 Subject: [PATCH 1/7] rust-toolchain: Update to latest nightly The current toolchain is 5 months old, and we want a new toolcahin for: - "efiapi" ABI - Using `Self` with enum implementations - Misc cargo improvements Signed-off-by: Joe Richey --- .travis.yml | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed6b8e11..1cd20090 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ dist: xenial language: rust rust: - - nightly-2019-05-10 + - nightly-2019-11-05 before_script: - rustup component add clippy diff --git a/rust-toolchain b/rust-toolchain index 109362de..5571d1ad 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2019-05-10 +nightly-2019-11-05 From 30287deec9bfcf89090db7ff3abf510a0409bbec Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 08:34:50 -0800 Subject: [PATCH 2/7] rustfmt: Run cargo fmt --all This also gets rid of some warnings Signed-off-by: Joe Richey --- src/bzimage.rs | 2 +- src/pe.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bzimage.rs b/src/bzimage.rs index 10779d0e..57f7e8e7 100644 --- a/src/bzimage.rs +++ b/src/bzimage.rs @@ -201,7 +201,7 @@ pub fn load_kernel(f: &mut Read) -> Result<(u64), Error> { let setup_bytes = setup_sects * 512; // Use to start reading the main image - let mut load_offset = u64::from(KERNEL_LOCATION);; + let mut load_offset = u64::from(KERNEL_LOCATION); f.seek(setup_bytes as u32)?; diff --git a/src/pe.rs b/src/pe.rs index 2e019920..2ac6cb69 100644 --- a/src/pe.rs +++ b/src/pe.rs @@ -236,5 +236,4 @@ mod tests { assert_eq!(a, fake_mem as u64 + 0x4000); assert_eq!(size, 110_592); } - } From 0acefedd6670d8a8b76983b9c60136dd175e9dcd Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 08:39:55 -0800 Subject: [PATCH 3/7] rust-toolchain: Fix warnings on new toolchain - &Trait -> &dyn Trait - Remove unneeded parens Signed-off-by: Joe Richey --- src/block.rs | 4 ++-- src/bzimage.rs | 4 ++-- src/fat.rs | 4 ++-- src/loader.rs | 2 +- src/part.rs | 4 ++-- src/pe.rs | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/block.rs b/src/block.rs index 6bc2ea2f..e0bac16d 100644 --- a/src/block.rs +++ b/src/block.rs @@ -70,7 +70,7 @@ struct UsedElem { #[cfg(not(test))] /// Device driver for virtio block over any transport pub struct VirtioBlockDevice<'a> { - transport: &'a mut VirtioTransport, + transport: &'a mut dyn VirtioTransport, state: RefCell, } @@ -131,7 +131,7 @@ enum RequestType { #[cfg(not(test))] impl<'a> VirtioBlockDevice<'a> { - pub fn new(transport: &'a mut VirtioTransport) -> VirtioBlockDevice<'a> { + pub fn new(transport: &'a mut dyn VirtioTransport) -> VirtioBlockDevice<'a> { VirtioBlockDevice { transport, state: RefCell::new(DriverState::default()), diff --git a/src/bzimage.rs b/src/bzimage.rs index 57f7e8e7..475e36de 100644 --- a/src/bzimage.rs +++ b/src/bzimage.rs @@ -56,7 +56,7 @@ struct E820Entry { } #[cfg(not(test))] -pub fn load_initrd(f: &mut Read) -> Result<(), Error> { +pub fn load_initrd(f: &mut dyn Read) -> Result<(), Error> { let mut zero_page = crate::mem::MemoryRegion::new(ZERO_PAGE_START as u64, 4096); let mut max_load_address = u64::from(zero_page.read_u32(0x22c)); @@ -147,7 +147,7 @@ pub fn append_commandline(addition: &str) -> Result<(), Error> { } #[cfg(not(test))] -pub fn load_kernel(f: &mut Read) -> Result<(u64), Error> { +pub fn load_kernel(f: &mut dyn Read) -> Result { f.seek(0)?; let mut buf: [u8; 1024] = [0; 1024]; diff --git a/src/fat.rs b/src/fat.rs index 2b2b9bc0..abc6c707 100644 --- a/src/fat.rs +++ b/src/fat.rs @@ -90,7 +90,7 @@ enum FatType { } pub struct Filesystem<'a> { - device: &'a SectorRead, + device: &'a dyn SectorRead, start: u64, last: u64, bytes_per_sector: u32, @@ -374,7 +374,7 @@ fn compare_name(name: &str, de: &DirectoryEntry) -> bool { } impl<'a> Filesystem<'a> { - pub fn new(device: &'a SectorRead, start: u64, last: u64) -> Filesystem { + pub fn new(device: &'a dyn SectorRead, start: u64, last: u64) -> Filesystem { Filesystem { device, start, diff --git a/src/loader.rs b/src/loader.rs index 8b6e8899..f819be23 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -126,7 +126,7 @@ fn default_entry_path(fs: &fat::Filesystem) -> Result<[u8; 260], fat::Error> { } #[cfg(not(test))] -pub fn load_default_entry(fs: &fat::Filesystem) -> Result<(u64), Error> { +pub fn load_default_entry(fs: &fat::Filesystem) -> Result { let default_entry_path = default_entry_path(&fs)?; let default_entry_path = ascii_strip(&default_entry_path); diff --git a/src/part.rs b/src/part.rs index ed53b267..b7e73ead 100644 --- a/src/part.rs +++ b/src/part.rs @@ -68,7 +68,7 @@ pub enum Error { NoEFIPartition, } -pub fn get_partitions(r: &SectorRead, parts_out: &mut [PartitionEntry]) -> Result { +pub fn get_partitions(r: &dyn SectorRead, parts_out: &mut [PartitionEntry]) -> Result { let mut data: [u8; 512] = [0; 512]; match r.read(1, &mut data) { Ok(_) => {} @@ -123,7 +123,7 @@ pub fn get_partitions(r: &SectorRead, parts_out: &mut [PartitionEntry]) -> Resul } /// Find EFI partition -pub fn find_efi_partition(r: &SectorRead) -> Result<(u64, u64), Error> { +pub fn find_efi_partition(r: &dyn SectorRead) -> Result<(u64, u64), Error> { // Assume no more than 16 partitions on the disk let mut parts: [PartitionEntry; 16] = unsafe { core::mem::zeroed() }; diff --git a/src/pe.rs b/src/pe.rs index 2ac6cb69..3dc1d526 100644 --- a/src/pe.rs +++ b/src/pe.rs @@ -15,7 +15,7 @@ use crate::mem::MemoryRegion; pub struct Loader<'a> { - file: &'a mut crate::fat::Read, + file: &'a mut dyn crate::fat::Read, num_sections: u16, image_base: u64, image_size: u32, @@ -38,7 +38,7 @@ struct Section { } impl<'a> Loader<'a> { - pub fn new(file: &'a mut crate::fat::Read) -> Loader { + pub fn new(file: &'a mut dyn crate::fat::Read) -> Loader { Loader { file, num_sections: 0, From c092ce0707f2993257ac671c565bf2e9e1f13a83 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 08:42:15 -0800 Subject: [PATCH 4/7] ci: Cleanup .travis.yml - Move image fetching out of main script - Move installation actions to "install" - Set warning configs via environment variables - Reorder sections to increase readablity Signed-off-by: Joe Richey --- .travis.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1cd20090..5c0c1f81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,26 +3,28 @@ language: rust rust: - nightly-2019-11-05 +env: + - RUSTFLAGS="-D warnings" -before_script: +addons: + apt: + update: true + +install: - rustup component add clippy - rustup component add rustfmt - rustup component add rust-src - cargo install cargo-xbuild - sudo apt-get install -y mtools - -addons: - apt: - update: true + - wget https://download.clearlinux.org/releases/28660/clear/clear-28660-kvm.img.xz + - unxz clear-28660-kvm.img.xz + - ./make-test-disks.sh script: - cargo xbuild --release --target target.json - - cargo xclippy -- -D warnings - - cargo clippy --all-targets --all-features -- -D warnings + - cargo xclippy + - cargo clippy --all-targets --all-features - cargo fmt --all -- --check - - wget https://download.clearlinux.org/releases/28660/clear/clear-28660-kvm.img.xz - - unxz clear-28660-kvm.img.xz - - ./make-test-disks.sh - cargo test deploy: From 1350859c8b47273a8049e3b42646e40b64e94bbb Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 11:50:37 -0800 Subject: [PATCH 5/7] build: Use lto and strip the binary - Makes the binary smaller - Prevents size regression when updating to new toolchain - Avoids bugs like: https://github.com/rust-lang/rust/issues/62785 Signed-off-by: Joe Richey --- .cargo/config | 2 ++ Cargo.toml | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 .cargo/config diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 00000000..03aa4e20 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,2 @@ +[target.target] +rustflags = ["-C", "link-arg=-s"] diff --git a/Cargo.toml b/Cargo.toml index 0cb11526..bbaecd5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,12 @@ edition = "2018" # the profile used for `cargo build` [profile.dev] panic = "abort" # disable stack unwinding on panic +lto = true # the profile used for `cargo build --release` [profile.release] panic = "abort" # disable stack unwinding on panic +lto = true [dependencies] cpuio = "*" From 061e10918b913eb03a3bedac71fa843020e50bfa Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 11:58:39 -0800 Subject: [PATCH 6/7] linker.ld: Reorder sections To allow for future flat BIOS builds, we reorder the sections to put the .text at the end (as that will contain the reset vector). We also remove the alignment requirements for the sections, as they are not necessary. This makes the binary about 10% smaller. Signed-off-by: Joe Richey --- layout.ld | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/layout.ld b/layout.ld index 5a792288..d1cf7e41 100644 --- a/layout.ld +++ b/layout.ld @@ -1,30 +1,15 @@ ENTRY(_start) - + SECTIONS { - . = 1M; - start_of_text = . ; - .text : ALIGN(4K) - { - *(.text .text.*) - } - end_of_text = . ; - + . = 1M ; start_of_data = . ; - .rodata : ALIGN(4K) - { - *(.rodata .rodata.*) - } - - .data : ALIGN(4K) - { - *(.data .data.*) - } + .rodata : { *(.rodata .rodata.*) } + .data : { *(.data .data.*) } + .bss : { *(COMMON) *(.bss .bss.*) } end_of_data = . ; - - .bss : ALIGN(4K) - { - *(COMMON) - *(.bss .bss.*) - } + + start_of_text = . ; + .text : { *(.text .text.*) } + end_of_text = . ; } From 0725a4e7b30e4e1fc3dcfcf465d5d7a6bdaa531c Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 5 Nov 2019 12:24:42 -0800 Subject: [PATCH 7/7] linker.ld: Use explict program headers This maps the file headers into readonly data, while preventing any other sections from being generated. It also makes the file 8% smaller. We also replace the marker symbols for {begin|end}_of_{text|data} with symbols denoting the begining/end of the file itself. Finally, we make an explict DISCARD section (based off of EDK2's GccBase.lds to prevent any additional data from entering our binary). Signed-off-by: Joe Richey --- layout.ld | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/layout.ld b/layout.ld index d1cf7e41..c3095013 100644 --- a/layout.ld +++ b/layout.ld @@ -1,15 +1,37 @@ ENTRY(_start) +PHDRS +{ + rodata PT_LOAD FILEHDR PHDRS ; + data PT_LOAD ; + text PT_LOAD ; +} + SECTIONS { . = 1M ; - start_of_data = . ; - .rodata : { *(.rodata .rodata.*) } - .data : { *(.data .data.*) } - .bss : { *(COMMON) *(.bss .bss.*) } - end_of_data = . ; - - start_of_text = . ; - .text : { *(.text .text.*) } - end_of_text = . ; + _start_of_file = . ; + + /* Mapping in the program headers makes it easier to mmap the whole file. */ + . += SIZEOF_HEADERS ; + + .rodata : { *(.rodata .rodata.*) } :rodata + .data : { *(.data .data.*) } :data + .bss : { *(.bss .bss.*) } :data + .text : { *(.text .text.*) } :text + + _end_of_file = . ; + + /* Match edk2's GccBase.lds DISCARD section */ + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.interp) + *(.dynsym) + *(.dynstr) + *(.dynamic) + *(.hash .gnu.hash) + *(.comment) + *(COMMON) + } }