[Crash-utility] [RFC] arm64: symbolize PLT entries in disassembling module functions

Dave Anderson anderson at redhat.com
Tue Oct 11 17:54:19 UTC 2016


Takahiro,

Nice!  Queued for crash-7.1.6:
 
  https://github.com/crash-utility/crash/commit/f08a9c8bceadcbd15a21b5dc314aa84353a26547

Thanks,
  Dave

  
----- Original Message -----
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
>  arm64.c | 69
>  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 69 insertions(+)
> 
> diff --git a/arm64.c b/arm64.c
> index b9fa14d..8235e3c 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -2540,6 +2540,59 @@ arm64_is_task_addr(ulong task)
>  		return (IS_KVADDR(task) && (ALIGNED_STACK_OFFSET(task) == 0));
>  }
>  
> +static ulong
> +PLT_veneer_to_kvaddr(ulong value)
> +{
> +	uint32_t insn;
> +	ulong addr = 0;
> +	int i;
> +
> +	/*
> +	 * PLT veneer always looks:
> +         *   movn x16, #0x....
> +         *   movk x16, #0x...., lsl #16
> +         *   movk x16, #0x...., lsl #32
> +         *   br   x16
> +	 */
> +	for (i = 0; i < 4; i++) {
> +		if (!readmem(value + i * sizeof(insn), KVADDR, &insn,
> +				sizeof(insn), "PLT veneer", RETURN_ON_ERROR)) {
> +			error(WARNING, "cannot read PLT veneer\n");
> +			return value;
> +		}
> +		switch (i) {
> +		case 0:
> +			if ((insn & 0xffe0001f) != 0x92800010)
> +				goto not_plt;
> +			addr = ~((ulong)(insn & 0x1fffe0) >> 5);
> +			break;
> +		case 1:
> +			if ((insn & 0xffe0001f) != 0xf2a00010)
> +				goto not_plt;
> +			addr &= 0xffffffff0000ffff;
> +			addr |= (ulong)(insn & 0x1fffe0) << (16 - 5);
> +			break;
> +		case 2:
> +			if ((insn & 0xffe0001f) != 0xf2c00010)
> +				goto not_plt;
> +			addr &= 0xffff0000ffffffff;
> +			addr |= (ulong)(insn & 0x1fffe0) << (32 - 5);
> +			break;
> +		case 3:
> +			if (insn != 0xd61f0200)
> +				goto not_plt;
> +			break;
> +		default:
> +			return value; /* to avoid any warnings */
> +		}
> +	}
> +
> +	return addr;
> +
> +not_plt:
> +	return value;
> +}
> +
>  /*
>   * Filter dissassembly output if the output radix is not gdb's default 10
>   */
> @@ -2589,6 +2642,22 @@ arm64_dis_filter(ulong vaddr, char *inbuf, unsigned
> int output_radix)
>  		sprintf(p1, "%s", buf1);
>  	}
>  
> +	if (IS_MODULE_VADDR(vaddr)) {
> +		ulong orig_value;
> +
> +		p1 = &inbuf[strlen(inbuf)-1];
> +		strcpy(buf1, inbuf);
> +		argc = parse_line(buf1, argv);
> +
> +		if ((STREQ(argv[argc-2], "b") || STREQ(argv[argc-2], "bl")) &&
> +		    extract_hex(argv[argc-1], &orig_value, NULLCHAR, TRUE)) {
> +			value = PLT_veneer_to_kvaddr(orig_value);
> +			sprintf(p1, " <%s%s>\n",
> +				value == orig_value ? "" : "plt:",
> +				value_to_symstr(value, buf2, output_radix));
> +		}
> +	}
> +
>  	console("    %s", inbuf);
>  
>  	return TRUE;
> --
> 2.10.0




More information about the Crash-utility mailing list