git: c1ccbc7f518e - stable/13 - libpmcstat: Fix a few ARM-specific issues with function symbols.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Wed, 11 May 2022 20:46:56 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=c1ccbc7f518e4e3c54ea4acd2d217c0ce5f6a13c

commit c1ccbc7f518e4e3c54ea4acd2d217c0ce5f6a13c
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-03-10 23:39:53 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2022-05-11 18:57:17 +0000

    libpmcstat: Fix a few ARM-specific issues with function symbols.
    
    - Refine the checks for ARM mapping symbols and apply them on arm64 as
      well as 32-bit arm.  In particular, mapping symbols can have
      additional characters and are not strictly limited to just "$a" but
      can append additional characters (e.g. "$a.1").  Add "$x" to the
      list of mapping symbol prefixes.
    
    - Clear the LSB of function symbol addresses.  Thumb function
      addresses set the LSB to enable Thumb mode.  However, the actual
      function starts at the aligned address with LSB clear.  Not clearing
      the LSB can cause pmcannotate to pass misaligned addresses to
      objdump when extracting disassembly.
    
    Reviewed by:    andrew
    Obtained from:  CheriBSD
    Sponsored by:   University of Cambridge, Google, Inc.
    Differential Revision:  https://reviews.freebsd.org/D34416
    
    (cherry picked from commit a6db407f15ab7d0dbfd83a48173343654106510e)
---
 lib/libpmcstat/libpmcstat_image.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/lib/libpmcstat/libpmcstat_image.c b/lib/libpmcstat/libpmcstat_image.c
index 9ee7097e95ec..7e021666aa58 100644
--- a/lib/libpmcstat/libpmcstat_image.c
+++ b/lib/libpmcstat/libpmcstat_image.c
@@ -118,13 +118,23 @@ pmcstat_image_add_symbols(struct pmcstat_image *image, Elf *e,
 		if ((fnname = elf_strptr(e, sh->sh_link, sym.st_name))
 		    == NULL)
 			continue;
-#ifdef __arm__
-		/* Remove spurious ARM function name. */
+
+#if defined(__aarch64__) || defined(__arm__)
+		/* Ignore ARM mapping symbols. */
 		if (fnname[0] == '$' &&
 		    (fnname[1] == 'a' || fnname[1] == 't' ||
-		    fnname[1] == 'd') &&
-		    fnname[2] == '\0')
+		    fnname[1] == 'd' || fnname[1] == 'x'))
 			continue;
+
+		/*
+		 * Clear LSB from starting addresses for functions
+		 * which execute in Thumb mode.  We should perhaps
+		 * only do this for functions in a $t mapping symbol
+		 * range, but parsing mapping symbols would be a lot
+		 * of work and function addresses shouldn't have the
+		 * LSB set otherwise.
+		 */
+		sym.st_value &= ~1;
 #endif
 
 		symptr->ps_name  = pmcstat_string_intern(fnname);