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