Skip to content
  • Vincent Whitchurch's avatar
    ARM: module: Fix function kallsyms on Thumb-2 · 93d77e7f
    Vincent Whitchurch authored
    
    
    Thumb-2 functions have the lowest bit set in the symbol value in the
    symtab.  When kallsyms are generated for the vmlinux, the kallsyms are
    generated from the output of nm, and nm clears the lowest bit.
    
     $ arm-linux-gnueabihf-readelf -a vmlinux | grep show_interrupts
      95947: 8015dc89   686 FUNC    GLOBAL DEFAULT    2 show_interrupts
     $ arm-linux-gnueabihf-nm vmlinux | grep show_interrupts
     8015dc88 T show_interrupts
     $ cat /proc/kallsyms | grep show_interrupts
     8015dc88 T show_interrupts
    
    However, for modules, the kallsyms uses the values in the symbol table
    without modification, so for functions in modules, the lowest bit is set
    in kallsyms.
    
     $ arm-linux-gnueabihf-readelf -a drivers/net/tun.ko | grep tun_get_socket
        333: 00002d4d    36 FUNC    GLOBAL DEFAULT    1 tun_get_socket
     $ arm-linux-gnueabihf-nm drivers/net/tun.ko | grep tun_get_socket
     00002d4c T tun_get_socket
     $ cat /proc/kallsyms | grep tun_get_socket
     7f802d4d t tun_get_socket      [tun]
    
    Because of this, the symbol+offset of the crashing instruction shown in
    oopses is incorrect when the crash is in a module.  For example, given a
    tun_get_socket which starts like this,
    
     00002d4c <tun_get_socket>:
         2d4c:       6943            ldr     r3, [r0, #20]
         2d4e:       4a07            ldr     r2, [pc, #28]
         2d50:       4293            cmp     r3, r2
    
    a crash when tun_get_socket is called with NULL results in:
    
     PC is at tun_xdp+0xa3/0xa4 [tun]
     pc : [<7f802d4c>]
    
    As can be seen, the "PC is at" line reports the wrong symbol name, and
    the symbol+offset will point to the wrong source line if it is passed to
    gdb.
    
    To solve this, add a way for archs to fixup the reading of these module
    kallsyms values, and use that to clear the lowest bit for function
    symbols on Thumb-2.
    
    After the fix:
    
     # cat /proc/kallsyms | grep tun_get_socket
     7f802d4c t tun_get_socket       [tun]
    
     PC is at tun_get_socket+0x0/0x24 [tun]
     pc : [<7f802d4c>]
    
    Signed-off-by: default avatarVincent Whitchurch <vincent.whitchurch@axis.com>
    Signed-off-by: default avatarJessica Yu <jeyu@kernel.org>
    93d77e7f