93dc2d
commit 84a7eb1f87c1d01b58ad887a0ab5d87abbc1c772
93dc2d
Author: H.J. Lu <hjl.tools@gmail.com>
93dc2d
Date:   Fri Jul 30 19:07:30 2021 -0700
93dc2d
93dc2d
    Use __executable_start as the lowest address for profiling [BZ #28153]
93dc2d
    
93dc2d
    Glibc assumes that ENTRY_POINT is the lowest address for which we need
93dc2d
    to keep profiling records and BFD linker uses a linker script to place
93dc2d
    the input sections.
93dc2d
    
93dc2d
    Starting from GCC 4.6, the main function is placed in .text.startup
93dc2d
    section and starting from binutils 2.22, BFD linker with
93dc2d
    
93dc2d
    commit add44f8d5c5c05e08b11e033127a744d61c26aee
93dc2d
    Author: Alan Modra <amodra@gmail.com>
93dc2d
    Date:   Thu Nov 25 03:03:02 2010 +0000
93dc2d
    
93dc2d
                * scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot
93dc2d
                sections.
93dc2d
    
93dc2d
    places .text.startup section before .text section, which leave the main
93dc2d
    function out of profiling records.
93dc2d
    
93dc2d
    Starting from binutils 2.15, linker provides __executable_start to mark
93dc2d
    the lowest address of the executable.  Use __executable_start as the
93dc2d
    lowest address to keep the main function in profiling records. This fixes
93dc2d
    [BZ #28153].
93dc2d
    
93dc2d
    Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with
93dc2d
    build-many-glibcs.py.
93dc2d
93dc2d
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
93dc2d
index b3432885b39071cc..344606a676c188d4 100644
93dc2d
--- a/csu/gmon-start.c
93dc2d
+++ b/csu/gmon-start.c
93dc2d
@@ -52,6 +52,11 @@ extern char ENTRY_POINT[];
93dc2d
 #endif
93dc2d
 extern char etext[];
93dc2d
 
93dc2d
+/* Use __executable_start as the lowest address to keep profiling records
93dc2d
+   if it provided by the linker.  */
93dc2d
+extern const char executable_start[] asm ("__executable_start")
93dc2d
+  __attribute__ ((weak, visibility ("hidden")));
93dc2d
+
93dc2d
 #ifndef TEXT_START
93dc2d
 # ifdef ENTRY_POINT_DECL
93dc2d
 #  define TEXT_START ENTRY_POINT
93dc2d
@@ -92,7 +97,10 @@ __gmon_start__ (void)
93dc2d
   called = 1;
93dc2d
 
93dc2d
   /* Start keeping profiling records.  */
93dc2d
-  __monstartup ((u_long) TEXT_START, (u_long) &etext);
93dc2d
+  if (&executable_start != NULL)
93dc2d
+    __monstartup ((u_long) &executable_start, (u_long) &etext);
93dc2d
+  else
93dc2d
+    __monstartup ((u_long) TEXT_START, (u_long) &etext);
93dc2d
 
93dc2d
   /* Call _mcleanup before exiting; it will write out gmon.out from the
93dc2d
      collected data.  */
93dc2d
diff --git a/gmon/tst-gmon-gprof.sh b/gmon/tst-gmon-gprof.sh
93dc2d
index 9d371582b99677fa..dc0be021104f725d 100644
93dc2d
--- a/gmon/tst-gmon-gprof.sh
93dc2d
+++ b/gmon/tst-gmon-gprof.sh
93dc2d
@@ -39,12 +39,14 @@ trap cleanup 0
93dc2d
 cat > "$expected" <
93dc2d
 f1 2000
93dc2d
 f2 1000
93dc2d
+f3 1
93dc2d
 EOF
93dc2d
 
93dc2d
 # Special version for powerpc with function descriptors.
93dc2d
 cat > "$expected_dot" <
93dc2d
 .f1 2000
93dc2d
 .f2 1000
93dc2d
+.f3 1
93dc2d
 EOF
93dc2d
 
93dc2d
 "$GPROF" -C "$program" "$data" \
93dc2d
diff --git a/gmon/tst-gmon-static-gprof.sh b/gmon/tst-gmon-static-gprof.sh
93dc2d
index 79218df967f9387f..4cc99c80d0115271 100644
93dc2d
--- a/gmon/tst-gmon-static-gprof.sh
93dc2d
+++ b/gmon/tst-gmon-static-gprof.sh
93dc2d
@@ -39,6 +39,7 @@ trap cleanup 0
93dc2d
 cat > "$expected" <
93dc2d
 f1 2000
93dc2d
 f2 1000
93dc2d
+f3 1
93dc2d
 main 1
93dc2d
 EOF
93dc2d
 
93dc2d
@@ -46,6 +47,7 @@ EOF
93dc2d
 cat > "$expected_dot" <
93dc2d
 .f1 2000
93dc2d
 .f2 1000
93dc2d
+.f3 1
93dc2d
 .main 1
93dc2d
 EOF
93dc2d