Bug 17213 - Fail to generate gprof's gmon.out on powerpc64le
Summary: Fail to generate gprof's gmon.out on powerpc64le
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.20
: P2 normal
Target Milestone: ---
Assignee: Adhemerval Zanella Netto
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-29 18:55 UTC by Adhemerval Zanella Netto
Modified: 2014-07-30 12:03 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adhemerval Zanella Netto 2014-07-29 18:55:02 UTC
A  impler test case:

$ cat simple.c 
int
main (void)
{
  return 0;
}
$ gcc -pg simple.c

Fails to run on a powerpc64le:

$ ./a.out 
monstartup: out of memory

Using gdb, the call to __monstartup is clearly bogus:

(gdb) bt
#0  0x00003fffb7ef3b28 in __monstartup (lowpc=4053955791311343618, highpc=268437740) at gmon.c:104
#1  0x00000000100004f8 in __gmon_start__ () at gmon-start.c:87
#2  0x0000000010000400 in _init () at ../sysdeps/powerpc/powerpc64/crti.S:77
#3  0x0000000010000768 in __libc_csu_init (argc=<optimized out>, argv=<optimized out>, 
    envp=<optimized out>) at elf-init.c:83
#4  0x00003fffb7df4d0c in generic_start_main (main=0x100006c4 <main>, argc=<optimized out>, 
    argv=0x3ffffffffa08, auxvec=0x3ffffffffae8, init=0x10000710 <__libc_csu_init>, 
    rtld_fini=<optimized out>, stack_end=<optimized out>, fini=<optimized out>)
    at ../csu/libc-start.c:244
#5  0x00003fffb7df4f74 in __libc_start_main (argc=<optimized out>, argv=<optimized out>, 
    ev=<optimized out>, auxvec=<optimized out>, rtld_fini=<optimized out>, stinfo=<optimized out>, 
    stack_on_entry=<optimized out>) at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:80
#6  0x0000000000000000 in ?? ()

The value of lowpc is clearly the problem.  This is from the source csu/gmon-start.c:__gmon_start():

      /* Start keeping profiling records.  */
      __monstartup ((u_long) TEXT_START, (u_long) &etext);

TEXT_START in defined in ./sysdeps/powerpc/powerpc64/entry.h:

/* Use the address of ._start as the lowest address for which we need
   to keep profiling records.  We can't copy the ia64 scheme as our
   entry poiny address is really the address of the function
   descriptor, not the actual function entry.  */
#define TEXT_START \
  ({ extern unsigned long int _start_as_data[] asm ("_start");  \
     _start_as_data[0]; })

This seems wrong for ELFv2, since _start is not a function descriptor. A straightforward patch is use the default defines:

diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
index b1d4b7f..2843912 100644
--- a/sysdeps/powerpc/powerpc64/entry.h
+++ b/sysdeps/powerpc/powerpc64/entry.h
@@ -23,6 +23,7 @@ extern void _start (void);
 
 #define ENTRY_POINT _start
 
+#if _CALL_ELF != 2
 /* We have to provide a special declaration.  */
 #define ENTRY_POINT_DECL(class) class void _start (void);
 
@@ -33,3 +34,4 @@ extern void _start (void);
 #define TEXT_START \
   ({ extern unsigned long int _start_as_data[] asm ("_start");  \
      _start_as_data[0]; })
+#endif
Comment 1 Adhemerval Zanella Netto 2014-07-30 12:03:20 UTC
Fixed upstream by a53fbd8e6cd2f69bdfa3431d616a5f332aea6664.