@@ -1862,6 +1862,71 @@ fn symbolize_kernel_bpf_program() {
18621862 } )
18631863}
18641864
1865+ /// Test symbolization of a kernel module address using DWARF debug
1866+ /// information from a `.ko` file.
1867+ ///
1868+ /// This exercises the full kernel module symbolization path: loading a
1869+ /// module, finding its symbols via `/proc/kallsyms`, and resolving an
1870+ /// address through the DWARF data embedded in the `.ko` file on disk.
1871+ ///
1872+ /// The kernel module must already be installed and loaded before this
1873+ /// test runs (see `main.sh` for the setup).
1874+ #[ test]
1875+ #[ ignore = "test requires VM environment (vmtest)" ]
1876+ fn symbolize_kernel_module_dwarf ( ) {
1877+ // Find a text function belonging to the test_hexdump module in
1878+ // /proc/kallsyms.
1879+ let kallsyms = read_file ( "/proc/kallsyms" ) . unwrap ( ) ;
1880+ let kallsyms = str:: from_utf8 ( & kallsyms) . unwrap ( ) ;
1881+ let ( addr, name) = kallsyms
1882+ . lines ( )
1883+ . find_map ( |line| {
1884+ let mut parts = line. split_ascii_whitespace ( ) ;
1885+ let addr = parts. next ( ) ?;
1886+ let ty = parts. next ( ) ?;
1887+ let name = parts. next ( ) ?;
1888+ let module = parts. next ( ) ?;
1889+
1890+ if module != "[test_hexdump]" || !matches ! ( ty, "t" | "T" ) {
1891+ return None ;
1892+ }
1893+ let addr = Addr :: from_str_radix ( addr, 16 ) . ok ( ) ?;
1894+ ( addr != 0 ) . then ( || ( addr, name. to_string ( ) ) )
1895+ } )
1896+ . expect ( "no text function found for [test_hexdump] in /proc/kallsyms" ) ;
1897+
1898+ // Symbolize the address using the default Kernel source, which
1899+ // consults /proc/modules, depmod, and the .ko file's DWARF data.
1900+ let src = Source :: Kernel ( Kernel :: default ( ) ) ;
1901+ let symbolizer = Symbolizer :: new ( ) ;
1902+ let symbolized = symbolizer
1903+ . symbolize_single ( & src, Input :: AbsAddr ( addr) )
1904+ . unwrap ( ) ;
1905+ let sym = symbolized
1906+ . into_sym ( )
1907+ . unwrap_or_else ( || panic ! ( "failed to symbolize `{name}` at {addr:#x}" ) ) ;
1908+
1909+ // The DWARF resolver should report source code information that is
1910+ // only present in the .ko's debug sections.
1911+ let code_info = sym. code_info . as_ref ( ) . unwrap_or_else ( || {
1912+ panic ! (
1913+ "no source code info for `{name}` at {addr:#x} (resolved as `{}`); \
1914+ DWARF data was not used",
1915+ sym. name,
1916+ )
1917+ } ) ;
1918+ assert_eq ! (
1919+ code_info. file,
1920+ OsStr :: new( "test_hexdump.c" ) ,
1921+ "unexpected source file: {:?}" ,
1922+ code_info. file,
1923+ ) ;
1924+ assert ! (
1925+ code_info. line. is_some( ) ,
1926+ "expected a line number in source info" ,
1927+ ) ;
1928+ }
1929+
18651930/// Symbolize a normalized address from a binary with an artificially
18661931/// inflated ELF segment.
18671932///
0 commit comments