Llvm-symbolizer is broken for kernel modules

In ChromeOS, we have kernel modules elf files ending with “.ko”. I tried to use llvm-symbolizer to symbolize kernel module addresses and i think its broken.

As you already must know, kernel modules elf are different than executable ELFs. The kernel modules have instruction addresses relative to the sections. So each section starts with 0x0. Example:

$  llvm-objdump -d iwl7000_mac80211.ko.debug;

Givens following output:

Disassembly of section .text:

0000000000000000 <ieee80211_configure_filter>:
       0: e8 00 00 00 00                callq   0x5 <ieee80211_configure_filter+0x5>
       5: 55                            pushq   %rbp
       ...
       ...
       ...

Disassembly of section .init.text:

0000000000000000 <init_module>:
       0: e8 00 00 00 00                callq   0x5 <init_module+0x5>
       5: 55                            pushq   %rbp
       ....
       ....

Notice that each section’s first symbol is starting at 0x0.

So when i run

llvm-symbolizer --obj=iwl7000_mac80211.ko.debug 0x5

There is no way for the llvm-symbolizer to know which section is the 0x5 referring to.

addr2line tool have a -j (section) parameter to solve this issue.

Can someone please confirm is my understanding is correct?
How can we use llvm-symbolizer to symbolize kernel modules?

.ko files are just relocatable object files.

% cat a.c
void f() {}
void g() {}
void h() {}
% clang -c -ffunction-sections a.c
% readelf -Ws a.o | grep 'Value\|FUNC'
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     5: 0000000000000000     6 FUNC    GLOBAL DEFAULT    3 f
     6: 0000000000000000     6 FUNC    GLOBAL DEFAULT    4 g
     7: 0000000000000000     6 FUNC    GLOBAL DEFAULT    5 h

f, g, and h have the same st_value. There is simply not sufficient information for llvm-symbolizer to deduce the symbol name with just the address information (really for the linked unit, but is not available in relocatable object files). There is nothing llvm-symbolizer can do about it.

2 Likes

Okay Thank you for confirming my observation.

The GNU Binutils’s addr2line has a parameter named “–section”, which helps in remove the ambiguity.