2009-08-12 13:07:25 +04:00
# include "event.h"
# include "symbol.h"
# include <stdlib.h>
# include <string.h>
# include <stdio.h>
2009-10-20 20:25:40 +04:00
# include "debug.h"
2009-08-12 13:07:25 +04:00
static inline int is_anon_memory ( const char * filename )
{
return strcmp ( filename , " //anon " ) = = 0 ;
}
static int strcommon ( const char * pathname , char * cwd , int cwdlen )
{
int n = 0 ;
while ( n < cwdlen & & pathname [ n ] = = cwd [ n ] )
+ + n ;
return n ;
}
2009-10-20 20:25:40 +04:00
struct map * map__new ( struct mmap_event * event , char * cwd , int cwdlen ,
2009-10-21 23:34:06 +04:00
unsigned int sym_priv_size , symbol_filter_t filter )
2009-08-12 13:07:25 +04:00
{
struct map * self = malloc ( sizeof ( * self ) ) ;
if ( self ! = NULL ) {
const char * filename = event - > filename ;
char newfilename [ PATH_MAX ] ;
int anon ;
2009-10-20 20:25:40 +04:00
bool new_dso ;
2009-08-12 13:07:25 +04:00
if ( cwd ) {
int n = strcommon ( filename , cwd , cwdlen ) ;
if ( n = = cwdlen ) {
snprintf ( newfilename , sizeof ( newfilename ) ,
" .%s " , filename + n ) ;
filename = newfilename ;
}
}
anon = is_anon_memory ( filename ) ;
if ( anon ) {
snprintf ( newfilename , sizeof ( newfilename ) , " /tmp/perf-%d.map " , event - > pid ) ;
filename = newfilename ;
}
self - > start = event - > start ;
self - > end = event - > start + event - > len ;
self - > pgoff = event - > pgoff ;
2009-10-20 20:25:40 +04:00
self - > dso = dsos__findnew ( filename , sym_priv_size , & new_dso ) ;
2009-08-12 13:07:25 +04:00
if ( self - > dso = = NULL )
goto out_delete ;
2009-10-20 20:25:40 +04:00
if ( new_dso ) {
2009-10-21 23:34:06 +04:00
int nr = dso__load ( self - > dso , self , filter ) ;
2009-10-20 20:25:40 +04:00
if ( nr < 0 )
2009-10-21 23:34:06 +04:00
pr_warning ( " Failed to open %s, continuing "
" without symbols \n " ,
self - > dso - > long_name ) ;
2009-10-20 20:25:40 +04:00
else if ( nr = = 0 )
2009-10-21 23:34:06 +04:00
pr_warning ( " No symbols found in %s, maybe "
" install a debug package? \n " ,
self - > dso - > long_name ) ;
2009-10-20 20:25:40 +04:00
}
2009-08-12 13:07:25 +04:00
if ( self - > dso = = vdso | | anon )
2009-10-19 23:17:57 +04:00
self - > map_ip = self - > unmap_ip = identity__map_ip ;
else {
2009-08-12 13:07:25 +04:00
self - > map_ip = map__map_ip ;
2009-10-19 23:17:57 +04:00
self - > unmap_ip = map__unmap_ip ;
}
2009-08-12 13:07:25 +04:00
}
return self ;
out_delete :
free ( self ) ;
return NULL ;
}
struct map * map__clone ( struct map * self )
{
struct map * map = malloc ( sizeof ( * self ) ) ;
if ( ! map )
return NULL ;
memcpy ( map , self , sizeof ( * self ) ) ;
return map ;
}
int map__overlap ( struct map * l , struct map * r )
{
if ( l - > start > r - > start ) {
struct map * t = l ;
l = r ;
r = t ;
}
if ( l - > end > r - > start )
return 1 ;
return 0 ;
}
size_t map__fprintf ( struct map * self , FILE * fp )
{
return fprintf ( fp , " %Lx-%Lx %Lx %s \n " ,
self - > start , self - > end , self - > pgoff , self - > dso - > name ) ;
}