GNU Binutils with patches for OS216
修订版 | cd55085b07e03aba28cc5a5358852efb1beb1a15 (tree) |
---|---|
时间 | 2020-06-26 01:23:38 |
作者 | Luis Machado <luis.machado@lina...> |
Commiter | Luis Machado |
AArch64: Report tag violation error information
Whenever a memory tag violation occurs, we get a SIGSEGV. Additional
information can be obtained through the siginfo data structure.
For AArch64 the Linux kernel may expose the fault address and tag
information, if we have a synchronous event. Otherwise there is
not fault address available.
gdb/ChangeLog:
YYYY-MM-DD Luis Machado <luis.machado@linaro.org>
* aarch64-linux-tdep.c
(aarch64_linux_handle_segmentation_fault): New function.
(aarch64_linux_init_abi): Register
aarch64_linux_handle_segmentation_fault as segmentation fault hook.
* arch/aarch64-linux.h (SEGV_MTEAERR): Define.
(SEGV_MTESERR): Define.
@@ -1644,6 +1644,57 @@ aarch64_linux_memtag_to_string (struct gdbarch *gdbarch, | ||
1644 | 1644 | return string_printf ("0x%s", phex_nz (tag, sizeof (tag))); |
1645 | 1645 | } |
1646 | 1646 | |
1647 | +/* AArch64 Linux implementation of the handle_segmentation_fault gdbarch | |
1648 | + hook. Displays information about possible memory tag violations. */ | |
1649 | + | |
1650 | +static void | |
1651 | +aarch64_linux_handle_segmentation_fault (struct gdbarch *gdbarch, | |
1652 | + struct ui_out *uiout) | |
1653 | +{ | |
1654 | + CORE_ADDR fault_addr = 0; | |
1655 | + long si_code = 0; | |
1656 | + CORE_ADDR ltag; | |
1657 | + CORE_ADDR atag; | |
1658 | + | |
1659 | + try | |
1660 | + { | |
1661 | + /* Sigcode tells us if the segfault is actually a memory tag | |
1662 | + violation. */ | |
1663 | + si_code = parse_and_eval_long ("$_siginfo.si_code\n"); | |
1664 | + | |
1665 | + fault_addr | |
1666 | + = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); | |
1667 | + } | |
1668 | + catch (const gdb_exception &exception) | |
1669 | + { | |
1670 | + return; | |
1671 | + } | |
1672 | + | |
1673 | + /* If this is not a memory tag violation, just return. */ | |
1674 | + if (si_code != SEGV_MTEAERR && si_code != SEGV_MTESERR) | |
1675 | + return; | |
1676 | + | |
1677 | + uiout->text ("\n"); | |
1678 | + | |
1679 | + uiout->field_string ("sigcode-meaning", _("Memory tag violation")); | |
1680 | + uiout->text (_(" while accessing address ")); | |
1681 | + uiout->field_core_addr ("fault-addr", gdbarch, fault_addr); | |
1682 | + uiout->text ("\n"); | |
1683 | + | |
1684 | + uiout->text (_("Logical tag ")); | |
1685 | + ltag = aarch64_linux_get_ltag (fault_addr); | |
1686 | + uiout->field_core_addr ("logical-tag", gdbarch, ltag); | |
1687 | + uiout->text ("\n"); | |
1688 | + | |
1689 | + if (aarch64_linux_get_atag (fault_addr, &atag) != 0) | |
1690 | + uiout->text (_("Allocation tag unavailable")); | |
1691 | + else | |
1692 | + { | |
1693 | + uiout->text (_("Allocation tag ")); | |
1694 | + uiout->field_core_addr ("allocation-tag", gdbarch, atag); | |
1695 | + } | |
1696 | +} | |
1697 | + | |
1647 | 1698 | static void |
1648 | 1699 | aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) |
1649 | 1700 | { |
@@ -1724,6 +1775,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | ||
1724 | 1775 | |
1725 | 1776 | /* Register a hook for converting a memory tag to a string. */ |
1726 | 1777 | set_gdbarch_memtag_to_string (gdbarch, aarch64_linux_memtag_to_string); |
1778 | + | |
1779 | + set_gdbarch_handle_segmentation_fault (gdbarch, | |
1780 | + aarch64_linux_handle_segmentation_fault); | |
1727 | 1781 | } |
1728 | 1782 | |
1729 | 1783 | /* Initialize the aarch64_linux_record_tdep. */ |
@@ -35,6 +35,12 @@ | ||
35 | 35 | #define MTE_LOGICAL_TAG_START_BIT 56 |
36 | 36 | #define MTE_LOGICAL_MAX_VALUE 0xf |
37 | 37 | |
38 | +/* Memory tagging definitions. */ | |
39 | +#ifndef SEGV_MTEAERR | |
40 | +# define SEGV_MTEAERR 8 | |
41 | +# define SEGV_MTESERR 9 | |
42 | +#endif | |
43 | + | |
38 | 44 | /* Return the number of tag granules in the memory range |
39 | 45 | [ADDR, ADDR + LEN) given GRANULE_SIZE. */ |
40 | 46 | extern int get_tag_granules (CORE_ADDR addr, size_t len, |