diff options
| -rw-r--r-- | tools/perf/util/symbol.c | 25 | 
1 files changed, 21 insertions, 4 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 39ce9adbaaf0..4ac1f871ec27 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -976,6 +976,23 @@ static int validate_kcore_modules(const char *kallsyms_filename,  	return 0;  } +static int validate_kcore_addresses(const char *kallsyms_filename, +				    struct map *map) +{ +	struct kmap *kmap = map__kmap(map); + +	if (kmap->ref_reloc_sym && kmap->ref_reloc_sym->name) { +		u64 start; + +		start = kallsyms__get_function_start(kallsyms_filename, +						     kmap->ref_reloc_sym->name); +		if (start != kmap->ref_reloc_sym->addr) +			return -EINVAL; +	} + +	return validate_kcore_modules(kallsyms_filename, map); +} +  struct kcore_mapfn_data {  	struct dso *dso;  	enum map_type type; @@ -1019,8 +1036,8 @@ static int dso__load_kcore(struct dso *dso, struct map *map,  					     kallsyms_filename))  		return -EINVAL; -	/* All modules must be present at their original addresses */ -	if (validate_kcore_modules(kallsyms_filename, map)) +	/* Modules and kernel must be present at their original addresses */ +	if (validate_kcore_addresses(kallsyms_filename, map))  		return -EINVAL;  	md.dso = dso; @@ -1424,7 +1441,7 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz)  			continue;  		scnprintf(kallsyms_filename, sizeof(kallsyms_filename),  			  "%s/%s/kallsyms", dir, dent->d_name); -		if (!validate_kcore_modules(kallsyms_filename, map)) { +		if (!validate_kcore_addresses(kallsyms_filename, map)) {  			strlcpy(dir, kallsyms_filename, dir_sz);  			ret = 0;  			break; @@ -1479,7 +1496,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)  		if (fd != -1) {  			close(fd);  			/* If module maps match go with /proc/kallsyms */ -			if (!validate_kcore_modules("/proc/kallsyms", map)) +			if (!validate_kcore_addresses("/proc/kallsyms", map))  				goto proc_kallsyms;  		}  | 
