[Crash-utility] [PATCH] arm64: exclude mapping symbols in modules

AKASHI Takahiro takahiro.akashi at linaro.org
Fri Oct 7 08:03:20 UTC 2016


Dave,

On Thu, Oct 06, 2016 at 04:35:42PM -0400, Dave Anderson wrote:
> 
> Hi Akashi,
> 
> I was playing around with this, and noted that if a module's debuginfo data is not
> loaded into a crash session with the "mod" command, branch instruction targets 
> that are within the module space are not translated.  For example, note the handful
> of "bl" instructions with module address targets are empty:
>   
>   crash> dis dm_create | grep bl
>   0xfffffdfffc003814 <dm_create+60>:	bl	0xfffffe0000226ce0 <kmem_cache_alloc_trace>
>   0xfffffdfffc003828 <dm_create+80>:	bl	0xfffffe0000143754 <try_module_get>
>   0xfffffdfffc003850 <dm_create+120>:	bl	0xfffffe00003c4f08 <idr_preload>
>   0xfffffdfffc00385c <dm_create+132>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003874 <dm_create+156>:	bl	0xfffffe00003c5d90 <idr_alloc>
>   0xfffffdfffc00388c <dm_create+180>:	bl	0xfffffe0000123044 <init_srcu_struct>
>   0xfffffdfffc0038b0 <dm_create+216>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc0038c0 <dm_create+232>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc0038d4 <dm_create+252>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc003918 <dm_create+320>:	bl	0xfffffe00003968c4 <blk_alloc_queue>
>   0xfffffdfffc003948 <dm_create+368>:	bl	0xfffffe00003ab298 <alloc_disk>
>   0xfffffdfffc003968 <dm_create+400>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc003994 <dm_create+444>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc0039a8 <dm_create+464>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc0039f8 <dm_create+544>:	bl	0xfffffe00003d1224 <sprintf>
>   0xfffffdfffc003a00 <dm_create+552>:	bl	0xfffffe00003aab08 <add_disk>
>   0xfffffdfffc003a1c <dm_create+580>:	bl	0xfffffe00003d1224 <sprintf>
>   0xfffffdfffc003a34 <dm_create+604>:	bl	0xfffffe00000e3acc <__alloc_workqueue_key>
>   0xfffffdfffc003a48 <dm_create+624>:	bl	0xfffffe00003a9a8c <bdget_disk>
>   0xfffffdfffc003a58 <dm_create+640>:	bl	0xfffffe000038ea84 <bio_init>
>   0xfffffdfffc003a70 <dm_create+664>:	bl	0xfffffdfffc00e418
>   0xfffffdfffc003a78 <dm_create+672>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003a88 <dm_create+688>:	bl	0xfffffe00003c4e54 <idr_replace>
>   0xfffffdfffc003aa4 <dm_create+716>:	bl	0xfffffdfffc00d270
>   0xfffffdfffc003ad8 <dm_create+768>:	bl	0xfffffe0000143860 <module_put>
>   0xfffffdfffc003ae0 <dm_create+776>:	bl	0xfffffe0000228464 <kfree>
>   0xfffffdfffc003b08 <dm_create+816>:	bl	0xfffffe00003c4f08 <idr_preload>
>   0xfffffdfffc003b14 <dm_create+828>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003b2c <dm_create+852>:	bl	0xfffffe00003c5d90 <idr_alloc>
>   0xfffffdfffc003b4c <dm_create+884>:	bl	0xfffffdfffc001220
>   0xfffffdfffc003b54 <dm_create+892>:	bl	0xfffffdfffc0012e0
>   0xfffffdfffc003b60 <dm_create+904>:	bl	0xfffffe00001c4828 <printk>
>   crash> 
>   
> With this patch: 
> 
>   --- a/arm64.c
>   +++ b/arm64.c
>   @@ -2977,6 +2977,16 @@ arm64_dis_filter(ulong vaddr, char *inbuf, unsigned int output_radix)
>                   sprintf(p1, "%s", buf1);
>           }
>    
>   +       if (IS_MODULE_VADDR(vaddr)) {
>   +               p1 = &inbuf[strlen(inbuf)-1];
>   +               strcpy(buf1, inbuf);
>   +               argc = parse_line(buf1, argv);
>   +               if (STREQ(argv[argc-2], "bl") &&
>   +                   extract_hex(argv[argc-1], &value, NULLCHAR, TRUE))
>   +                       sprintf(p1, " <%s>\n",
>   +                               value_to_symstr(value, buf2, output_radix));
>   +       }
>   +
>           console("    %s", inbuf);
>    
>           return TRUE;
> 
> module addresses are translated without having to load the module's debuginfo:
> 
>   crash> dis dm_create | grep bl
>   0xfffffdfffc003814 <dm_create+60>:	bl	0xfffffe0000226ce0 <kmem_cache_alloc_trace>
>   0xfffffdfffc003828 <dm_create+80>:	bl	0xfffffe0000143754 <try_module_get>
>   0xfffffdfffc003850 <dm_create+120>:	bl	0xfffffe00003c4f08 <idr_preload>
>   0xfffffdfffc00385c <dm_create+132>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003874 <dm_create+156>:	bl	0xfffffe00003c5d90 <idr_alloc>
>   0xfffffdfffc00388c <dm_create+180>:	bl	0xfffffe0000123044 <init_srcu_struct>
>   0xfffffdfffc0038b0 <dm_create+216>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc0038c0 <dm_create+232>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc0038d4 <dm_create+252>:	bl	0xfffffe000010f9d0 <__mutex_init>
>   0xfffffdfffc003918 <dm_create+320>:	bl	0xfffffe00003968c4 <blk_alloc_queue>
>   0xfffffdfffc003948 <dm_create+368>:	bl	0xfffffe00003ab298 <alloc_disk>
>   0xfffffdfffc003968 <dm_create+400>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc003994 <dm_create+444>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc0039a8 <dm_create+464>:	bl	0xfffffe000010a878 <__init_waitqueue_head>
>   0xfffffdfffc0039f8 <dm_create+544>:	bl	0xfffffe00003d1224 <sprintf>
>   0xfffffdfffc003a00 <dm_create+552>:	bl	0xfffffe00003aab08 <add_disk>
>   0xfffffdfffc003a1c <dm_create+580>:	bl	0xfffffe00003d1224 <sprintf>
>   0xfffffdfffc003a34 <dm_create+604>:	bl	0xfffffe00000e3acc <__alloc_workqueue_key>
>   0xfffffdfffc003a48 <dm_create+624>:	bl	0xfffffe00003a9a8c <bdget_disk>
>   0xfffffdfffc003a58 <dm_create+640>:	bl	0xfffffe000038ea84 <bio_init>
>   0xfffffdfffc003a70 <dm_create+664>:	bl	0xfffffdfffc00e418 <dm_stats_init>
>   0xfffffdfffc003a78 <dm_create+672>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003a88 <dm_create+688>:	bl	0xfffffe00003c4e54 <idr_replace>
>   0xfffffdfffc003aa4 <dm_create+716>:	bl	0xfffffdfffc00d270 <dm_sysfs_init>
>   0xfffffdfffc003ad8 <dm_create+768>:	bl	0xfffffe0000143860 <module_put>
>   0xfffffdfffc003ae0 <dm_create+776>:	bl	0xfffffe0000228464 <kfree>
>   0xfffffdfffc003b08 <dm_create+816>:	bl	0xfffffe00003c4f08 <idr_preload>
>   0xfffffdfffc003b14 <dm_create+828>:	bl	0xfffffe000078241c <_raw_spin_lock>
>   0xfffffdfffc003b2c <dm_create+852>:	bl	0xfffffe00003c5d90 <idr_alloc>
>   0xfffffdfffc003b4c <dm_create+884>:	bl	0xfffffdfffc001220 <cleanup_mapped_device>
>   0xfffffdfffc003b54 <dm_create+892>:	bl	0xfffffdfffc0012e0 <free_minor>
>   0xfffffdfffc003b60 <dm_create+904>:	bl	0xfffffe00001c4828 <printk>
>   crash> 
> 
> Now, this sample patch doesn't deal with branch instructions other than "bl",
> so perhaps it could just check whether the last argument in the instruction
> line is a translatable address.  
> 
> On the other hand, for the PLT veneer issue, it would have to:
> 
>  (1) make sure it's a "bl", and

and other variants of "bl"

>  (2) instead of blindly doing a translation of the PLT veneer label address,
>      it would first have to check whether it points to a 12-byte chunk of 
>      kernel address construction, and if so, translate the reconstructed 
>      address.

Actually, a veneer always consists of 4 instructions:
    mov  x16, #imm16
    movk x16, #imm16, lsl #16
    movk x16, #imm16, lsl #32
    br   x16

It would be safe to identify any veneers with this type of sequence,
but I'm wondering if there is any other trick of directly checking
if the label address is fit in PLT section of a module.
(On arm64, this section is dynamically allocated on module loading,
and so it's not trivial.)

>  
> So I'm thinking something along these lines, say, where "value" may or may not be
> modified by your new function:
> 
>        if (IS_MODULE_VADDR(vaddr)) {
>                p1 = &inbuf[strlen(inbuf)-1];
>                strcpy(buf1, inbuf);
>                argc = parse_line(buf1, argv);
>                if (STREQ(argv[argc-2], "bl") &&
>                    extract_hex(argv[argc-1], &value, NULLCHAR, TRUE)) {
> +                      value = PLT_veneer_to_kvaddr(value);
>                        sprintf(p1, " <%s>\n",
>                                value_to_symstr(value, buf2, output_radix));
> 	       }
>        }

Looks nice.

> However, another thing to consider is what "dis" shows if the "mod" command
> has already loaded the debuginfo data.  In that case, I'm guessing that gdb
> would translate the address of the PLT veneer location?

Give that the output from "bt" command shows "testmod_init" which is
a module_init function of my sample module, I assume that the debug
data have already been loaded in my case.

> The sample KASLR
> vmcore you gave me doesn't have any modules, so I don't know. 

I can give you my sample vmcore.
Please tell me a location where I can push the iamge.

Thanks,
-Takahiro AKASHI

> Dave
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility




More information about the Crash-utility mailing list