[v2] Place ENTRY_POINT in .text.unlikely section [BZ #28153]
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
dj/TryBot-32bit |
success
|
Build for i686
|
Commit Message
Glibc assumes that ENTRY_POINT is the lowest address for which we need
to keep profiling records and BFD linker uses a linker script to place
the input sections.
Since GCC 4.6, the main function is placed in .text.startup section and
since binutils 2.22, BFD linker with
commit add44f8d5c5c05e08b11e033127a744d61c26aee
Author: Alan Modra <amodra@gmail.com>
Date: Thu Nov 25 03:03:02 2010 +0000
* scripttempl/elf.sc: Group .text.exit, text.startup and .text.hot
sections.
places .text.startup section before .text section.
Because ENTRY_POINT in gcrt1.o, which is passed to the linker first, is
placed in .text section, linker may place the main function below
ENTRY_POINT, which leaves the main function out of profiling records.
Place ENTRY_POINT in .text.unlikely section so that when GNU binutils
2.20 or newer with
commit 4c4fb5dac57a7cc4704fffb1f2fc11634dccc833
Author: Alan Modra <amodra@gmail.com>
Date: Fri Sep 4 06:35:29 2009 +0000
* scripttempl/elf.sc (.text): Add cold text sections.
is used, BFD linker places ENTRY_POINT at the lowest address. This
fixes [BZ #28153].
Tested on Linux/x86-64, Linux/x32 and Linux/i686 as well as with
build-many-glibcs.py.
---
gmon/tst-gmon-gprof.sh | 2 ++
gmon/tst-gmon-static-gprof.sh | 2 ++
sysdeps/aarch64/start.S | 2 +-
sysdeps/alpha/start.S | 2 +-
sysdeps/arc/start.S | 1 +
sysdeps/arm/start.S | 2 +-
sysdeps/csky/abiv2/start.S | 2 +-
sysdeps/hppa/start.S | 2 +-
sysdeps/i386/start.S | 1 +
sysdeps/ia64/start.S | 1 +
sysdeps/m68k/start.S | 2 +-
sysdeps/microblaze/start.S | 2 +-
sysdeps/mips/start.S | 2 +-
sysdeps/nios2/start.S | 2 +-
sysdeps/powerpc/powerpc32/start.S | 2 +-
sysdeps/powerpc/powerpc64/start.S | 2 +-
sysdeps/riscv/start.S | 1 +
sysdeps/s390/s390-32/start.S | 2 +-
sysdeps/s390/s390-64/start.S | 2 +-
sysdeps/sh/start.S | 2 +-
sysdeps/sparc/sparc32/start.S | 2 +-
sysdeps/sparc/sparc64/start.S | 2 +-
sysdeps/x86_64/start.S | 1 +
23 files changed, 25 insertions(+), 16 deletions(-)
Comments
* H. J. Lu via Libc-alpha:
> diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
> index 417da8802b..e46e01ed0b 100644
> --- a/sysdeps/aarch64/start.S
> +++ b/sysdeps/aarch64/start.S
> @@ -42,7 +42,7 @@
> NULL
> */
>
> - .text
> + .section .text.unlikely,"ax",%progbits
> ENTRY(_start)
> /* Create an initial frame with 0 LR and FP */
> cfi_undefined (x30)
I don't think it's correct to place code that runs during every process
start into .text.unlikely. Surely we can avoid that page fault.
Can we fix the ENTRY_POINT assumption in profiling instead?
Thanks,
Florian
On Sat, Jul 31, 2021 at 9:36 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu via Libc-alpha:
>
> > diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
> > index 417da8802b..e46e01ed0b 100644
> > --- a/sysdeps/aarch64/start.S
> > +++ b/sysdeps/aarch64/start.S
> > @@ -42,7 +42,7 @@
> > NULL
> > */
> >
> > - .text
> > + .section .text.unlikely,"ax",%progbits
> > ENTRY(_start)
> > /* Create an initial frame with 0 LR and FP */
> > cfi_undefined (x30)
>
> I don't think it's correct to place code that runs during every process
> start into .text.unlikely. Surely we can avoid that page fault.
>
> Can we fix the ENTRY_POINT assumption in profiling instead?
We can do
diff --git a/csu/gmon-start.c b/csu/gmon-start.c
index b3432885b3..83322fd586 100644
--- a/csu/gmon-start.c
+++ b/csu/gmon-start.c
@@ -48,7 +48,7 @@
#ifdef ENTRY_POINT_DECL
ENTRY_POINT_DECL(extern)
#else
-extern char ENTRY_POINT[];
+extern char entry_point[] asm (__SYMBOL_PREFIX "main");
#endif
extern char etext[];
@@ -56,7 +56,7 @@ extern char etext[];
# ifdef ENTRY_POINT_DECL
# define TEXT_START ENTRY_POINT
# else
-# define TEXT_START &ENTRY_POINT
+# define TEXT_START &entry_point
# endif
#endif
But this may only work with BFD linker which places .text.startup
section before .text section.
On Sat, Jul 31, 2021 at 10:06 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Sat, Jul 31, 2021 at 9:36 AM Florian Weimer <fweimer@redhat.com> wrote:
> >
> > * H. J. Lu via Libc-alpha:
> >
> > > diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
> > > index 417da8802b..e46e01ed0b 100644
> > > --- a/sysdeps/aarch64/start.S
> > > +++ b/sysdeps/aarch64/start.S
> > > @@ -42,7 +42,7 @@
> > > NULL
> > > */
> > >
> > > - .text
> > > + .section .text.unlikely,"ax",%progbits
> > > ENTRY(_start)
> > > /* Create an initial frame with 0 LR and FP */
> > > cfi_undefined (x30)
> >
> > I don't think it's correct to place code that runs during every process
> > start into .text.unlikely. Surely we can avoid that page fault.
> >
> > Can we fix the ENTRY_POINT assumption in profiling instead?
>
> We can do
>
> diff --git a/csu/gmon-start.c b/csu/gmon-start.c
> index b3432885b3..83322fd586 100644
> --- a/csu/gmon-start.c
> +++ b/csu/gmon-start.c
> @@ -48,7 +48,7 @@
> #ifdef ENTRY_POINT_DECL
> ENTRY_POINT_DECL(extern)
> #else
> -extern char ENTRY_POINT[];
> +extern char entry_point[] asm (__SYMBOL_PREFIX "main");
> #endif
> extern char etext[];
>
> @@ -56,7 +56,7 @@ extern char etext[];
> # ifdef ENTRY_POINT_DECL
> # define TEXT_START ENTRY_POINT
> # else
> -# define TEXT_START &ENTRY_POINT
> +# define TEXT_START &entry_point
> # endif
> #endif
>
> But this may only work with BFD linker which places .text.startup
> section before .text section.
Another option is to place _start in .text.startup which leaves
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
sections out of profiling records.
* H. J. Lu:
> On Sat, Jul 31, 2021 at 9:36 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu via Libc-alpha:
>>
>> > diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
>> > index 417da8802b..e46e01ed0b 100644
>> > --- a/sysdeps/aarch64/start.S
>> > +++ b/sysdeps/aarch64/start.S
>> > @@ -42,7 +42,7 @@
>> > NULL
>> > */
>> >
>> > - .text
>> > + .section .text.unlikely,"ax",%progbits
>> > ENTRY(_start)
>> > /* Create an initial frame with 0 LR and FP */
>> > cfi_undefined (x30)
>>
>> I don't think it's correct to place code that runs during every process
>> start into .text.unlikely. Surely we can avoid that page fault.
>>
>> Can we fix the ENTRY_POINT assumption in profiling instead?
>
> We can do
>
> diff --git a/csu/gmon-start.c b/csu/gmon-start.c
> index b3432885b3..83322fd586 100644
> --- a/csu/gmon-start.c
> +++ b/csu/gmon-start.c
> @@ -48,7 +48,7 @@
> #ifdef ENTRY_POINT_DECL
> ENTRY_POINT_DECL(extern)
> #else
> -extern char ENTRY_POINT[];
> +extern char entry_point[] asm (__SYMBOL_PREFIX "main");
> #endif
> extern char etext[];
>
> @@ -56,7 +56,7 @@ extern char etext[];
> # ifdef ENTRY_POINT_DECL
> # define TEXT_START ENTRY_POINT
> # else
> -# define TEXT_START &ENTRY_POINT
> +# define TEXT_START &entry_point
> # endif
> #endif
>
> But this may only work with BFD linker which places .text.startup
> section before .text section.
Can we get the linker to emit a symbol at the start of the text section?
Like it does for orphan sections?
Then we can use a weak symbol reference in gmon-start.c and use the new
symbol if it is available.
Thanks,
Florian
On Jul 31 2021, Florian Weimer via Libc-alpha wrote:
> Can we get the linker to emit a symbol at the start of the text section?
There is __executable_start at the start of the text segment.
Andreas.
On Sat, Jul 31, 2021 at 10:11 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > On Sat, Jul 31, 2021 at 9:36 AM Florian Weimer <fweimer@redhat.com> wrote:
> >>
> >> * H. J. Lu via Libc-alpha:
> >>
> >> > diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
> >> > index 417da8802b..e46e01ed0b 100644
> >> > --- a/sysdeps/aarch64/start.S
> >> > +++ b/sysdeps/aarch64/start.S
> >> > @@ -42,7 +42,7 @@
> >> > NULL
> >> > */
> >> >
> >> > - .text
> >> > + .section .text.unlikely,"ax",%progbits
> >> > ENTRY(_start)
> >> > /* Create an initial frame with 0 LR and FP */
> >> > cfi_undefined (x30)
> >>
> >> I don't think it's correct to place code that runs during every process
> >> start into .text.unlikely. Surely we can avoid that page fault.
> >>
> >> Can we fix the ENTRY_POINT assumption in profiling instead?
> >
> > We can do
> >
> > diff --git a/csu/gmon-start.c b/csu/gmon-start.c
> > index b3432885b3..83322fd586 100644
> > --- a/csu/gmon-start.c
> > +++ b/csu/gmon-start.c
> > @@ -48,7 +48,7 @@
> > #ifdef ENTRY_POINT_DECL
> > ENTRY_POINT_DECL(extern)
> > #else
> > -extern char ENTRY_POINT[];
> > +extern char entry_point[] asm (__SYMBOL_PREFIX "main");
> > #endif
> > extern char etext[];
> >
> > @@ -56,7 +56,7 @@ extern char etext[];
> > # ifdef ENTRY_POINT_DECL
> > # define TEXT_START ENTRY_POINT
> > # else
> > -# define TEXT_START &ENTRY_POINT
> > +# define TEXT_START &entry_point
> > # endif
> > #endif
> >
> > But this may only work with BFD linker which places .text.startup
> > section before .text section.
>
> Can we get the linker to emit a symbol at the start of the text section?
We already have __executable_start which is pretty close to what we
need. Like this.
> Like it does for orphan sections?
>
> Then we can use a weak symbol reference in gmon-start.c and use the new
> symbol if it is available.
>
> Thanks,
> Florian
>
@@ -39,12 +39,14 @@ trap cleanup 0
cat > "$expected" <<EOF
f1 2000
f2 1000
+f3 1
EOF
# Special version for powerpc with function descriptors.
cat > "$expected_dot" <<EOF
.f1 2000
.f2 1000
+.f3 1
EOF
"$GPROF" -C "$program" "$data" \
@@ -39,6 +39,7 @@ trap cleanup 0
cat > "$expected" <<EOF
f1 2000
f2 1000
+f3 1
main 1
EOF
@@ -46,6 +47,7 @@ EOF
cat > "$expected_dot" <<EOF
.f1 2000
.f2 1000
+.f3 1
.main 1
EOF
@@ -42,7 +42,7 @@
NULL
*/
- .text
+ .section .text.unlikely,"ax",%progbits
ENTRY(_start)
/* Create an initial frame with 0 LR and FP */
cfi_undefined (x30)
@@ -36,7 +36,7 @@
#include <sysdep.h>
- .text
+ .section .text.unlikely,"ax",%progbits
.align 3
.globl _start
.ent _start, 0
@@ -33,6 +33,7 @@
env[0...N] environment variables (pointers)
NULL. */
+ .section .text.unlikely,"ax",%progbits
ENTRY (ENTRY_POINT)
/* Needed to make gdb backtraces stop here. */
@@ -69,7 +69,7 @@
.syntax unified
#endif
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,#function
_start:
@@ -41,7 +41,7 @@
#include <sysdep.h>
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start;
.type _start,@function;
.align 4;
@@ -51,7 +51,7 @@
.Lp__libc_start_main:
.word P%__libc_start_main
- .text
+ .section .text.unlikely,"ax",%progbits
.align 4
.globl _start
.export _start, ENTRY
@@ -54,6 +54,7 @@
#include <sysdep.h>
+ .section .text.unlikely,"ax",%progbits
ENTRY (_start)
/* Clearing frame pointer is insufficient, use CFI. */
cfi_undefined (eip)
@@ -48,6 +48,7 @@
* out6: stack_end
*/
+ .section .text.unlikely,"ax",%progbits
.align 32
.global _start
@@ -54,7 +54,7 @@
#include <sysdep.h>
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,@function
_start:
@@ -33,7 +33,7 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,@function
_start:
@@ -71,7 +71,7 @@
void (*rtld_fini) (void), void *stack_end)
*/
- .text
+ .section .text.unlikely,"ax",%progbits
.globl ENTRY_POINT
.type ENTRY_POINT,@function
#ifndef __mips16
@@ -65,7 +65,7 @@
value, terminated by an AT_NULL tag.
*/
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,%function
_start:
@@ -56,7 +56,7 @@ L(start_addresses):
.long 0 /* Used to be fini. */
ASM_SIZE_DIRECTIVE(L(start_addresses))
- .section ".text"
+ .section .text.unlikely,"ax",%progbits
ENTRY(_start)
/* Save the stack pointer, in case we're statically linked under Linux. */
mr r9,r1
@@ -61,7 +61,7 @@ L(start_addresses):
.section ".toc","aw"
.L01:
.tc L(start_addresses)[TC],L(start_addresses)
- .section ".text"
+ .section .text.unlikely,"ax",%progbits
ENTRY (_start)
/* Save the stack pointer, in case we're statically linked under Linux. */
mr r9,r1
@@ -42,6 +42,7 @@
a0 contains the address of a function to be passed to atexit.
__libc_start_main wants this in a5. */
+ .section .text.unlikely,"ax",%progbits
ENTRY (ENTRY_POINT)
/* Terminate call stack by noting ra is undefined. Use a dummy
.cfi_label to force starting the FDE. */
@@ -55,7 +55,7 @@
NULL
*/
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,@function
_start:
@@ -55,7 +55,7 @@
NULL
*/
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,@function
_start:
@@ -57,7 +57,7 @@
NULL
*/
- .text
+ .section .text.unlikely,"ax",%progbits
.globl _start
.type _start,@function
_start:
@@ -37,7 +37,7 @@
#include <sysdep.h>
- .section ".text"
+ .section .text.unlikely,"ax",%progbits
.align 4
.global _start
.type _start,#function
@@ -37,7 +37,7 @@
#include <sysdep.h>
- .section ".text"
+ .section .text.unlikely,"ax",%progbits
.align 4
.global _start
.type _start,#function
@@ -55,6 +55,7 @@
#include <sysdep.h>
+ .section .text.unlikely,"ax",%progbits
ENTRY (_start)
/* Clearing frame pointer is insufficient, use CFI. */
cfi_undefined (rip)