main.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. use std::str;
  2. #[derive(Debug, Clone)]
  3. struct KernelSymbolEntry {
  4. vaddr: u64,
  5. #[allow(dead_code)]
  6. symbol_type: char,
  7. symbol: String,
  8. symbol_length: usize,
  9. }
  10. fn symbol_to_write(vaddr: u64, text_vaddr: u64, etext_vaddr: u64) -> bool {
  11. vaddr >= text_vaddr && vaddr <= etext_vaddr
  12. }
  13. fn read_symbol(line: &str) -> Option<KernelSymbolEntry> {
  14. if line.len() > 512 {
  15. return None;
  16. } // skip line with length >= 512
  17. let mut parts = line.split_whitespace();
  18. let vaddr = u64::from_str_radix(parts.next()?, 16).ok()?;
  19. let symbol_type = parts.next()?.chars().next()?;
  20. let symbol = parts.collect::<Vec<_>>().join(" ");
  21. if symbol_type != 'T' && symbol_type != 't' {
  22. return None;
  23. } // local symbol or global symbol in text section
  24. if symbol == "$x" {
  25. return None;
  26. } // skip $x symbol
  27. let symbol_length = symbol.len() + 1; // +1 for null terminator
  28. Some(KernelSymbolEntry {
  29. vaddr,
  30. symbol_type,
  31. symbol,
  32. symbol_length,
  33. })
  34. }
  35. fn read_map() -> (Vec<KernelSymbolEntry>, u64, u64) {
  36. let mut symbol_table = Vec::new();
  37. let mut text_vaddr = 0;
  38. let mut etext_vaddr = 0;
  39. let mut line = String::new();
  40. loop {
  41. let size = std::io::stdin().read_line(&mut line).unwrap();
  42. if size == 0 {
  43. break;
  44. }
  45. line = line.trim().to_string();
  46. if let Some(entry) = read_symbol(&line) {
  47. if entry.symbol.starts_with("_text") {
  48. text_vaddr = entry.vaddr;
  49. } else if entry.symbol.starts_with("_etext") {
  50. etext_vaddr = entry.vaddr;
  51. }
  52. symbol_table.push(entry);
  53. }
  54. line.clear();
  55. }
  56. (symbol_table, text_vaddr, etext_vaddr)
  57. }
  58. fn generate_result(symbol_table: &[KernelSymbolEntry], text_vaddr: u64, etext_vaddr: u64) {
  59. println!(".section .rodata\n");
  60. println!(".global kallsyms_address");
  61. println!(".align 8\n");
  62. println!("kallsyms_address:");
  63. let mut last_vaddr = 0;
  64. let mut total_syms_to_write = 0;
  65. for entry in symbol_table {
  66. if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
  67. continue;
  68. }
  69. println!("\t.quad\t{:#x}", entry.vaddr);
  70. total_syms_to_write += 1;
  71. last_vaddr = entry.vaddr;
  72. }
  73. println!("\n.global kallsyms_num");
  74. println!(".align 8");
  75. println!("kallsyms_num:");
  76. println!("\t.quad\t{}", total_syms_to_write);
  77. println!("\n.global kallsyms_names_index");
  78. println!(".align 8");
  79. println!("kallsyms_names_index:");
  80. let mut position = 0;
  81. last_vaddr = 0;
  82. for entry in symbol_table {
  83. if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
  84. continue;
  85. }
  86. println!("\t.quad\t{}", position);
  87. position += entry.symbol_length;
  88. last_vaddr = entry.vaddr;
  89. }
  90. println!("\n.global kallsyms_names");
  91. println!(".align 8");
  92. println!("kallsyms_names:");
  93. last_vaddr = 0;
  94. for entry in symbol_table {
  95. if !symbol_to_write(entry.vaddr, text_vaddr, etext_vaddr) || entry.vaddr == last_vaddr {
  96. continue;
  97. }
  98. println!("\t.asciz\t\"{}\"", entry.symbol);
  99. last_vaddr = entry.vaddr;
  100. }
  101. }
  102. fn main() {
  103. let (symbol_table, text_vaddr, etext_vaddr) = read_map();
  104. generate_result(&symbol_table, text_vaddr, etext_vaddr);
  105. }