mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 09:06:32 +00:00
refacotr: remove all c files (#1131)
* refacotr: remove all c files Use Rust to implement the symbol table generator. Delete unused header files and c files Adjust the makefile in the debug directory Signed-off-by: Godones <chenlinfeng25@outlook.com> * fix: remove extern "C" rs_* functions move gen_kallsyms.rs to build-scripts Signed-off-by: Godones <chenlinfeng25@outlook.com>
This commit is contained in:
19
build-scripts/Cargo.lock
generated
19
build-scripts/Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
@ -87,12 +87,6 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "elf"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -109,6 +103,10 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gen_kallsyms"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
@ -193,13 +191,6 @@ version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||
|
||||
[[package]]
|
||||
name = "linux_boot_helper"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"elf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
|
@ -1,5 +1,3 @@
|
||||
[workspace]
|
||||
members = [
|
||||
"kernel_build",
|
||||
]
|
||||
members = ["gen_kallsyms", "kernel_build"]
|
||||
resolver = "2"
|
||||
|
@ -1,8 +1,9 @@
|
||||
.PHONY: fmt
|
||||
all:
|
||||
@cargo +nightly-2024-11-05 build --release -p gen_kallsyms
|
||||
fmt:
|
||||
cargo fmt --all $(FMT_CHECK)
|
||||
|
||||
clean:
|
||||
@cargo clean
|
||||
check:
|
||||
@cargo +nightly-2024-11-05 check --workspace $(CARGO_ZBUILD) --message-format=json
|
||||
.PHONY: fmt
|
6
build-scripts/gen_kallsyms/Cargo.toml
Normal file
6
build-scripts/gen_kallsyms/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "gen_kallsyms"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
122
build-scripts/gen_kallsyms/src/main.rs
Normal file
122
build-scripts/gen_kallsyms/src/main.rs
Normal file
@ -0,0 +1,122 @@
|
||||
use std::str;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct KernelSymbolEntry {
|
||||
vaddr: u64,
|
||||
#[allow(dead_code)]
|
||||
symbol_type: char,
|
||||
symbol: String,
|
||||
symbol_length: usize,
|
||||
}
|
||||
|
||||
fn symbol_to_write(vaddr: u64, text_vaddr: u64, etext_vaddr: u64) -> bool {
|
||||
vaddr >= text_vaddr && vaddr <= etext_vaddr
|
||||
}
|
||||
fn read_symbol(line: &str) -> Option<KernelSymbolEntry> {
|
||||
if line.len() > 512 {
|
||||
return None;
|
||||
} // skip line with length >= 512
|
||||
let mut parts = line.split_whitespace();
|
||||
let vaddr = u64::from_str_radix(parts.next()?, 16).ok()?;
|
||||
let symbol_type = parts.next()?.chars().next()?;
|
||||
let symbol = parts.collect::<Vec<_>>().join(" ");
|
||||
if symbol_type != 'T' && symbol_type != 't' {
|
||||
return None;
|
||||
} // local symbol or global symbol in text section
|
||||
if symbol == "$x" {
|
||||
return None;
|
||||
} // skip $x symbol
|
||||
let symbol_length = symbol.len() + 1; // +1 for null terminator
|
||||
Some(KernelSymbolEntry {
|
||||
vaddr,
|
||||
symbol_type,
|
||||
symbol,
|
||||
symbol_length,
|
||||
})
|
||||
}
|
||||
|
||||
fn read_map() -> (Vec<KernelSymbolEntry>, u64, u64) {
|
||||
let mut symbol_table = Vec::new();
|
||||
let mut text_vaddr = 0;
|
||||
let mut etext_vaddr = 0;
|
||||
let mut line = String::new();
|
||||
loop {
|
||||
let size = std::io::stdin().read_line(&mut line).unwrap();
|
||||
if size == 0 {
|
||||
break;
|
||||
}
|
||||
line = line.trim().to_string();
|
||||
if let Some(entry) = read_symbol(&line) {
|
||||
if entry.symbol.starts_with("_text") {
|
||||
text_vaddr = entry.vaddr;
|
||||
} else if entry.symbol.starts_with("_etext") {
|
||||
etext_vaddr = entry.vaddr;
|
||||
}
|
||||
symbol_table.push(entry);
|
||||
}
|
||||
line.clear();
|
||||
}
|
||||
(symbol_table, text_vaddr, etext_vaddr)
|
||||
}
|
||||
|
||||
fn generate_result(symbol_table: &[KernelSymbolEntry], text_vaddr: u64, etext_vaddr: u64) {
|
||||
println!(".section .rodata\n");
|
||||
println!(".global kallsyms_address");
|
||||
println!(".align 8\n");
|
||||
println!("kallsyms_address:");
|
||||
|
||||
let mut last_vaddr = 0;
|
||||
let mut total_syms_to_write = 0;
|
||||
|
||||
for entry in symbol_table {
|
||||
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("\t.quad\t{:#x}", entry.vaddr);
|
||||
total_syms_to_write += 1;
|
||||
last_vaddr = entry.vaddr;
|
||||
}
|
||||
|
||||
println!("\n.global kallsyms_num");
|
||||
println!(".align 8");
|
||||
println!("kallsyms_num:");
|
||||
println!("\t.quad\t{}", total_syms_to_write);
|
||||
|
||||
println!("\n.global kallsyms_names_index");
|
||||
println!(".align 8");
|
||||
println!("kallsyms_names_index:");
|
||||
|
||||
let mut position = 0;
|
||||
last_vaddr = 0;
|
||||
|
||||
for entry in symbol_table {
|
||||
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("\t.quad\t{}", position);
|
||||
position += entry.symbol_length;
|
||||
last_vaddr = entry.vaddr;
|
||||
}
|
||||
|
||||
println!("\n.global kallsyms_names");
|
||||
println!(".align 8");
|
||||
println!("kallsyms_names:");
|
||||
|
||||
last_vaddr = 0;
|
||||
|
||||
for entry in symbol_table {
|
||||
if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("\t.asciz\t\"{}\"", entry.symbol);
|
||||
last_vaddr = entry.vaddr;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (symbol_table, text_vaddr, etext_vaddr) = read_map();
|
||||
generate_result(&symbol_table, text_vaddr, etext_vaddr);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
use crate::utils::cargo_handler::{CargoHandler, TargetArch};
|
||||
|
||||
use self::x86_64::X86_64BindgenArch;
|
||||
|
||||
pub mod riscv64;
|
||||
pub mod x86_64;
|
||||
|
||||
pub(super) trait BindgenArch {
|
||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder;
|
||||
}
|
||||
|
||||
/// 获取当前的bindgen架构;
|
||||
pub(super) fn current_bindgenarch() -> &'static dyn BindgenArch {
|
||||
let arch = CargoHandler::target_arch();
|
||||
match arch {
|
||||
TargetArch::X86_64 => &X86_64BindgenArch,
|
||||
TargetArch::Riscv64 => &riscv64::RiscV64BindgenArch,
|
||||
_ => panic!("Unsupported arch: {:?}", arch),
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
use super::BindgenArch;
|
||||
|
||||
pub struct RiscV64BindgenArch;
|
||||
impl BindgenArch for RiscV64BindgenArch {
|
||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder {
|
||||
builder
|
||||
.clang_arg("-I./src/arch/riscv64/include")
|
||||
.clang_arg("--target=riscv64-none-none-elf")
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
use super::BindgenArch;
|
||||
|
||||
pub struct X86_64BindgenArch;
|
||||
|
||||
impl BindgenArch for X86_64BindgenArch {
|
||||
fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder {
|
||||
builder
|
||||
.clang_arg("-I./src/arch/x86_64/include")
|
||||
.clang_arg("--target=x86_64-none-none")
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
use crate::{bindgen::arch::current_bindgenarch, utils::cargo_handler::CargoHandler};
|
||||
|
||||
mod arch;
|
||||
|
||||
/// 生成 C->Rust bindings
|
||||
pub fn generate_bindings() {
|
||||
let wrapper_h = PathBuf::from_str("src/include/bindings/wrapper.h")
|
||||
.expect("Failed to parse 'wrapper.h' path");
|
||||
CargoHandler::emit_rerun_if_files_changed(&[wrapper_h.clone()]);
|
||||
|
||||
let out_path = PathBuf::from(String::from("src/include/bindings/"));
|
||||
|
||||
// The bindgen::Builder is the main entry point
|
||||
// to bindgen, and lets you build up options for
|
||||
// the resulting bindings.
|
||||
|
||||
let builder = bindgen::Builder::default()
|
||||
.clang_arg("-I./src")
|
||||
.clang_arg("-I./src/include")
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header(wrapper_h.to_str().unwrap())
|
||||
.blocklist_file("src/include/bindings/bindings.h")
|
||||
.clang_arg("-v")
|
||||
// 使用core,并将c语言的类型改为core::ffi,而不是使用std库。
|
||||
.use_core()
|
||||
.ctypes_prefix("::core::ffi")
|
||||
.generate_inline_functions(true)
|
||||
.raw_line("#![allow(dead_code)]")
|
||||
.raw_line("#![allow(non_upper_case_globals)]")
|
||||
.raw_line("#![allow(non_camel_case_types)]")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||
|
||||
// 处理架构相关的绑定
|
||||
let builder = current_bindgenarch().generate_bindings(builder);
|
||||
|
||||
// Finish the builder and generate the bindings.
|
||||
let bindings = builder
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
@ -12,11 +12,8 @@ pub mod x86_64;
|
||||
pub(super) trait CFilesArch {
|
||||
/// 设置架构相关的宏定义
|
||||
fn setup_defines(&self, c: &mut Build);
|
||||
/// 设置架构相关的全局包含目录
|
||||
fn setup_global_include_dir(&self, c: &mut HashSet<PathBuf>);
|
||||
/// 设置需要编译的架构相关的文件
|
||||
fn setup_files(&self, c: &mut Build, files: &mut HashSet<PathBuf>);
|
||||
|
||||
/// 设置架构相关的全局编译标志
|
||||
fn setup_global_flags(&self, c: &mut Build);
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use crate::{constant::ARCH_DIR_RISCV64, utils::FileUtils};
|
||||
|
||||
use super::CFilesArch;
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
pub(super) struct RiscV64CFilesArch;
|
||||
|
||||
@ -12,18 +9,8 @@ impl CFilesArch for RiscV64CFilesArch {
|
||||
c.define("__riscv", None);
|
||||
}
|
||||
|
||||
fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
|
||||
include_dirs.insert("src/arch/riscv64/include".into());
|
||||
}
|
||||
|
||||
fn setup_files(&self, _c: &mut cc::Build, files: &mut HashSet<PathBuf>) {
|
||||
files.insert(PathBuf::from("src/arch/riscv64/asm/head.S"));
|
||||
|
||||
FileUtils::list_all_files(&arch_path("asm"), Some("c"), true)
|
||||
.into_iter()
|
||||
.for_each(|f| {
|
||||
files.insert(f);
|
||||
});
|
||||
}
|
||||
|
||||
fn setup_global_flags(&self, c: &mut cc::Build) {
|
||||
@ -37,7 +24,3 @@ impl CFilesArch for RiscV64CFilesArch {
|
||||
c.flag("-march=rv64gc");
|
||||
}
|
||||
}
|
||||
|
||||
fn arch_path(relative_path: &str) -> PathBuf {
|
||||
PathBuf::from(format!("{}/{}", ARCH_DIR_RISCV64, relative_path))
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use cc::Build;
|
||||
|
||||
use crate::{constant::ARCH_DIR_X86_64, utils::FileUtils};
|
||||
|
||||
use super::CFilesArch;
|
||||
use cc::Build;
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
pub(super) struct X86_64CFilesArch;
|
||||
|
||||
@ -13,20 +9,7 @@ impl CFilesArch for X86_64CFilesArch {
|
||||
c.define("__x86_64__", None);
|
||||
}
|
||||
|
||||
fn setup_global_include_dir(&self, include_dirs: &mut HashSet<PathBuf>) {
|
||||
include_dirs.insert("src/arch/x86_64/include".into());
|
||||
}
|
||||
|
||||
fn setup_files(&self, _c: &mut Build, files: &mut HashSet<PathBuf>) {
|
||||
const DIRS: [&str; 4] = ["driver/apic", "init", "asm", "interrupt"];
|
||||
DIRS.iter().for_each(|dir| {
|
||||
FileUtils::list_all_files(&arch_path(dir), Some("c"), true)
|
||||
.into_iter()
|
||||
.for_each(|f| {
|
||||
files.insert(f);
|
||||
});
|
||||
});
|
||||
|
||||
// setup asm files
|
||||
files.insert(PathBuf::from("src/arch/x86_64/asm/head.S"));
|
||||
files.insert(PathBuf::from("src/arch/x86_64/asm/entry.S"));
|
||||
@ -39,7 +22,3 @@ impl CFilesArch for X86_64CFilesArch {
|
||||
c.flag("-mcmodel=large").flag("-m64");
|
||||
}
|
||||
}
|
||||
|
||||
fn arch_path(relative_path: &str) -> PathBuf {
|
||||
PathBuf::from(format!("{}/{}", ARCH_DIR_X86_64, relative_path))
|
||||
}
|
||||
|
@ -1,20 +1,7 @@
|
||||
use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use crate::utils::FileUtils;
|
||||
|
||||
pub(super) fn setup_common_files(files: &mut HashSet<PathBuf>) {
|
||||
const DIRS: [&str; 3] = ["src/common", "src/debug/traceback", "src/libs"];
|
||||
DIRS.iter().for_each(|dir| {
|
||||
FileUtils::list_all_files(&dir.into(), Some("c"), true)
|
||||
.into_iter()
|
||||
.for_each(|f| {
|
||||
files.insert(f);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn setup_common_include_dir(include_dirs: &mut HashSet<PathBuf>) {
|
||||
const DIRS: [&str; 3] = ["src/include", "src/common", "src"];
|
||||
const DIRS: [&str; 2] = ["src/common", "src"];
|
||||
DIRS.iter().for_each(|dir| {
|
||||
include_dirs.insert(dir.into());
|
||||
});
|
||||
|
@ -53,8 +53,6 @@ impl CFilesBuilder {
|
||||
|
||||
common::setup_common_include_dir(&mut include_dirs);
|
||||
|
||||
current_cfiles_arch().setup_global_include_dir(&mut include_dirs);
|
||||
|
||||
let include_dirs: Vec<PathBuf> = include_dirs.into_iter().collect();
|
||||
Self::set_rerun_if_files_changed(&include_dirs);
|
||||
|
||||
@ -67,7 +65,6 @@ impl CFilesBuilder {
|
||||
fn setup_files(c: &mut Build) {
|
||||
let mut files: HashSet<PathBuf> = HashSet::new();
|
||||
current_cfiles_arch().setup_files(c, &mut files);
|
||||
common::setup_common_files(&mut files);
|
||||
// 去重
|
||||
let files: Vec<PathBuf> = files.into_iter().collect();
|
||||
Self::set_rerun_if_files_changed(&files);
|
||||
|
@ -1,2 +0,0 @@
|
||||
pub const ARCH_DIR_X86_64: &str = "src/arch/x86_64";
|
||||
pub const ARCH_DIR_RISCV64: &str = "src/arch/riscv64";
|
@ -2,9 +2,7 @@
|
||||
extern crate lazy_static;
|
||||
extern crate cc;
|
||||
|
||||
mod bindgen;
|
||||
mod cfiles;
|
||||
mod constant;
|
||||
mod kconfig;
|
||||
mod utils;
|
||||
|
||||
@ -12,7 +10,6 @@ mod utils;
|
||||
pub fn run() {
|
||||
println!("cargo:rustc-link-search=src");
|
||||
|
||||
crate::bindgen::generate_bindings();
|
||||
crate::cfiles::CFilesBuilder::build();
|
||||
crate::kconfig::KConfigBuilder::build();
|
||||
}
|
||||
|
@ -1,49 +1 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub mod cargo_handler;
|
||||
|
||||
pub struct FileUtils;
|
||||
|
||||
impl FileUtils {
|
||||
/// 列出指定目录下的所有文件
|
||||
///
|
||||
/// ## 参数
|
||||
///
|
||||
/// - `path` - 指定的目录
|
||||
/// - `ext_name` - 文件的扩展名,如果为None,则列出所有文件
|
||||
/// - `recursive` - 是否递归列出所有文件
|
||||
pub fn list_all_files(path: &PathBuf, ext_name: Option<&str>, recursive: bool) -> Vec<PathBuf> {
|
||||
let mut queue: Vec<PathBuf> = Vec::new();
|
||||
let mut result = Vec::new();
|
||||
queue.push(path.clone());
|
||||
|
||||
while !queue.is_empty() {
|
||||
let path = queue.pop().unwrap();
|
||||
let d = std::fs::read_dir(path);
|
||||
if d.is_err() {
|
||||
continue;
|
||||
}
|
||||
let d = d.unwrap();
|
||||
|
||||
d.for_each(|ent| {
|
||||
if let Ok(ent) = ent {
|
||||
if let Ok(file_type) = ent.file_type() {
|
||||
if file_type.is_file() {
|
||||
if let Some(e) = ext_name {
|
||||
if let Some(ext) = ent.path().extension() {
|
||||
if ext == e {
|
||||
result.push(ent.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if file_type.is_dir() && recursive {
|
||||
queue.push(ent.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user