2012-09-10 20:50:19 +04:00
# include <unistd.h>
# include <stdio.h>
# include <string.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <stdlib.h>
# include <linux/kernel.h>
# include "vdso.h"
# include "util.h"
# include "symbol.h"
2014-07-22 17:17:53 +04:00
# include "machine.h"
2014-10-23 14:45:23 +04:00
# include "thread.h"
2012-09-10 20:50:19 +04:00
# include "linux/string.h"
2014-07-15 01:46:48 +04:00
# include "debug.h"
2012-09-10 20:50:19 +04:00
2014-10-24 01:16:03 +04:00
/*
* Include definition of find_vdso_map ( ) also used in perf - read - vdso . c for
* building perf - read - vdso32 and perf - read - vdsox32 .
*/
# include "find-vdso-map.c"
2014-07-22 17:17:54 +04:00
# define VDSO__TEMP_FILE_NAME " / tmp / perf-vdso.so-XXXXXX"
struct vdso_file {
bool found ;
bool error ;
char temp_file_name [ sizeof ( VDSO__TEMP_FILE_NAME ) ] ;
const char * dso_name ;
2014-10-23 14:45:23 +04:00
const char * read_prog ;
2014-07-22 17:17:54 +04:00
} ;
struct vdso_info {
struct vdso_file vdso ;
2014-10-23 14:45:23 +04:00
# if BITS_PER_LONG == 64
struct vdso_file vdso32 ;
struct vdso_file vdsox32 ;
# endif
2014-07-22 17:17:54 +04:00
} ;
2014-07-23 15:23:00 +04:00
static struct vdso_info * vdso_info__new ( void )
{
static const struct vdso_info vdso_info_init = {
. vdso = {
. temp_file_name = VDSO__TEMP_FILE_NAME ,
2014-07-22 17:17:57 +04:00
. dso_name = DSO__NAME_VDSO ,
2014-07-23 15:23:00 +04:00
} ,
2014-10-23 14:45:23 +04:00
# if BITS_PER_LONG == 64
. vdso32 = {
. temp_file_name = VDSO__TEMP_FILE_NAME ,
. dso_name = DSO__NAME_VDSO32 ,
. read_prog = " perf-read-vdso32 " ,
} ,
. vdsox32 = {
. temp_file_name = VDSO__TEMP_FILE_NAME ,
. dso_name = DSO__NAME_VDSOX32 ,
. read_prog = " perf-read-vdsox32 " ,
} ,
# endif
2014-07-23 15:23:00 +04:00
} ;
return memdup ( & vdso_info_init , sizeof ( vdso_info_init ) ) ;
}
2012-09-10 20:50:19 +04:00
2014-07-22 17:17:54 +04:00
static char * get_file ( struct vdso_file * vdso_file )
2012-09-10 20:50:19 +04:00
{
char * vdso = NULL ;
char * buf = NULL ;
void * start , * end ;
size_t size ;
int fd ;
2014-07-22 17:17:54 +04:00
if ( vdso_file - > found )
return vdso_file - > temp_file_name ;
2012-09-10 20:50:19 +04:00
2014-07-22 17:17:54 +04:00
if ( vdso_file - > error | | find_vdso_map ( & start , & end ) )
2012-09-10 20:50:19 +04:00
return NULL ;
size = end - start ;
buf = memdup ( start , size ) ;
if ( ! buf )
return NULL ;
2014-07-22 17:17:54 +04:00
fd = mkstemp ( vdso_file - > temp_file_name ) ;
2012-09-10 20:50:19 +04:00
if ( fd < 0 )
goto out ;
if ( size = = ( size_t ) write ( fd , buf , size ) )
2014-07-22 17:17:54 +04:00
vdso = vdso_file - > temp_file_name ;
2012-09-10 20:50:19 +04:00
close ( fd ) ;
out :
free ( buf ) ;
2014-07-22 17:17:54 +04:00
vdso_file - > found = ( vdso ! = NULL ) ;
vdso_file - > error = ! vdso_file - > found ;
2012-09-10 20:50:19 +04:00
return vdso ;
}
perf machine: Fix up vdso methods names
To make it consistent with the other dso lifetime routines.
For instance:
struct dso *vdso__new(struct machine *machine, const char *short_name,
const char *long_name)
Becomes:
struct dso *machine__addnew_vdso(struct machine *machine, const
char *short_name, const char *long_name)
Because:
1) There is no 'struct vdso' for us to have vdso__ prefixed routines.
2) Because it will not really just create a new instance of 'struct
dso', it'll call dso__new() but it will also insert it into the
DSO's list/rbtree, and we have a method name for that: 'addnew',
just like we have dsos__addnew().
3) So it is really a 'struct machine' operation, it is the first
argument, etc.
This way the place where this is used gets consistent:
if (vdso) {
pgoff = 0;
- dso = vdso__dso_findnew(machine, thread);
+ dso = machine__findnew_vdso(machine, thread);
} else
dso = machine__findnew_dso(machine, filename);
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-r3w3tvh8exm9xfz3p4tz9qbz@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-05-29 17:54:08 +03:00
void machine__exit_vdso ( struct machine * machine )
2012-09-10 20:50:19 +04:00
{
2014-07-23 15:23:00 +04:00
struct vdso_info * vdso_info = machine - > vdso_info ;
if ( ! vdso_info )
return ;
2014-07-22 17:17:54 +04:00
if ( vdso_info - > vdso . found )
unlink ( vdso_info - > vdso . temp_file_name ) ;
2014-10-23 14:45:23 +04:00
# if BITS_PER_LONG == 64
if ( vdso_info - > vdso32 . found )
unlink ( vdso_info - > vdso32 . temp_file_name ) ;
if ( vdso_info - > vdsox32 . found )
unlink ( vdso_info - > vdsox32 . temp_file_name ) ;
# endif
2014-07-23 15:23:00 +04:00
zfree ( & machine - > vdso_info ) ;
2012-09-10 20:50:19 +04:00
}
2015-06-01 21:40:01 +03:00
static struct dso * __machine__addnew_vdso ( struct machine * machine , const char * short_name ,
const char * long_name )
2014-07-22 17:17:56 +04:00
{
struct dso * dso ;
dso = dso__new ( short_name ) ;
if ( dso ! = NULL ) {
2015-06-01 21:40:01 +03:00
__dsos__add ( & machine - > dsos , dso ) ;
2014-07-22 17:17:56 +04:00
dso__set_long_name ( dso , long_name , false ) ;
}
return dso ;
}
2014-10-23 14:45:23 +04:00
static enum dso_type machine__thread_dso_type ( struct machine * machine ,
struct thread * thread )
{
enum dso_type dso_type = DSO__TYPE_UNKNOWN ;
struct map * map ;
struct dso * dso ;
map = map_groups__first ( thread - > mg , MAP__FUNCTION ) ;
for ( ; map ; map = map_groups__next ( map ) ) {
dso = map - > dso ;
if ( ! dso | | dso - > long_name [ 0 ] ! = ' / ' )
continue ;
dso_type = dso__type ( dso , machine ) ;
if ( dso_type ! = DSO__TYPE_UNKNOWN )
break ;
}
return dso_type ;
}
perf tools: Find right DSO taking into account if binary is 32 or 64-bit
There's a problem in machine__findnew_vdso(), vdso buildid generated by a
32-bit machine stores it with the name 'vdso', but when processing buildid on a
64-bit machine with the same 'perf.data', perf will search for vdso named as
'vdso32' and get failed.
This patch tries to find the existing dsos in machine->dsos by thread dso_type.
64-bit thread tries to find vdso with name 'vdso', because all 64-bit vdso is
named as that. 32-bit thread first tries to find vdso with name 'vdso32' if
this thread was run on 64-bit machine, if failed, then it tries 'vdso' which
indicates that the thread was run on 32-bit machine when recording.
Committer note:
Additional explanation by Adrian Hunter:
We match maps to builds ids using the file name - consider
machine__findnew_[v]dso() called in map__new(). So in the context of a perf
data file, we consider the file name to be unique.
A vdso map does not have a file name - all we know is that it is vdso. We look
at the thread to tell if it is 32-bit, 64-bit or x32. Then we need to get the
build id which has been recorded using short name "[vdso]" or "[vdso32]" or
"[vdsox32]".
The problem is that on a 32-bit machine, we use the name "[vdso]". If you take
a 32-bit perf data file to a 64-bit machine, it gets hard to figure out if
"[vdso]" is 32-bit or 64-bit.
This patch solves that problem.
----
This also merges a followup patch fixing a problem introduced by the
original submission of this patch, that would crash 'perf record' when
recording samples for a 32-bit app on a 64-bit system.
Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1463475894-163531-1-git-send-email-hekuang@huawei.com
Link: http://lkml.kernel.org/r/1466578626-92406-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-17 12:04:54 +03:00
# if BITS_PER_LONG == 64
2014-10-23 14:45:23 +04:00
static int vdso__do_copy_compat ( FILE * f , int fd )
{
char buf [ 4096 ] ;
size_t count ;
while ( 1 ) {
count = fread ( buf , 1 , sizeof ( buf ) , f ) ;
if ( ferror ( f ) )
return - errno ;
if ( feof ( f ) )
break ;
if ( count & & writen ( fd , buf , count ) ! = ( ssize_t ) count )
return - errno ;
}
return 0 ;
}
static int vdso__copy_compat ( const char * prog , int fd )
{
FILE * f ;
int err ;
f = popen ( prog , " r " ) ;
if ( ! f )
return - errno ;
err = vdso__do_copy_compat ( f , fd ) ;
if ( pclose ( f ) = = - 1 )
return - errno ;
return err ;
}
static int vdso__create_compat_file ( const char * prog , char * temp_name )
{
int fd , err ;
fd = mkstemp ( temp_name ) ;
if ( fd < 0 )
return - errno ;
err = vdso__copy_compat ( prog , fd ) ;
if ( close ( fd ) = = - 1 )
return - errno ;
return err ;
}
static const char * vdso__get_compat_file ( struct vdso_file * vdso_file )
{
int err ;
if ( vdso_file - > found )
return vdso_file - > temp_file_name ;
if ( vdso_file - > error )
return NULL ;
err = vdso__create_compat_file ( vdso_file - > read_prog ,
vdso_file - > temp_file_name ) ;
if ( err ) {
pr_err ( " %s failed, error %d \n " , vdso_file - > read_prog , err ) ;
vdso_file - > error = true ;
return NULL ;
}
vdso_file - > found = true ;
return vdso_file - > temp_file_name ;
}
2015-06-01 21:40:01 +03:00
static struct dso * __machine__findnew_compat ( struct machine * machine ,
struct vdso_file * vdso_file )
2014-10-23 14:45:23 +04:00
{
const char * file_name ;
struct dso * dso ;
2015-06-01 21:40:01 +03:00
dso = __dsos__find ( & machine - > dsos , vdso_file - > dso_name , true ) ;
2014-10-23 14:45:23 +04:00
if ( dso )
2015-07-07 14:13:38 +03:00
goto out ;
2014-10-23 14:45:23 +04:00
file_name = vdso__get_compat_file ( vdso_file ) ;
if ( ! file_name )
2015-07-07 14:13:38 +03:00
goto out ;
2014-10-23 14:45:23 +04:00
2015-06-01 21:40:01 +03:00
dso = __machine__addnew_vdso ( machine , vdso_file - > dso_name , file_name ) ;
2015-07-07 14:13:38 +03:00
out :
2015-06-01 21:40:01 +03:00
return dso ;
2014-10-23 14:45:23 +04:00
}
2015-06-01 21:40:01 +03:00
static int __machine__findnew_vdso_compat ( struct machine * machine ,
struct thread * thread ,
struct vdso_info * vdso_info ,
struct dso * * dso )
2014-10-23 14:45:23 +04:00
{
enum dso_type dso_type ;
dso_type = machine__thread_dso_type ( machine , thread ) ;
2014-10-23 14:45:24 +04:00
# ifndef HAVE_PERF_READ_VDSO32
if ( dso_type = = DSO__TYPE_32BIT )
return 0 ;
# endif
# ifndef HAVE_PERF_READ_VDSOX32
if ( dso_type = = DSO__TYPE_X32BIT )
return 0 ;
# endif
2014-10-23 14:45:23 +04:00
switch ( dso_type ) {
case DSO__TYPE_32BIT :
2015-06-01 21:40:01 +03:00
* dso = __machine__findnew_compat ( machine , & vdso_info - > vdso32 ) ;
2014-10-23 14:45:23 +04:00
return 1 ;
case DSO__TYPE_X32BIT :
2015-06-01 21:40:01 +03:00
* dso = __machine__findnew_compat ( machine , & vdso_info - > vdsox32 ) ;
2014-10-23 14:45:23 +04:00
return 1 ;
case DSO__TYPE_UNKNOWN :
case DSO__TYPE_64BIT :
default :
return 0 ;
}
}
# endif
perf tools: Find right DSO taking into account if binary is 32 or 64-bit
There's a problem in machine__findnew_vdso(), vdso buildid generated by a
32-bit machine stores it with the name 'vdso', but when processing buildid on a
64-bit machine with the same 'perf.data', perf will search for vdso named as
'vdso32' and get failed.
This patch tries to find the existing dsos in machine->dsos by thread dso_type.
64-bit thread tries to find vdso with name 'vdso', because all 64-bit vdso is
named as that. 32-bit thread first tries to find vdso with name 'vdso32' if
this thread was run on 64-bit machine, if failed, then it tries 'vdso' which
indicates that the thread was run on 32-bit machine when recording.
Committer note:
Additional explanation by Adrian Hunter:
We match maps to builds ids using the file name - consider
machine__findnew_[v]dso() called in map__new(). So in the context of a perf
data file, we consider the file name to be unique.
A vdso map does not have a file name - all we know is that it is vdso. We look
at the thread to tell if it is 32-bit, 64-bit or x32. Then we need to get the
build id which has been recorded using short name "[vdso]" or "[vdso32]" or
"[vdsox32]".
The problem is that on a 32-bit machine, we use the name "[vdso]". If you take
a 32-bit perf data file to a 64-bit machine, it gets hard to figure out if
"[vdso]" is 32-bit or 64-bit.
This patch solves that problem.
----
This also merges a followup patch fixing a problem introduced by the
original submission of this patch, that would crash 'perf record' when
recording samples for a 32-bit app on a 64-bit system.
Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1463475894-163531-1-git-send-email-hekuang@huawei.com
Link: http://lkml.kernel.org/r/1466578626-92406-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-17 12:04:54 +03:00
static struct dso * machine__find_vdso ( struct machine * machine ,
struct thread * thread )
{
struct dso * dso = NULL ;
enum dso_type dso_type ;
dso_type = machine__thread_dso_type ( machine , thread ) ;
switch ( dso_type ) {
case DSO__TYPE_32BIT :
dso = __dsos__find ( & machine - > dsos , DSO__NAME_VDSO32 , true ) ;
if ( ! dso ) {
dso = __dsos__find ( & machine - > dsos , DSO__NAME_VDSO ,
true ) ;
if ( dso & & dso_type ! = dso__type ( dso , machine ) )
dso = NULL ;
}
break ;
case DSO__TYPE_X32BIT :
dso = __dsos__find ( & machine - > dsos , DSO__NAME_VDSOX32 , true ) ;
break ;
case DSO__TYPE_64BIT :
case DSO__TYPE_UNKNOWN :
default :
dso = __dsos__find ( & machine - > dsos , DSO__NAME_VDSO , true ) ;
break ;
}
return dso ;
}
perf machine: Fix up vdso methods names
To make it consistent with the other dso lifetime routines.
For instance:
struct dso *vdso__new(struct machine *machine, const char *short_name,
const char *long_name)
Becomes:
struct dso *machine__addnew_vdso(struct machine *machine, const
char *short_name, const char *long_name)
Because:
1) There is no 'struct vdso' for us to have vdso__ prefixed routines.
2) Because it will not really just create a new instance of 'struct
dso', it'll call dso__new() but it will also insert it into the
DSO's list/rbtree, and we have a method name for that: 'addnew',
just like we have dsos__addnew().
3) So it is really a 'struct machine' operation, it is the first
argument, etc.
This way the place where this is used gets consistent:
if (vdso) {
pgoff = 0;
- dso = vdso__dso_findnew(machine, thread);
+ dso = machine__findnew_vdso(machine, thread);
} else
dso = machine__findnew_dso(machine, filename);
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/n/tip-r3w3tvh8exm9xfz3p4tz9qbz@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-05-29 17:54:08 +03:00
struct dso * machine__findnew_vdso ( struct machine * machine ,
perf tools: Find right DSO taking into account if binary is 32 or 64-bit
There's a problem in machine__findnew_vdso(), vdso buildid generated by a
32-bit machine stores it with the name 'vdso', but when processing buildid on a
64-bit machine with the same 'perf.data', perf will search for vdso named as
'vdso32' and get failed.
This patch tries to find the existing dsos in machine->dsos by thread dso_type.
64-bit thread tries to find vdso with name 'vdso', because all 64-bit vdso is
named as that. 32-bit thread first tries to find vdso with name 'vdso32' if
this thread was run on 64-bit machine, if failed, then it tries 'vdso' which
indicates that the thread was run on 32-bit machine when recording.
Committer note:
Additional explanation by Adrian Hunter:
We match maps to builds ids using the file name - consider
machine__findnew_[v]dso() called in map__new(). So in the context of a perf
data file, we consider the file name to be unique.
A vdso map does not have a file name - all we know is that it is vdso. We look
at the thread to tell if it is 32-bit, 64-bit or x32. Then we need to get the
build id which has been recorded using short name "[vdso]" or "[vdso32]" or
"[vdsox32]".
The problem is that on a 32-bit machine, we use the name "[vdso]". If you take
a 32-bit perf data file to a 64-bit machine, it gets hard to figure out if
"[vdso]" is 32-bit or 64-bit.
This patch solves that problem.
----
This also merges a followup patch fixing a problem introduced by the
original submission of this patch, that would crash 'perf record' when
recording samples for a 32-bit app on a 64-bit system.
Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1463475894-163531-1-git-send-email-hekuang@huawei.com
Link: http://lkml.kernel.org/r/1466578626-92406-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-17 12:04:54 +03:00
struct thread * thread )
2012-09-10 20:50:19 +04:00
{
2014-07-23 15:23:00 +04:00
struct vdso_info * vdso_info ;
2015-06-01 21:40:01 +03:00
struct dso * dso = NULL ;
2014-07-23 15:23:00 +04:00
2015-06-01 21:40:01 +03:00
pthread_rwlock_wrlock ( & machine - > dsos . lock ) ;
2014-07-23 15:23:00 +04:00
if ( ! machine - > vdso_info )
machine - > vdso_info = vdso_info__new ( ) ;
vdso_info = machine - > vdso_info ;
if ( ! vdso_info )
2015-06-01 21:40:01 +03:00
goto out_unlock ;
2012-09-10 20:50:19 +04:00
perf tools: Find right DSO taking into account if binary is 32 or 64-bit
There's a problem in machine__findnew_vdso(), vdso buildid generated by a
32-bit machine stores it with the name 'vdso', but when processing buildid on a
64-bit machine with the same 'perf.data', perf will search for vdso named as
'vdso32' and get failed.
This patch tries to find the existing dsos in machine->dsos by thread dso_type.
64-bit thread tries to find vdso with name 'vdso', because all 64-bit vdso is
named as that. 32-bit thread first tries to find vdso with name 'vdso32' if
this thread was run on 64-bit machine, if failed, then it tries 'vdso' which
indicates that the thread was run on 32-bit machine when recording.
Committer note:
Additional explanation by Adrian Hunter:
We match maps to builds ids using the file name - consider
machine__findnew_[v]dso() called in map__new(). So in the context of a perf
data file, we consider the file name to be unique.
A vdso map does not have a file name - all we know is that it is vdso. We look
at the thread to tell if it is 32-bit, 64-bit or x32. Then we need to get the
build id which has been recorded using short name "[vdso]" or "[vdso32]" or
"[vdsox32]".
The problem is that on a 32-bit machine, we use the name "[vdso]". If you take
a 32-bit perf data file to a 64-bit machine, it gets hard to figure out if
"[vdso]" is 32-bit or 64-bit.
This patch solves that problem.
----
This also merges a followup patch fixing a problem introduced by the
original submission of this patch, that would crash 'perf record' when
recording samples for a 32-bit app on a 64-bit system.
Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1463475894-163531-1-git-send-email-hekuang@huawei.com
Link: http://lkml.kernel.org/r/1466578626-92406-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-17 12:04:54 +03:00
dso = machine__find_vdso ( machine , thread ) ;
if ( dso )
goto out_unlock ;
2014-10-23 14:45:23 +04:00
# if BITS_PER_LONG == 64
2015-06-01 21:40:01 +03:00
if ( __machine__findnew_vdso_compat ( machine , thread , vdso_info , & dso ) )
goto out_unlock ;
2014-10-23 14:45:23 +04:00
# endif
2015-06-01 21:40:01 +03:00
dso = __dsos__find ( & machine - > dsos , DSO__NAME_VDSO , true ) ;
2012-09-10 20:50:19 +04:00
if ( ! dso ) {
char * file ;
2014-07-22 17:17:54 +04:00
file = get_file ( & vdso_info - > vdso ) ;
2015-06-01 21:40:01 +03:00
if ( file )
dso = __machine__addnew_vdso ( machine , DSO__NAME_VDSO , file ) ;
2012-09-10 20:50:19 +04:00
}
2015-06-01 21:40:01 +03:00
out_unlock :
2015-06-02 17:53:26 +03:00
dso__get ( dso ) ;
2015-06-01 21:40:01 +03:00
pthread_rwlock_unlock ( & machine - > dsos . lock ) ;
2012-09-10 20:50:19 +04:00
return dso ;
}
2014-07-22 17:17:57 +04:00
bool dso__is_vdso ( struct dso * dso )
{
2014-10-23 14:45:23 +04:00
return ! strcmp ( dso - > short_name , DSO__NAME_VDSO ) | |
! strcmp ( dso - > short_name , DSO__NAME_VDSO32 ) | |
! strcmp ( dso - > short_name , DSO__NAME_VDSOX32 ) ;
2014-07-22 17:17:57 +04:00
}