Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip debug symbols from kernel #59

Merged
merged 3 commits into from
Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
- Make the physical memory offset configurable through a `BOOTLOADER_PHYSICAL_MEMORY_OFFSET` environment variable ([#58](https://github.com/rust-osdev/bootloader/pull/58)).
- Use a stripped copy of the kernel binary (debug info removed) to reduce load times ([#59](https://github.com/rust-osdev/bootloader/pull/59)).

# 0.6.0

Expand Down
52 changes: 33 additions & 19 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,18 @@ fn main() {
process::exit(1);
}
});
let kernel_file_name = kernel
.file_name()
.expect("KERNEL has no valid file name")
.to_str()
.expect("kernel file name not valid utf8");

// check that the kernel file exists
assert!(
kernel.exists(),
format!("KERNEL does not exist: {}", kernel.display())
);

let kernel_file_name = kernel
.file_name()
.expect("KERNEL has no valid file name")
.to_str()
.expect("kernel file name not valid utf8");
let kernel_file_name_replaced = kernel_file_name.replace('-', "_");
let kernel_out_path = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
let kernel_archive_path = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));

// get access to llvm tools shipped in the llvm-tools-preview rustup component
let llvm_tools = match llvm_tools::LlvmTools::new() {
Ok(tools) => tools,
Expand Down Expand Up @@ -76,30 +72,48 @@ fn main() {
Kernel executable at `{}`\n", kernel.display());
}

// wrap the kernel executable as binary in a new ELF file
// strip debug symbols from kernel for faster loading
let stripped_kernel_file_name = format!("kernel_stripped-{}", kernel_file_name);
let stripped_kernel = out_dir.join(&stripped_kernel_file_name);
let objcopy = llvm_tools
.tool(&llvm_tools::exe("llvm-objcopy"))
.expect("llvm-objcopy not found in llvm-tools");
let mut cmd = Command::new(objcopy);
let mut cmd = Command::new(&objcopy);
cmd.arg("--strip-debug");
cmd.arg(&kernel);
cmd.arg(&stripped_kernel);
let exit_status = cmd
.status()
.expect("failed to run objcopy to strip debug symbols");
if !exit_status.success() {
eprintln!("Error: Stripping debug symbols failed");
process::exit(1);
}

// wrap the kernel executable as binary in a new ELF file
let stripped_kernel_file_name_replaced = stripped_kernel_file_name.replace('-', "_");
let kernel_bin = out_dir.join(format!("kernel_bin-{}.o", kernel_file_name));
let kernel_archive = out_dir.join(format!("libkernel_bin-{}.a", kernel_file_name));
let mut cmd = Command::new(&objcopy);
cmd.arg("-I").arg("binary");
cmd.arg("-O").arg("elf64-x86-64");
cmd.arg("--binary-architecture=i386:x86-64");
cmd.arg("--rename-section").arg(".data=.kernel");
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_start=_kernel_start_addr",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_end=_kernel_end_addr",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.arg("--redefine-sym").arg(format!(
"_binary_{}_size=_kernel_size",
kernel_file_name_replaced
stripped_kernel_file_name_replaced
));
cmd.current_dir(kernel.parent().expect("KERNEL has no valid parent dir"));
cmd.arg(&kernel_file_name);
cmd.arg(&kernel_out_path);
cmd.current_dir(&out_dir);
cmd.arg(&stripped_kernel_file_name);
cmd.arg(&kernel_bin);
let exit_status = cmd.status().expect("failed to run objcopy");
if !exit_status.success() {
eprintln!("Error: Running objcopy failed");
Expand All @@ -117,8 +131,8 @@ fn main() {
});
let mut cmd = Command::new(ar);
cmd.arg("crs");
cmd.arg(&kernel_archive_path);
cmd.arg(&kernel_out_path);
cmd.arg(&kernel_archive);
cmd.arg(&kernel_bin);
let exit_status = cmd.status().expect("failed to run ar");
if !exit_status.success() {
eprintln!("Error: Running ar failed");
Expand Down